From de18ac8fe103451e358fa1ef7850fc3c3be70cdb Mon Sep 17 00:00:00 2001 From: Julio Estrada Date: Mon, 26 Jan 2026 20:21:01 -0500 Subject: [PATCH] Add gcovr UI customization templates and build scripts - Add HTML templates for customized gcovr coverage reports with sidebar navigation - Add build_tree.py script to generate tree.json for directory navigation - Add gcovr_wrapper.py for local coverage processing - Update build.sh to handle both local/macOS and CI/Linux environments - Add macOS workaround: auto-detect paths from .info files since gcovr cannot read .gcda files directly on macOS - Add .gitignore for generated coverage reports and temp files --- .gitignore | 10 + build.sh | 48 +- json/gcovr-output/index.css | 956 + json/gcovr-output/index.html | 2455 ++ json/gcovr-output/index.js | 158 + ....hpp.161c04ed0fb44652959476d632ffe1a5.html | 2726 ++ ....hpp.43ca8a64d5cb1e0e18bac819d8dd589d.html | 6726 ++++ ....hpp.6e0bda7bf6757e548b5faad83e899291.html | 13566 +++++++ ....hpp.ffb272ea2be09d8caf7e569420bf69e3.html | 2454 ++ ....ipp.12b73a50f89b12e61f6c515c936b6c51.html | 8614 ++++ ....hpp.06e327eb6aa84eac97ab3143afde5536.html | 4334 ++ ....hpp.c9c83104d1acc54b93b6e51f63102df2.html | 7478 ++++ ....hpp.5c3e10cbda02afe7ee8dcae02239f852.html | 25430 ++++++++++++ ....hpp.7ed59f082bdc8865c839e37a907818ae.html | 7094 ++++ ....hpp.55b2280adf5814131719bffc56d99e63.html | 3278 ++ ...conv.510f5dd29cc43eca58c0d2b93adff045.html | 2188 ++ ....hpp.98695bbba488db8061085c97a91bfff6.html | 3262 ++ ....hpp.14da4b5c079d398c9d8067d0d7a811dc.html | 3718 ++ ....hpp.0a32ee1b4391ae1eeb404af25739161a.html | 4022 ++ ....hpp.c385894883668d872f8d1b74220b0f7e.html | 6958 ++++ json/gcovr/index.css | 1481 + ....hpp.cde3922f605044959e8be4ef6db1abab.html | 4222 ++ ....ipp.5c6823db6d8cdf35aa2e1efe1dbd8e24.html | 7966 ++++ ....hpp.08b587354545c40cd025a0cdb25e60c9.html | 5030 +++ ....hpp.83ef835088fb80240623093e946e5ee8.html | 3958 ++ ....hpp.aa9ca29d0a37b3474618fa96dc2b5923.html | 3678 ++ ....hpp.cf498b84410e67aa58bd4c613cab1f84.html | 2918 ++ ....ipp.29b0230184410f16ceaecef9a447dcef.html | 2654 ++ ...tail.0ab43ac414239956f09d5b0181f77c50.html | 2872 ++ ...tail.287b6ad9e303318f27f0e943b3878477.html | 2368 ++ ...tail.e4ef6da21b1421bbb8fd14958bc3b5ac.html | 2296 ++ ....hpp.905cd2165a4f34376c449f885fe1adf1.html | 3030 ++ ....hpp.d6697c5bee8735e93381acb1ede736e7.html | 5646 +++ ....hpp.54cb42fce758b96305314c836f5822d5.html | 2598 ++ ....hpp.0ceaaed8d203e80b297f0b1456573326.html | 3638 ++ ....hpp.561447e3b80e5107d88e9cf24f3b9513.html | 3134 ++ ....ipp.5ffd5dbb81ff10cef7db2ed5dff0c794.html | 3630 ++ ....ipp.12c9aef5d4d66299103ac6024ed0063f.html | 2510 ++ ...loat.eccdc16b8d3a6677c41246e350f1ee5c.html | 2332 ++ ....hpp.60c7bd470abb6c3589089cc294f360d4.html | 6614 ++++ ....ipp.9ec47a71b786a54db9e57825e82a5eb7.html | 3110 ++ ....ipp.1f79c0e3711fd7d708dc790de46627b3.html | 2486 ++ ....hpp.a4a922435f511d73baf7f630422a09ef.html | 3486 ++ ....hpp.62421e671be5feb9c0f1e3df5a09b86e.html | 4126 ++ json/gcovr/index.functions.html | 2063 + ....ipp.25997a61b96794a78e1e3ddeede59723.html | 3742 ++ json/gcovr/index.html | 2800 ++ ...impl.c82c9a65c0038782a53ba4c76e95a641.html | 3124 ++ ...impl.cde90127c1b0418ad9f796d3477a9914.html | 2440 ++ ....hpp.4c04f6dbbc7f34b14ccd1b3f4b32318c.html | 4030 ++ json/gcovr/index.js | 453 + ....ipp.944bac86090b83665f00c8cee1a3defe.html | 2478 ++ ....hpp.2e722ac7a80e95232217c08e5473907a.html | 2630 ++ ....hpp.c7901c306f139d49bdd39970ea9decfb.html | 4558 +++ ....ipp.05f2ed6d69820a792f84fc5a30acb7c6.html | 3478 ++ ....ipp.a960c79e90c931af68e459ac2d12d5fe.html | 2830 ++ ....hpp.4af583e26a117226f5f096905dacf35c.html | 13566 +++++++ ....hpp.f7e5cc97accf7f1302ce80ea402b6373.html | 2878 ++ ....hpp.f9faeb03c62042d95f8ee35052afa9e9.html | 6670 ++++ ....ipp.84c492a53a4bbdeb0fd1338b41d399a5.html | 9598 +++++ ....ipp.bda6280a016bf6834766bc3a0bff32bc.html | 3198 ++ ....hpp.9fe27b0246ac36c90c713d2ffcd261fd.html | 3158 ++ ....hpp.f1e9fbffabe35587d223b9d98d9e761c.html | 17902 +++++++++ ....hpp.7949b767450af0a0c4e38d459ab8efa6.html | 4006 ++ ....hpp.45a498812670ba69036304cd17e3052d.html | 5134 +++ ....hpp.d91835266758ed9bedb91a3636a5e82c.html | 6446 +++ ....ipp.266f2bed4bd28788f0addeb11aa58a0d.html | 3430 ++ ....hpp.4dd6b487af20fd66fc07f525c990eb8b.html | 3838 ++ ....ipp.29ac44758c62ce39e625bbc7f1409991.html | 6318 +++ ....hpp.e956a435ea4d78939339c698f7ed6545.html | 3182 ++ ....ryu.9a047557b83bbcb666051bf9b69b073a.html | 2188 ++ ....hpp.9e08251ec0ed54496b3a8a6fb89a63c3.html | 3630 ++ ....hpp.d3414f2b51c87c80044a72e36bd57115.html | 2462 ++ ....ipp.01c963125bda877c839757dd2c6962c0.html | 4206 ++ ....hpp.79c79ec35822453ea6370e04c673a001.html | 4286 ++ ....hpp.ad86b38709508f8d05ea641d2e98c1da.html | 8902 +++++ ....ipp.a6e01f5c62a1e98844cee0136d1d1512.html | 6662 ++++ ....hpp.1927ca08c89a37cdfbf293076af47ff7.html | 2806 ++ ....ipp.f07eb9144ccb01dab822bc01a22dda0d.html | 2406 ++ ....hpp.6a507d81ac7c10f52d533f58d85ac238.html | 6478 +++ ....hpp.2c1d90a4d04ade6bea988474789a22e6.html | 3110 ++ ....hpp.c6cfbf398aba6b34d13f47ba0d19bf6a.html | 3486 ++ ....ipp.3a9e0e01201646e2f48328d15e4e2602.html | 2918 ++ ....hpp.7bee809dfe2a5a1cb7dd0c3dd2654987.html | 3902 ++ ....ipp.da4918eee73bb2b38d71ee2c22c5a4b6.html | 2702 ++ ....hpp.ac80baa46fb5bebc8f455223b00c44c4.html | 5798 +++ ....hpp.07654afdcb5f383c2335d7fecd03055c.html | 4886 +++ ....hpp.756a2056175378bf4974ad36f699d9ba.html | 7246 ++++ ....ipp.9e84d7cb15fc2f2f5eb0a5dbb07fed15.html | 3566 ++ ....hpp.753c5fbae83abdbca988b8d9bf6c7e2c.html | 4126 ++ ....hpp.a0ee7b78a1e1a48649112e27bc32c7ed.html | 19846 ++++++++++ ....ipp.608f1816a0e4c09495ec66dab6eb9085.html | 5830 +++ ....hpp.3bd773ee5e5571ae1ed6db73d00280e3.html | 5198 +++ ....ipp.e66f2c45d36b3fec9c3bfbb095fa9edb.html | 6006 +++ ....hpp.d18a20eb6345bd7b0b78784fd246f3ed.html | 3670 ++ ....hpp.08b63e532c8156eaeb5cccaa7944e074.html | 4382 +++ ....hpp.4e464561aa627034092b7a363639d5b7.html | 32702 ++++++++++++++++ ....hpp.927a100eb53bf40397be1d8b22da1871.html | 2366 ++ ....ipp.210aedf137631846f16fbe0ee4f0812c.html | 9990 +++++ ....hpp.1cdcc419fa9e4a63453aa84ed54ca11f.html | 4430 +++ ....hpp.a24a88c1f8fcc581db892ed3062c98a8.html | 3478 ++ ....hpp.5136da43247c9084cc2a038477b40231.html | 6142 +++ ....hpp.9e9582fd1af4a003bf535e71a0b7904d.html | 2574 ++ ....ipp.e9a0bd8aab92a2b5ab364bf6b69e3959.html | 3622 ++ ....ipp.898987b601e2219cdbbc0139ef61766f.html | 5918 +++ ....hpp.1b7ce679b2c4b444ce7bf9f62953b6be.html | 4006 ++ ....hpp.635e555e887031c6fc380bccf2c402de.html | 8902 +++++ ....hpp.d5ce1db1e3454de3538149bf6f28b617.html | 2830 ++ json/gcovr/keep.txt | 1 - json/gcovr/tree.json | 802 + scripts/build_tree.py | 208 + scripts/gcovr_wrapper.py | 22 + templates/html/base.html | 99 + templates/html/directory_page.content.html | 81 + templates/html/directory_page.html | 42 + templates/html/directory_page.navigation.html | 9 + templates/html/directory_page.summary.html | 85 + templates/html/functions_page.content.html | 36 + templates/html/functions_page.html | 37 + templates/html/functions_page.summary.html | 16 + templates/html/gcovr.js | 453 + templates/html/source_page.content.html | 177 + templates/html/source_page.html | 42 + templates/html/source_page.navigation.html | 15 + templates/html/source_page.summary.html | 26 + templates/html/style.css | 1481 + 126 files changed, 536491 insertions(+), 7 deletions(-) create mode 100644 .gitignore create mode 100644 json/gcovr-output/index.css create mode 100644 json/gcovr-output/index.html create mode 100644 json/gcovr-output/index.js create mode 100644 json/gcovr/index.array.hpp.161c04ed0fb44652959476d632ffe1a5.html create mode 100644 json/gcovr/index.array.hpp.43ca8a64d5cb1e0e18bac819d8dd589d.html create mode 100644 json/gcovr/index.array.hpp.6e0bda7bf6757e548b5faad83e899291.html create mode 100644 json/gcovr/index.array.hpp.ffb272ea2be09d8caf7e569420bf69e3.html create mode 100644 json/gcovr/index.array.ipp.12b73a50f89b12e61f6c515c936b6c51.html create mode 100644 json/gcovr/index.ascii_number.hpp.06e327eb6aa84eac97ab3143afde5536.html create mode 100644 json/gcovr/index.basic_parser.hpp.c9c83104d1acc54b93b6e51f63102df2.html create mode 100644 json/gcovr/index.basic_parser_impl.hpp.5c3e10cbda02afe7ee8dcae02239f852.html create mode 100644 json/gcovr/index.bigint.hpp.7ed59f082bdc8865c839e37a907818ae.html create mode 100644 json/gcovr/index.buffer.hpp.55b2280adf5814131719bffc56d99e63.html create mode 100644 json/gcovr/index.charconv.510f5dd29cc43eca58c0d2b93adff045.html create mode 100644 json/gcovr/index.common.hpp.98695bbba488db8061085c97a91bfff6.html create mode 100644 json/gcovr/index.compute_float64.hpp.14da4b5c079d398c9d8067d0d7a811dc.html create mode 100644 json/gcovr/index.config.hpp.0a32ee1b4391ae1eeb404af25739161a.html create mode 100644 json/gcovr/index.conversion.hpp.c385894883668d872f8d1b74220b0f7e.html create mode 100644 json/gcovr/index.css create mode 100644 json/gcovr/index.d2s.hpp.cde3922f605044959e8be4ef6db1abab.html create mode 100644 json/gcovr/index.d2s.ipp.5c6823db6d8cdf35aa2e1efe1dbd8e24.html create mode 100644 json/gcovr/index.d2s_full_table.hpp.08b587354545c40cd025a0cdb25e60c9.html create mode 100644 json/gcovr/index.d2s_intrinsics.hpp.83ef835088fb80240623093e946e5ee8.html create mode 100644 json/gcovr/index.decimal_to_binary.hpp.aa9ca29d0a37b3474618fa96dc2b5923.html create mode 100644 json/gcovr/index.default_resource.hpp.cf498b84410e67aa58bd4c613cab1f84.html create mode 100644 json/gcovr/index.default_resource.ipp.29b0230184410f16ceaecef9a447dcef.html create mode 100644 json/gcovr/index.detail.0ab43ac414239956f09d5b0181f77c50.html create mode 100644 json/gcovr/index.detail.287b6ad9e303318f27f0e943b3878477.html create mode 100644 json/gcovr/index.detail.e4ef6da21b1421bbb8fd14958bc3b5ac.html create mode 100644 json/gcovr/index.digest.hpp.905cd2165a4f34376c449f885fe1adf1.html create mode 100644 json/gcovr/index.digit_comparison.hpp.d6697c5bee8735e93381acb1ede736e7.html create mode 100644 json/gcovr/index.digit_table.hpp.54cb42fce758b96305314c836f5822d5.html create mode 100644 json/gcovr/index.emulated128.hpp.0ceaaed8d203e80b297f0b1456573326.html create mode 100644 json/gcovr/index.error.hpp.561447e3b80e5107d88e9cf24f3b9513.html create mode 100644 json/gcovr/index.error.ipp.5ffd5dbb81ff10cef7db2ed5dff0c794.html create mode 100644 json/gcovr/index.except.ipp.12c9aef5d4d66299103ac6024ed0063f.html create mode 100644 json/gcovr/index.fast_float.eccdc16b8d3a6677c41246e350f1ee5c.html create mode 100644 json/gcovr/index.float_common.hpp.60c7bd470abb6c3589089cc294f360d4.html create mode 100644 json/gcovr/index.format.ipp.9ec47a71b786a54db9e57825e82a5eb7.html create mode 100644 json/gcovr/index.from_chars.ipp.1f79c0e3711fd7d708dc790de46627b3.html create mode 100644 json/gcovr/index.from_chars_float_impl.hpp.a4a922435f511d73baf7f630422a09ef.html create mode 100644 json/gcovr/index.from_chars_integer_impl.hpp.62421e671be5feb9c0f1e3df5a09b86e.html create mode 100644 json/gcovr/index.functions.html create mode 100644 json/gcovr/index.handler.ipp.25997a61b96794a78e1e3ddeede59723.html create mode 100644 json/gcovr/index.html create mode 100644 json/gcovr/index.impl.c82c9a65c0038782a53ba4c76e95a641.html create mode 100644 json/gcovr/index.impl.cde90127c1b0418ad9f796d3477a9914.html create mode 100644 json/gcovr/index.integer_search_trees.hpp.4c04f6dbbc7f34b14ccd1b3f4b32318c.html create mode 100644 json/gcovr/index.js create mode 100644 json/gcovr/index.kind.ipp.944bac86090b83665f00c8cee1a3defe.html create mode 100644 json/gcovr/index.literals.hpp.2e722ac7a80e95232217c08e5473907a.html create mode 100644 json/gcovr/index.monotonic_resource.hpp.c7901c306f139d49bdd39970ea9decfb.html create mode 100644 json/gcovr/index.monotonic_resource.ipp.05f2ed6d69820a792f84fc5a30acb7c6.html create mode 100644 json/gcovr/index.null_resource.ipp.a960c79e90c931af68e459ac2d12d5fe.html create mode 100644 json/gcovr/index.object.hpp.4af583e26a117226f5f096905dacf35c.html create mode 100644 json/gcovr/index.object.hpp.f7e5cc97accf7f1302ce80ea402b6373.html create mode 100644 json/gcovr/index.object.hpp.f9faeb03c62042d95f8ee35052afa9e9.html create mode 100644 json/gcovr/index.object.ipp.84c492a53a4bbdeb0fd1338b41d399a5.html create mode 100644 json/gcovr/index.parse.ipp.bda6280a016bf6834766bc3a0bff32bc.html create mode 100644 json/gcovr/index.parse_into.hpp.9fe27b0246ac36c90c713d2ffcd261fd.html create mode 100644 json/gcovr/index.parse_into.hpp.f1e9fbffabe35587d223b9d98d9e761c.html create mode 100644 json/gcovr/index.parse_number.hpp.7949b767450af0a0c4e38d459ab8efa6.html create mode 100644 json/gcovr/index.parser.hpp.45a498812670ba69036304cd17e3052d.html create mode 100644 json/gcovr/index.parser.hpp.d91835266758ed9bedb91a3636a5e82c.html create mode 100644 json/gcovr/index.parser.ipp.266f2bed4bd28788f0addeb11aa58a0d.html create mode 100644 json/gcovr/index.pilfer.hpp.4dd6b487af20fd66fc07f525c990eb8b.html create mode 100644 json/gcovr/index.pointer.ipp.29ac44758c62ce39e625bbc7f1409991.html create mode 100644 json/gcovr/index.result_for.hpp.e956a435ea4d78939339c698f7ed6545.html create mode 100644 json/gcovr/index.ryu.9a047557b83bbcb666051bf9b69b073a.html create mode 100644 json/gcovr/index.sbo_buffer.hpp.9e08251ec0ed54496b3a8a6fb89a63c3.html create mode 100644 json/gcovr/index.serialize.hpp.d3414f2b51c87c80044a72e36bd57115.html create mode 100644 json/gcovr/index.serialize.ipp.01c963125bda877c839757dd2c6962c0.html create mode 100644 json/gcovr/index.serializer.hpp.79c79ec35822453ea6370e04c673a001.html create mode 100644 json/gcovr/index.serializer.hpp.ad86b38709508f8d05ea641d2e98c1da.html create mode 100644 json/gcovr/index.serializer.ipp.a6e01f5c62a1e98844cee0136d1d1512.html create mode 100644 json/gcovr/index.shared_resource.hpp.1927ca08c89a37cdfbf293076af47ff7.html create mode 100644 json/gcovr/index.shared_resource.ipp.f07eb9144ccb01dab822bc01a22dda0d.html create mode 100644 json/gcovr/index.sse2.hpp.6a507d81ac7c10f52d533f58d85ac238.html create mode 100644 json/gcovr/index.stack.hpp.2c1d90a4d04ade6bea988474789a22e6.html create mode 100644 json/gcovr/index.stack.hpp.c6cfbf398aba6b34d13f47ba0d19bf6a.html create mode 100644 json/gcovr/index.stack.ipp.3a9e0e01201646e2f48328d15e4e2602.html create mode 100644 json/gcovr/index.static_resource.hpp.7bee809dfe2a5a1cb7dd0c3dd2654987.html create mode 100644 json/gcovr/index.static_resource.ipp.da4918eee73bb2b38d71ee2c22c5a4b6.html create mode 100644 json/gcovr/index.storage_ptr.hpp.ac80baa46fb5bebc8f455223b00c44c4.html create mode 100644 json/gcovr/index.stream.hpp.07654afdcb5f383c2335d7fecd03055c.html create mode 100644 json/gcovr/index.stream_parser.hpp.756a2056175378bf4974ad36f699d9ba.html create mode 100644 json/gcovr/index.stream_parser.ipp.9e84d7cb15fc2f2f5eb0a5dbb07fed15.html create mode 100644 json/gcovr/index.string.hpp.753c5fbae83abdbca988b8d9bf6c7e2c.html create mode 100644 json/gcovr/index.string.hpp.a0ee7b78a1e1a48649112e27bc32c7ed.html create mode 100644 json/gcovr/index.string.ipp.608f1816a0e4c09495ec66dab6eb9085.html create mode 100644 json/gcovr/index.string_impl.hpp.3bd773ee5e5571ae1ed6db73d00280e3.html create mode 100644 json/gcovr/index.string_impl.ipp.e66f2c45d36b3fec9c3bfbb095fa9edb.html create mode 100644 json/gcovr/index.utf8.hpp.d18a20eb6345bd7b0b78784fd246f3ed.html create mode 100644 json/gcovr/index.value.hpp.08b63e532c8156eaeb5cccaa7944e074.html create mode 100644 json/gcovr/index.value.hpp.4e464561aa627034092b7a363639d5b7.html create mode 100644 json/gcovr/index.value.hpp.927a100eb53bf40397be1d8b22da1871.html create mode 100644 json/gcovr/index.value.ipp.210aedf137631846f16fbe0ee4f0812c.html create mode 100644 json/gcovr/index.value_from.hpp.1cdcc419fa9e4a63453aa84ed54ca11f.html create mode 100644 json/gcovr/index.value_from.hpp.a24a88c1f8fcc581db892ed3062c98a8.html create mode 100644 json/gcovr/index.value_ref.hpp.5136da43247c9084cc2a038477b40231.html create mode 100644 json/gcovr/index.value_ref.hpp.9e9582fd1af4a003bf535e71a0b7904d.html create mode 100644 json/gcovr/index.value_ref.ipp.e9a0bd8aab92a2b5ab364bf6b69e3959.html create mode 100644 json/gcovr/index.value_stack.ipp.898987b601e2219cdbbc0139ef61766f.html create mode 100644 json/gcovr/index.value_to.hpp.1b7ce679b2c4b444ce7bf9f62953b6be.html create mode 100644 json/gcovr/index.value_to.hpp.635e555e887031c6fc380bccf2c402de.html create mode 100644 json/gcovr/index.visit.hpp.d5ce1db1e3454de3538149bf6f28b617.html delete mode 100644 json/gcovr/keep.txt create mode 100644 json/gcovr/tree.json create mode 100755 scripts/build_tree.py create mode 100755 scripts/gcovr_wrapper.py create mode 100644 templates/html/base.html create mode 100644 templates/html/directory_page.content.html create mode 100644 templates/html/directory_page.html create mode 100644 templates/html/directory_page.navigation.html create mode 100644 templates/html/directory_page.summary.html create mode 100644 templates/html/functions_page.content.html create mode 100644 templates/html/functions_page.html create mode 100644 templates/html/functions_page.summary.html create mode 100644 templates/html/gcovr.js create mode 100644 templates/html/source_page.content.html create mode 100644 templates/html/source_page.html create mode 100644 templates/html/source_page.navigation.html create mode 100644 templates/html/source_page.summary.html create mode 100644 templates/html/style.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3b27ffb8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Generated coverage reports +# json/gcovr/ +# json/gcovr-lcov/ +# json/gcovr-output/ + +# Claude Code +.claude/ + +# Temp files +*.bak diff --git a/build.sh b/build.sh index 105484d5..5d9c8597 100755 --- a/build.sh +++ b/build.sh @@ -8,15 +8,51 @@ export REPONAME="json" export ORGANIZATION="boostorg" GCOVRFILTER=".*/$REPONAME/.*" -cd "$REPONAME" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +cd "$SCRIPT_DIR/$REPONAME" BOOST_CI_SRC_FOLDER=$(pwd) -cd ../boost-root - outputlocation="$BOOST_CI_SRC_FOLDER/gcovr" -outputlocation="/mnt/c/output" rm -rf $outputlocation || true - mkdir -p $outputlocation -gcovr --merge-mode-functions separate -p --html-nested --html-template-dir=..\templates --exclude-unreachable-branches --exclude-throw-branches --exclude '.*/test/.*' --exclude '.*/extra/.*' --filter "$GCOVRFILTER" --html --output "$outputlocation/index.html" +if [[ -f "$BOOST_CI_SRC_FOLDER/coverage_filtered.info" ]]; then + # Local/macOS workaround: gcovr cannot read .gcda coverage files directly on macOS, + # so we convert the .info file (from lcov) to Cobertura XML format instead. + # The .info file contains absolute paths from the original build environment, + # which we auto-detect and rewrite to match the local machine's paths. + # Use 'boost-root' as anchor since it's consistently named across all builds + ORIGINAL_PATH=$(grep -m1 "^SF:" "$BOOST_CI_SRC_FOLDER/coverage_filtered.info" | sed 's|^SF:||' | sed 's|/boost-root/.*||') + TEMP_COVERAGE="/tmp/coverage_local.info" + TEMP_XML="/tmp/coverage.xml" + + sed "s|$ORIGINAL_PATH|$SCRIPT_DIR|g" "$BOOST_CI_SRC_FOLDER/coverage_filtered.info" > "$TEMP_COVERAGE" + lcov_cobertura "$TEMP_COVERAGE" -o "$TEMP_XML" + sed -i.bak "s|filename=\"\.\./boost-root/|filename=\"$SCRIPT_DIR/boost-root/|g" "$TEMP_XML" + + "$SCRIPT_DIR/scripts/gcovr_wrapper.py" \ + --cobertura-add-tracefile "$TEMP_XML" \ + --root "$SCRIPT_DIR" \ + --html-nested \ + --html-template-dir "$SCRIPT_DIR/templates/html" \ + --output "$outputlocation/index.html" + + # Generate tree.json for sidebar navigation + python3 "$SCRIPT_DIR/scripts/build_tree.py" "$outputlocation" +else + # CI/Linux: gcovr reads coverage data directly + cd ../boost-root + gcovr --merge-mode-functions separate -p \ + --html-nested \ + --html-template-dir=../templates/html \ + --exclude-unreachable-branches \ + --exclude-throw-branches \ + --exclude '.*/test/.*' \ + --exclude '.*/extra/.*' \ + --filter "$GCOVRFILTER" \ + --html \ + --output "$outputlocation/index.html" + + # Generate tree.json for sidebar navigation + python3 "../scripts/build_tree.py" "$outputlocation" +fi diff --git a/json/gcovr-output/index.css b/json/gcovr-output/index.css new file mode 100644 index 00000000..f8d381ed --- /dev/null +++ b/json/gcovr-output/index.css @@ -0,0 +1,956 @@ +@charset "utf-8"; + +:root { + font-family: sans-serif; + --tab_size: 4; +} + +.theme-green, .theme-blue { + --unknown_color: lightgray; + --low_color: #FF6666; + --medium_color: #F9FD63; + --partial_covered_color: var(--medium_color); + --uncovered_color: #FF8C8C; + --warning_color: orangered; + --notTakenBranch_color: red; + --notTakenCondition_color: red; + --uncheckedDecision_color: darkorange; + --notTakenDecision_color: red; + --notInvokedCall_color: red; + --excluded_color: darkkhaki; + /* Colors taken from github theme */ + --color-fg-default: #1F2328; + --color-canvas-default: #ffffff; + --color-border-default: #d0d7de; + --color-border-muted: hsla(210, 18%, 87%, 1); + --color-fg-muted: #656d76; + --color-canvas-subtle: #f6f8fa; + --color-accent-subtle: #ddf4ff;; +} + +.theme-green { + --high_color: #85E485; + --covered_color: #85E485; + --takenBranch_color: green; + --takenCondition_color: green; + --takenDecision_color: green; + --invokedCall_color: green; +} + +.theme-blue { + --high_color: #66B4FF; + --covered_color: #66B4Ff; + --takenBranch_color: blue; + --takenCondition_color: blue; + --takenDecision_color: blue; + --invokedCall_color: blue; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; + color: var(--color-fg-default); + background-color: var(--color-canvas-default) +} + +h1 +{ + text-align: center; + margin: 0; + padding-bottom: 10px; + font-size: 20pt; + font-weight: bold; +} + +hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: rgba(0,0,0,0); + border: 0; + border-bottom: 1px solid var(--color-border-muted); +} + +.sticky { + position: sticky; + top: 0; +} + +a:link +{ + color: navy; + text-decoration: underline; +} +a:visited +{ + color: maroon; + text-decoration: underline; +} + +.js-enabled .js-enabled-hidden { + display: none +} + +.js-disabled .js-disabled-hidden { + display: none +} + +.block-separator { + border-bottom: 5px solid var(--color-border-muted); +} + +@media (max-width: 544px) { + .filelist .Box-row { + flex-direction: column; + } + .functionslist .Box-row { + flex-direction: column; + } + + .filelist .Box-row > div { + width: 100%; + } + .functionslist .Box-row > div { + width: 100%; + } +} + +button.button_toggle_coveredLine, +button.button_toggle_uncoveredLine, +button.button_toggle_excludedLine, +button.button_toggle_partialCoveredLine { + margin-left: 1em; + border: 1px solid; + border-radius: 6px; + color: var(--color-fg-default); + display: inline-flex; + align-items: center; + text-decoration: line-through; +} +button.button_toggle_coveredLine.show_coveredLine, +button.button_toggle_uncoveredLine.show_uncoveredLine, +button.button_toggle_excludedLine.show_excludedLine, +button.button_toggle_partialCoveredLine.show_partialCoveredLine { + text-decoration: none; +} + +button.button_toggle_coveredLine { + background-color: var(--covered_color) !important; +} +button.button_toggle_uncoveredLine { + background-color: var(--uncovered_color) !important; +} +button.button_toggle_excludedLine { + background-color: var(--excluded_color) !important; +} +button.button_toggle_partialCoveredLine { + background-color: var(--partial_covered_color) !important; +} + +div.nav { + margin-left: auto; +} + +a.nav { + text-decoration: none; + color: grey; + padding-left: 1em; + white-space: nowrap; + overflow: hidden; +} + +a.nav:hover { + text-decoration: underline; +} + +a.nav.prev::after { + content: "« prev"; +} + +a.nav.index::after { + content: "^ index"; +} + +a.nav.next::after { + content: "» next"; +} + +.sortable { + cursor: pointer; +} + +.sorted-ascending::after { + content: " ↑"; + white-space: pre; +} + +.sorted-descending::after { + content: " ↓"; + white-space: pre; +} + +.source-table-container { + overflow-x: auto; +} + +#scroll_marker { + position: fixed; + z-index: 3; + right: 0; + top: 0; + width: 12px; + height: 100%; + background-color: var(--color-canvas-default); + border-left: 1px solid var(--color-border-default); + will-change: transform; +} + +#scroll_marker .marker { + background: #cccccc; + position: absolute; + min-height: 3px; + width: 100%; +} +/*** Summary formats ***/ + +.summary +{ + display: flex; + flex-flow: row wrap; + max-width: 100%; + justify-content: flex-start; +} + +.summary > table +{ + flex: 1 0 7em; + border: 0; +} + +.summary > :last-child { + margin-left: auto; +} + +table.legend +{ + color: black; + display: flex; + flex-flow: row wrap; + justify-content: flex-start; + margin-left: 16px; +} + +table.legend th[scope=row] +{ + font-weight: normal; + text-align: right; + white-space: nowrap; +} + +table.legend td +{ + color: blue; + text-align: left; + white-space: nowrap; + padding-left: 5px; +} + +table.legend td.legend +{ + color: black; + font-size: 80%; +} + +table.legend td.warning_text +{ + color: var(--warning_color); +} + +table.coverage +{ + border-collapse: collapse; + margin-right: 16px; +} + +table.coverage td, +table.coverage th +{ + text-align: right; + color: black; + font-weight: normal; + white-space: nowrap; + padding-top: 3px; + padding-bottom: 3px; + padding-left: 5px; + padding-right: 4px; +} + +table.coverage td +{ + background-color: LightSteelBlue; +} + +table.coverage th[scope=row] +{ + color: black; + font-weight: normal; + white-space: nowrap; +} + +table.coverage th[scope=col] +{ + color: blue; + font-weight: normal; + white-space: nowrap; +} + +table.legend span +{ + margin-right: 4px; + padding: 2px; +} + +table.legend span.coverage-unknown, +table.legend span.coverage-none, +table.legend span.coverage-low, +table.legend span.coverage-medium, +table.legend span.coverage-high +{ + padding-left: 0.5em; + padding-right: 0.5em; +} + +table.legend span.coverage-unknown, +table.coverage td.coverage-unknown +{ + background-color: var(--unknown_color) !important; +} + +table.legend span.coverage-none, +table.legend span.coverage-low, +table.coverage td.coverage-none, +table.coverage td.coverage-low +{ + background-color: var(--low_color) !important; +} + +table.legend span.coverage-medium, +table.coverage td.coverage-medium +{ + background-color: var(--medium_color) !important; +} + +table.legend span.coverage-high, +table.coverage td.coverage-high +{ + background-color: var(--high_color) !important; +} + +/*** End of Summary formats ***/ +/*** Meter formats ***/ + +/* Common */ +meter { + -moz-appearance: none; + + width: 200px; + min-width: 4em; + max-width: 15em; + height: 0.75em; + padding: 0; + vertical-align: baseline; + margin-top: 3px; + /* Outer background for Mozilla */ + background: none; + background-color: whitesmoke; +} + +/* Webkit */ + +meter::-webkit-meter-bar { + /* Outer background for Webkit */ + background: none; + background-color: whitesmoke; + height: 0.75em; + border-radius: 0px; +} + +meter::-webkit-meter-optimum-value, +meter::-webkit-meter-suboptimum-value, +meter::-webkit-meter-even-less-good-value +{ + /* Inner shadow for Webkit */ + border: solid 1px black; +} + +meter.coverage-none::-webkit-meter-optimum-value, +meter.coverage-low::-webkit-meter-optimum-value +{ + background: var(--low_color); +} + +meter.coverage-medium::-webkit-meter-optimum-value +{ + background: var(--medium_color); +} + +meter.coverage-high::-webkit-meter-optimum-value +{ + background: var(--high_color); +} + +/* Mozilla */ + +meter::-moz-meter-bar +{ + box-sizing: border-box; +} + +meter:-moz-meter-optimum::-moz-meter-bar, +meter:-moz-meter-sub-optimum::-moz-meter-bar, +meter:-moz-meter-sub-sub-optimum::-moz-meter-bar +{ + /* Inner shadow for Mozilla */ + border: solid 1px black; +} + +meter.coverage-none:-moz-meter-optimum::-moz-meter-bar, +meter.coverage-low:-moz-meter-optimum::-moz-meter-bar +{ + background: var(--low_color); +} + +meter.coverage-medium:-moz-meter-optimum::-moz-meter-bar +{ + background: var(--medium_color); +} + +meter.coverage-high:-moz-meter-optimum::-moz-meter-bar +{ + background: var(--high_color); +} + +/*** End of Meter formats ***/ +div.file-list +{ + border: 0; + border-spacing: 1px; +} + +div.file-list.coverage-unknown > span:not(:has(meter)) +{ + background-color: var(--unknown_color) !important; +} + +div.file-list.coverage-none > span:not(:has(meter)), +div.file-list.coverage-low > span:not(:has(meter)) +{ + background-color: var(--low_color) !important; +} + +div.file-list.coverage-medium > span:not(:has(meter)) +{ + background-color: var(--medium_color) !important; +} + +div.file-list.coverage-high > span:not(:has(meter)) +{ + background-color: var(--high_color) !important; +} + +div.file-list > span:has(meter) +{ + margin-right: 5px !important; +} + +div.file-list > span:not(:has(meter)) +{ + color: black !important; + padding-left: 5px !important; + padding-right: 5px !important; + margin-left: 0px !important; + margin-right: 0px !important; + text-align: right +} + +div.file-list > span:first-child +{ + min-width: 3.5em !important; +} + +div.file-list > span:last-child +{ + min-width: 4.5em !important; +} +td.CoverValue +{ + text-align: right; + white-space: nowrap; +} + +.coveredLine.show_coveredLine +{ + background-color: var(--covered_color) !important; +} + +.partialCoveredLine.show_partialCoveredLine +{ + background-color: var(--partial_covered_color) !important; +} + +.uncoveredLine.show_uncoveredLine +{ + background-color: var(--uncovered_color) !important; +} + +.excludedLine.show_excludedLine +{ + background-color: var(--excluded_color) !important; +} + +.linebranch, .linecondition, .linedecision, .linecall, .linecount, .lineblockids +{ + font-family: monospace; + border-right: 1px gray solid; + background-color: lightgray; + white-space: nowrap; +} +.linebranch, .linecondition, .linedecision, .linecall +{ + text-align: left; +} +.linecount +{ + text-align: right; +} + +details summary { + cursor:pointer; +} + +.linebranchDetails[open]>summary::before, +.lineconditionDetails[open]>summary::before, +.linedecisionDetails[open]>summary::before, +.linecallDetails[open]>summary::before +{ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 80; + display: block; + cursor: default; + content: " "; + background: rgba(0, 0, 0, 0); +} + +.linebranchSummary, .lineconditionSummary, .linedecisionSummary, .linecallSummary +{ + white-space: nowrap; +} + +.linebranchContents, .lineconditionContents, .linedecisionContents, .linecallContents +{ + font-family: monospace; + font-size: medium; + text-align: left; + white-space: nowrap; + position: absolute; + padding: 1em; + background: white; + border: solid gray 1px; + box-shadow: 5px 5px 10px gray; + z-index: 1; /* show in front of the table entries */ +} + +.functionName +{ + font-style: italic !important; + font-weight: bolder !important; +} + +.excludedBranch +{ + color: var(--takenBranch_color) !important; +} + +.takenBranch +{ + color: var(--takenBranch_color) !important; +} + +.notTakenBranch +{ + color: var(--notTakenBranch_color) !important; +} + +.excludedCondition +{ + color: var(--takenCondition_color) !important; +} + +.takenCondition +{ + color: var(--takenCondition_color) !important; +} + +.notTakenCondition +{ + color: var(--notTakenCondition_color) !important; +} + +.takenDecision +{ + color: var(--takenDecision_color) !important; +} + +.notTakenDecision +{ + color: var(--notTakenDecision_color) !important; +} + +.uncheckedDecision +{ + color: var(--uncheckedDecision_color) !important; +} + +.excludedCall +{ + color: var(--invokedCall_color) !important; +} + +.invokedCall +{ + color: var(--invokedCall_color) !important; +} + +.notInvokedCall +{ + color: var(--notInvokedCall_color) !important; +} + +.src +{ + padding-left: 12px; + text-align: left; + + font-family: monospace; + white-space: pre; + + tab-size: var(--tab_size); + -moz-tab-size: var(--tab_size); +} + +span.takenBranch, +span.notTakenBranch, +span.takenDecision, +span.notTakenDecision, +span.uncheckedDecision +{ + font-family: monospace; + font-weight: bold; +} + +pre +{ + height : 15px; + margin-top: 0; + margin-bottom: 0; +} + +.listOfFunctions td, .listOfFunctions th { + padding: 0 10px; +} +.listOfFunctions th +{ + text-align: center; + color: white; + background-color: SteelBlue; +} +.listOfFunctions tr > td { + background: aliceblue; +} +.listOfFunctions tr:nth-child(even) > td { + background: LightSteelBlue +} +.listOfFunctions tr:hover > td +{ + background-color: #ddd; +} +.listOfFunctions tr > td > a +{ + text-decoration: none; + color: inherit; +} + +.source-line +{ + height : 15px; + margin-top: 0; + margin-bottom: 0; +} + +.lineno +{ + background-color: #EFE383; + border-right: 1px solid #BBB15F; + text-align: right; + unicode-bidi: embed; + font-family: monospace; + white-space: pre; +} + +.lineno > a +{ + text-decoration: none; + color: inherit; +} + +.file-source table +{ + border-spacing: 0; +} + +.file-source table td, +.file-source table th +{ + padding: 1px 10px; +} + +.file-source table th +{ + font-family: monospace; + font-weight: bold; +} + +.file-source table td:last-child +{ + width: 100%; +} +.color-fg-muted { + color: var(--color-fg-muted) !important +} + +.text-mono { + font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace !important +} +.text-small { + font-size: 12px !important +} + +.Layout-main { + min-width: 0 +} + +@media(max-width: 543.98px) { + .Layout { + grid-auto-flow: row; + grid-template-columns: 1fr !important + } + + .Layout .Layout-main { + grid-column: 1 !important; + width: 100% !important + } +} + +.Layout-main .Layout-main-centered-lg { + margin-left: auto; + margin-right: auto +} + +.Box { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; + font-size: var(--body-font-size, 14px); + line-height: 1.5; + color: var(--color-fg-default); + background-color: var(--color-canvas-default); + border-color: var(--color-border-default); + border-radius: var(--borderRadius-medium, 6px); + border-style: solid; + border-width: var(--borderWidth-thin, 1px) +} + +.Box-header { + background-color: var(--color-canvas-subtle); + border-color: var(--color-border-default); + border-style: solid; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-width: 1px; + margin: -1px -1px 0; + padding: 16px; +} + +.Box-row { + border-top: var(--borderWidth-thin, 1px) solid var(--color-border-muted); + list-style-type: none; + margin-top: calc(var(--borderWidth-thin, 1px)*-1); + padding: var(--stack-padding-normal, 16px) +} + +.Box-row:first-of-type { + border-top-left-radius: var(--borderRadius-medium, 6px); + border-top-right-radius: var(--borderRadius-medium, 6px) +} + +.Box-row:last-of-type { + border-bottom-left-radius: var(--borderRadius-medium, 6px); + border-bottom-right-radius: var(--borderRadius-medium, 6px) +} + +.Box-row--focus-gray:hover { + background-color: var(--color-canvas-subtle) !important; +} + +.filelist .Box-row:nth-child(2n+3){ + background-color: var(--color-accent-subtle); +} + +.functionslist .Box-row:nth-child(2n+3){ + background-color: var(--color-accent-subtle); +} + +.d-flex { + display: flex !important +} + +.flex-auto { + flex: auto !important +} + +.flex-justify-end { + justify-content: flex-end !important +} + +.flex-justify-center { + justify-content: center !important +} + +.flex-wrap { + flex-wrap: wrap !important +} + +.flex-items-baseline { + align-items: baseline !important +} + +.flex-space-between { + justify-content: space-between !important +} + +.min-width-0 { + min-width: 0 !important +} + +.m-3 { + margin: var(--base-size-16, 16px) !important +} + +.py-2 { + padding-top: var(--base-size-8, 8px) !important; + padding-bottom: var(--base-size-8, 8px) !important; +} + +.col-2, +.col-md-2 +{ + width: 12.5% +} + +.css-truncate.css-truncate-target { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + display: inline-block; + max-width: 125px; + vertical-align: top +} + +.d-block { + display: block !important +} + +.width-fit { + max-width: 100% !important +} + +.text-center { + text-align: center !important +} + +/* pygments syntax highlighting */ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.hll { background-color: #ffffcc } +.c { color: #3D7B7B; font-style: italic } /* Comment */ +.err { border: 1px solid #F00 } /* Error */ +.k { color: #008000; font-weight: bold } /* Keyword */ +.o { color: #666 } /* Operator */ +.ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.cp { color: #9C6500 } /* Comment.Preproc */ +.cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.cs { color: #3D7B7B; font-weight: bold; font-style: italic } /* Comment.Special */ +.gd { color: #A00000 } /* Generic.Deleted */ +.ge { font-style: italic } /* Generic.Emph */ +.ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.gr { color: #E40000 } /* Generic.Error */ +.gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.gi { color: #008400 } /* Generic.Inserted */ +.go { color: #717171 } /* Generic.Output */ +.gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.gt { color: #04D } /* Generic.Traceback */ +.kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.kp { color: #008000 } /* Keyword.Pseudo */ +.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.kt { color: #B00040 } /* Keyword.Type */ +.m { color: #666 } /* Literal.Number */ +.s { color: #BA2121 } /* Literal.String */ +.na { color: #687822 } /* Name.Attribute */ +.nb { color: #008000 } /* Name.Builtin */ +.nc { color: #00F; font-weight: bold } /* Name.Class */ +.no { color: #800 } /* Name.Constant */ +.nd { color: #A2F } /* Name.Decorator */ +.ni { color: #717171; font-weight: bold } /* Name.Entity */ +.ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.nf { color: #00F } /* Name.Function */ +.nl { color: #767600 } /* Name.Label */ +.nn { color: #00F; font-weight: bold } /* Name.Namespace */ +.nt { color: #008000; font-weight: bold } /* Name.Tag */ +.nv { color: #19177C } /* Name.Variable */ +.ow { color: #A2F; font-weight: bold } /* Operator.Word */ +.w { color: #BBB } /* Text.Whitespace */ +.mb { color: #666 } /* Literal.Number.Bin */ +.mf { color: #666 } /* Literal.Number.Float */ +.mh { color: #666 } /* Literal.Number.Hex */ +.mi { color: #666 } /* Literal.Number.Integer */ +.mo { color: #666 } /* Literal.Number.Oct */ +.sa { color: #BA2121 } /* Literal.String.Affix */ +.sb { color: #BA2121 } /* Literal.String.Backtick */ +.sc { color: #BA2121 } /* Literal.String.Char */ +.dl { color: #BA2121 } /* Literal.String.Delimiter */ +.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.s2 { color: #BA2121 } /* Literal.String.Double */ +.se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.sh { color: #BA2121 } /* Literal.String.Heredoc */ +.si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.sx { color: #008000 } /* Literal.String.Other */ +.sr { color: #A45A77 } /* Literal.String.Regex */ +.s1 { color: #BA2121 } /* Literal.String.Single */ +.ss { color: #19177C } /* Literal.String.Symbol */ +.bp { color: #008000 } /* Name.Builtin.Pseudo */ +.fm { color: #00F } /* Name.Function.Magic */ +.vc { color: #19177C } /* Name.Variable.Class */ +.vg { color: #19177C } /* Name.Variable.Global */ +.vi { color: #19177C } /* Name.Variable.Instance */ +.vm { color: #19177C } /* Name.Variable.Magic */ +.il { color: #666 } /* Literal.Number.Integer.Long */ diff --git a/json/gcovr-output/index.html b/json/gcovr-output/index.html new file mode 100644 index 00000000..52ecc3e9 --- /dev/null +++ b/json/gcovr-output/index.html @@ -0,0 +1,2455 @@ + + + + + + GCC Code Coverage Report + + + + + + +
+
+
+

GCC Code Coverage Report

+
+
+
+
+
+ + + + + + + + + +
Directory:boost-root/libs/json/include/boost/json/
Coverage: + low: ≥ 0% + medium: ≥ 75.0% + high: ≥ 90.0% +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
CoverageExec / Excl / Total
Lines:93.3%8225 / 0 / 8811
Functions:-%0 / 0 / 0
Branches:-%0 / 0 / 0
+
+
+
+
+ +
+
+
+
File
+
+
Lines
+
Functions
+
Branches
+
+
+
+
+ + array.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 29 / 0 / 29 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 11 / 0 / 11 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 98.3 + +
+
+ 98.3% + 1253 / 0 / 1275 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 9 / 0 / 9 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 44 / 0 / 44 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 0.0 + +
+
+ 0.0% + 0 / 0 / 53 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 0.0 + +
+
+ 0.0% + 0 / 0 / 3 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 88.0 + +
+
+ 88.0% + 95 / 0 / 108 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 89.9 + +
+
+ 89.9% + 213 / 0 / 237 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 94.7 + +
+
+ 94.7% + 54 / 0 / 57 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 76.9 + +
+
+ 76.9% + 143 / 0 / 186 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 62.7 + +
+
+ 62.7% + 52 / 0 / 83 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 42.9 + +
+
+ 42.9% + 27 / 0 / 63 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 0.0 + +
+
+ 0.0% + 0 / 0 / 49 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 0.0 + +
+
+ 0.0% + 0 / 0 / 56 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 0.0 + +
+
+ 0.0% + 0 / 0 / 40 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 0.0 + +
+
+ 0.0% + 0 / 0 / 162 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 25.0 + +
+
+ 25.0% + 3 / 0 / 12 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 4 / 0 / 4 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 4 / 0 / 4 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 27 / 0 / 27 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 15 / 0 / 15 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 87.5 + +
+
+ 87.5% + 7 / 0 / 8 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 8 / 0 / 8 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 40 / 0 / 40 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 50 / 0 / 50 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 6 / 0 / 6 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 55 / 0 / 55 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 43 / 0 / 43 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 99.1 + +
+
+ 99.1% + 227 / 0 / 229 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 2 / 0 / 2 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 13 / 0 / 13 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 395 / 0 / 395 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 38 / 0 / 38 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 42 / 0 / 42 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 4 / 0 / 4 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 28 / 0 / 28 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 2 / 0 / 2 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 99.6 + +
+
+ 99.6% + 224 / 0 / 225 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 44 / 0 / 44 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 9 / 0 / 9 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + detail/sse2.hpp + +
+
+
+ + 97.8 + +
+
+ 97.8% + 134 / 0 / 137 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 13 / 0 / 13 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 101 / 0 / 101 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 73 / 0 / 73 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + detail/utf8.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 62 / 0 / 62 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 61 / 0 / 61 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 46 / 0 / 46 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 157 / 0 / 157 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/array.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 163 / 0 / 163 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/array.ipp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 389 / 0 / 389 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 18 / 0 / 18 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/error.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 5 / 0 / 5 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/error.ipp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 74 / 0 / 74 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/kind.ipp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 14 / 0 / 14 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 97.1 + +
+
+ 97.1% + 67 / 0 / 69 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 77.8 + +
+
+ 77.8% + 7 / 0 / 9 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/object.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 168 / 0 / 168 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/object.ipp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 435 / 0 / 435 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/parse.ipp + +
+
+
+ + 96.1 + +
+
+ 96.1% + 49 / 0 / 51 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 43 / 0 / 43 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/parser.ipp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 59 / 0 / 59 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 244 / 0 / 244 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 8 / 0 / 8 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 96.0 + +
+
+ 96.0% + 95 / 0 / 99 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 97.8 + +
+
+ 97.8% + 178 / 0 / 182 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 261 / 0 / 261 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 81.8 + +
+
+ 81.8% + 18 / 0 / 22 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 67 / 0 / 67 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/string.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 69 / 0 / 69 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/string.ipp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 167 / 0 / 167 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/value.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 3 / 0 / 3 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/value.ipp + +
+
+
+ + 98.7 + +
+
+ 98.7% + 456 / 0 / 462 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 7 / 0 / 7 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 96.0 + +
+
+ 96.0% + 72 / 0 / 75 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 99.5 + +
+
+ 99.5% + 198 / 0 / 199 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + impl/visit.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 37 / 0 / 37 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+ + 100.0 + +
+
+ 100.0% + 3 / 0 / 3 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + object.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 37 / 0 / 37 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + parser.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 29 / 0 / 29 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + pilfer.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 7 / 0 / 7 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + result_for.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 3 / 0 / 3 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + serializer.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 4 / 0 / 4 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 3 / 0 / 3 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + storage_ptr.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 68 / 0 / 68 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+ +
+
+ + 100.0 + +
+
+ 100.0% + 31 / 0 / 31 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + string.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 151 / 0 / 151 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + value.hpp + +
+
+
+ + 98.9 + +
+
+ 98.9% + 516 / 0 / 522 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + value_from.hpp + +
+
+
+ + 92.3 + +
+
+ 92.3% + 12 / 0 / 13 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + value_ref.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 114 / 0 / 114 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+
+
+ + value_to.hpp + +
+
+
+ + 100.0 + +
+
+ 100.0% + 9 / 0 / 9 +
+
+ -% + 0 / 0 / 0 +
+
+ -% + 0 / 0 / 0 +
+
+
+ +
+
+ +
+
+ + + diff --git a/json/gcovr-output/index.js b/json/gcovr-output/index.js new file mode 100644 index 00000000..23b16d75 --- /dev/null +++ b/json/gcovr-output/index.js @@ -0,0 +1,158 @@ +/* +This file is inspired by coverage.py's js code. +*/ + +gcovr = {}; + +gcovr.fileLoaded = function () { + gcovr.addOnClickHandler(".button_toggle_coveredLine", gcovr.toggleLines); + gcovr.addOnClickHandler(".button_toggle_uncoveredLine", gcovr.toggleLines); + gcovr.addOnClickHandler(".button_toggle_partialCoveredLine", gcovr.toggleLines); + gcovr.addOnClickHandler(".button_toggle_excludedLine", gcovr.toggleLines); + + gcovr.addOnClickHandler("div.sortable", gcovr.sortGridTable); + + gcovr.source_table_body = document.querySelector(".source-table-container > table > tbody") + gcovr.initScrollMarkers(); + window.addEventListener("resize", () => { + gcovr.initScrollMarkers(); + }); +}; + +gcovr.addOnClickHandler = function (selector, handler) { + document.querySelectorAll(selector).forEach(elt => { + elt.style.cursor = "pointer"; + elt.addEventListener("click", handler) + }); +}; + + +gcovr.toggleLines = function (event) { + const btn = event.target.closest("button"); + const category = btn.value + const show = !btn.classList.contains("show_" + category); + gcovr.setLineVisibility(btn, category, show); + gcovr.buildScrollMarkers(); +}; + +gcovr.setLineVisibility = function (btn, category, should_show) { + const cls = "show_" + category; + if (should_show) { + btn.closest("main").querySelectorAll("td." + category).forEach(e => e.classList.add(cls)); + btn.classList.add(cls); + } + else { + btn.closest("main").querySelectorAll("td." + category).forEach(e => e.classList.remove(cls)); + btn.classList.remove(cls); + } +}; + +gcovr.initScrollMarkers = function () { + if (gcovr.source_table_body === null) { + const temp_scroll_marker = document.getElementById("scroll_marker") + if (temp_scroll_marker) { + temp_scroll_marker.remove(); + } + } + else { + gcovr.lines_len = gcovr.source_table_body.querySelectorAll("tr").length - 1; // exclude header + gcovr.buildScrollMarkers(); + } +}; + +gcovr.buildScrollMarkers = function () { + const temp_scroll_marker = document.getElementById("scroll_marker") + if (temp_scroll_marker) temp_scroll_marker.remove(); + // Don't build markers if the window has no scroll bar. + if (document.body.scrollHeight <= window.innerHeight) { + return; + } + + const marker_scale = window.innerHeight / document.body.scrollHeight; + const line_height = Math.max(3, window.innerHeight / gcovr.lines_len); + const offset_table_start = gcovr.source_table_body.querySelector("td").getBoundingClientRect().top; + + let previous_line = -99, last_mark, last_top; + + const scroll_marker = document.createElement("div"); + scroll_marker.id = "scroll_marker"; + gcovr.source_table_body.querySelectorAll( + "tr:has(td.show_coveredLine), tr:has(td.show_uncoveredLine), tr:has(td.show_excludedLine), tr:has(td.show_partialCoveredLine)" + ).forEach(element => { + const line_top = Math.floor((offset_table_start + element.offsetTop) * marker_scale); + const line_number = parseInt(element.querySelector("td > a").textContent); + + if (line_number === previous_line + 1) { + // If this solid missed block just make previous mark higher. + last_mark.style.height = `${line_top + line_height - last_top}px`; + } + else { + // Add colored line in scroll_marker block. + last_mark = document.createElement("div"); + last_mark.id = `m${line_number}`; + last_mark.classList.add("marker"); + last_mark.style.height = `${line_height}px`; + last_mark.style.top = `${line_top}px`; + scroll_marker.append(last_mark); + last_top = line_top; + } + + previous_line = line_number; + }); + + // Append last to prevent layout calculation + document.body.append(scroll_marker); +}; + +gcovr.sortGridTable = function (event) { + const rowHeaderColumn = event.target.closest('div.sortable'); + const table = rowHeaderColumn.closest('.Box'); + const rows = Array.from(table.querySelectorAll('.Box-row')); + + const columnIndex = Array.from(rowHeaderColumn.parentNode.children).indexOf(rowHeaderColumn); + const isAscending = rowHeaderColumn.classList.contains('sorted-ascending'); + + rows.sort((a, b) => { + const cellA = + a.children[columnIndex].hasAttribute('data-sort') + ? a.children[columnIndex].getAttribute('data-sort') + : a.children[columnIndex].textContent.trim().toLowerCase(); + const cellB = + b.children[columnIndex].hasAttribute('data-sort') + ? b.children[columnIndex].getAttribute('data-sort') + : b.children[columnIndex].textContent.trim().toLowerCase(); + + let comparison = 0; + if (!isNaN(parseFloat(cellA)) && !isNaN(parseFloat(cellB))) { + comparison = parseFloat(cellA) - parseFloat(cellB); + } else { + comparison = cellA.localeCompare(cellB); + } + + if (comparison == 0) { + // Fallback to first column (ascending) for stable sorting + const firstCellA = a.children[0].textContent.trim().toLowerCase(); + const firstCellB = b.children[0].textContent.trim().toLowerCase(); + return firstCellA.localeCompare(firstCellB); + } + + return isAscending ? -comparison : comparison; + }); + + + // Remove existing rows + rows.forEach(row => table.removeChild(row)); + + // Append sorted rows + rows.forEach(row => table.appendChild(row)); + + // Update header classes + Array.from(rowHeaderColumn.parentNode.children).forEach(th => { + th.classList.remove('sorted-ascending', 'sorted-descending'); + }); + rowHeaderColumn.classList.add(isAscending ? 'sorted-descending' : 'sorted-ascending'); +} + +document.addEventListener("DOMContentLoaded", () => { + gcovr.fileLoaded(); +}); diff --git a/json/gcovr/index.array.hpp.161c04ed0fb44652959476d632ffe1a5.html b/json/gcovr/index.array.hpp.161c04ed0fb44652959476d632ffe1a5.html new file mode 100644 index 00000000..009dbc7c --- /dev/null +++ b/json/gcovr/index.array.hpp.161c04ed0fb44652959476d632ffe1a5.html @@ -0,0 +1,2726 @@ + + + + + + detail/array.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/array.hpp

+
+ + 100.0% Lines (9/9) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/array.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_ARRAY_HPP
+ 11 + + #define BOOST_JSON_DETAIL_ARRAY_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/json/storage_ptr.hpp>
+ 15 + + #include <cstddef>
+ 16 + +
+ 17 + + namespace boost {
+ 18 + + namespace json {
+ 19 + +
+ 20 + + class value;
+ 21 + +
+ 22 + + namespace detail {
+ 23 + +
+ 24 + + class unchecked_array
+ 25 + + {
+ 26 + + value* data_;
+ 27 + + std::size_t size_;
+ 28 + + storage_ptr const& sp_;
+ 29 + +
+ 30 + + public:
+ 31 + + inline
+ 32 + + ~unchecked_array();
+ 33 + +
+ 34 + +2120 unchecked_array(
+ 35 + + value* data,
+ 36 + + std::size_t size,
+ 37 + + storage_ptr const& sp) noexcept
+ 38 + +2120 : data_(data)
+ 39 + +2120 , size_(size)
+ 40 + +2120 , sp_(sp)
+ 41 + + {
+ 42 + +2120 }
+ 43 + +
+ 44 + + unchecked_array(
+ 45 + + unchecked_array&& other) noexcept
+ 46 + + : data_(other.data_)
+ 47 + + , size_(other.size_)
+ 48 + + , sp_(other.sp_)
+ 49 + + {
+ 50 + + other.data_ = nullptr;
+ 51 + + }
+ 52 + +
+ 53 + + storage_ptr const&
+ 54 + +2120 storage() const noexcept
+ 55 + + {
+ 56 + +2120 return sp_;
+ 57 + + }
+ 58 + +
+ 59 + + std::size_t
+ 60 + +4684 size() const noexcept
+ 61 + + {
+ 62 + +4684 return size_;
+ 63 + + }
+ 64 + +
+ 65 + + inline
+ 66 + + void
+ 67 + + relocate(value* dest) noexcept;
+ 68 + + };
+ 69 + +
+ 70 + + } // detail
+ 71 + +
+ 72 + + } // namespace json
+ 73 + + } // namespace boost
+ 74 + +
+ 75 + + // includes are at the bottom of <boost/json/value.hpp>
+ 76 + +
+ 77 + + #endif
+ 78 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.array.hpp.43ca8a64d5cb1e0e18bac819d8dd589d.html b/json/gcovr/index.array.hpp.43ca8a64d5cb1e0e18bac819d8dd589d.html new file mode 100644 index 00000000..2d28577e --- /dev/null +++ b/json/gcovr/index.array.hpp.43ca8a64d5cb1e0e18bac819d8dd589d.html @@ -0,0 +1,6726 @@ + + + + + + impl/array.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/array.hpp

+
+ + 100.0% Lines (163/163) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/array.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_ARRAY_HPP
+ 11 + + #define BOOST_JSON_IMPL_ARRAY_HPP
+ 12 + +
+ 13 + + #include <boost/core/detail/static_assert.hpp>
+ 14 + + #include <boost/json/value.hpp>
+ 15 + + #include <boost/json/detail/except.hpp>
+ 16 + + #include <algorithm>
+ 17 + + #include <stdexcept>
+ 18 + + #include <type_traits>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + +
+ 23 + + //----------------------------------------------------------
+ 24 + +
+ 25 + + struct alignas(value)
+ 26 + + array::table
+ 27 + + {
+ 28 + + std::uint32_t size = 0;
+ 29 + + std::uint32_t capacity = 0;
+ 30 + +
+ 31 + + constexpr table();
+ 32 + +
+ 33 + + value&
+ 34 + +37658 operator[](std::size_t pos) noexcept
+ 35 + + {
+ 36 + + return (reinterpret_cast<
+ 37 + +37658 value*>(this + 1))[pos];
+ 38 + + }
+ 39 + +
+ 40 + + BOOST_JSON_DECL
+ 41 + + static
+ 42 + + table*
+ 43 + + allocate(
+ 44 + + std::size_t capacity,
+ 45 + + storage_ptr const& sp);
+ 46 + +
+ 47 + + BOOST_JSON_DECL
+ 48 + + static
+ 49 + + void
+ 50 + + deallocate(
+ 51 + + table* p,
+ 52 + + storage_ptr const& sp);
+ 53 + + };
+ 54 + +
+ 55 + + //----------------------------------------------------------
+ 56 + +
+ 57 + + class array::revert_construct
+ 58 + + {
+ 59 + + array* arr_;
+ 60 + +
+ 61 + + public:
+ 62 + + explicit
+ 63 + +407 revert_construct(
+ 64 + + array& arr) noexcept
+ 65 + +407 : arr_(&arr)
+ 66 + + {
+ 67 + +407 }
+ 68 + +
+ 69 + +407 ~revert_construct()
+ 70 + +64 {
+ 71 + +407 if(! arr_)
+ 72 + +343 return;
+ 73 + +64 arr_->destroy();
+ 74 + +407 }
+ 75 + +
+ 76 + + void
+ 77 + +343 commit() noexcept
+ 78 + + {
+ 79 + +343 arr_ = nullptr;
+ 80 + +343 }
+ 81 + + };
+ 82 + +
+ 83 + + //----------------------------------------------------------
+ 84 + +
+ 85 + + class array::revert_insert
+ 86 + + {
+ 87 + + array* arr_;
+ 88 + + std::size_t const i_;
+ 89 + + std::size_t const n_;
+ 90 + +
+ 91 + + public:
+ 92 + + value* p;
+ 93 + +
+ 94 + + BOOST_JSON_DECL
+ 95 + + revert_insert(
+ 96 + + const_iterator pos,
+ 97 + + std::size_t n,
+ 98 + + array& arr);
+ 99 + +
+ 100 + + BOOST_JSON_DECL
+ 101 + + ~revert_insert();
+ 102 + +
+ 103 + + value*
+ 104 + +18 commit() noexcept
+ 105 + + {
+ 106 + + auto it =
+ 107 + +18 arr_->data() + i_;
+ 108 + +18 arr_ = nullptr;
+ 109 + +18 return it;
+ 110 + + }
+ 111 + + };
+ 112 + +
+ 113 + + //----------------------------------------------------------
+ 114 + +
+ 115 + + void
+ 116 + +787 array::
+ 117 + + relocate(
+ 118 + + value* dest,
+ 119 + + value* src,
+ 120 + + std::size_t n) noexcept
+ 121 + + {
+ 122 + +787 if(n == 0)
+ 123 + +650 return;
+ 124 + +137 std::memmove(
+ 125 + + static_cast<void*>(dest),
+ 126 + + static_cast<void const*>(src),
+ 127 + + n * sizeof(value));
+ 128 + + }
+ 129 + +
+ 130 + + //----------------------------------------------------------
+ 131 + + //
+ 132 + + // Construction
+ 133 + + //
+ 134 + + //----------------------------------------------------------
+ 135 + +
+ 136 + + template<class InputIt, class>
+ 137 + +37 array::
+ 138 + + array(
+ 139 + + InputIt first, InputIt last,
+ 140 + + storage_ptr sp)
+ 141 + + : array(
+ 142 + + first, last,
+ 143 + +37 std::move(sp),
+ 144 + +40 iter_cat<InputIt>{})
+ 145 + + {
+ 146 + + BOOST_CORE_STATIC_ASSERT((
+ 147 + + std::is_constructible<value, decltype(*first)>::value));
+ 148 + +21 }
+ 149 + +
+ 150 + + //----------------------------------------------------------
+ 151 + + //
+ 152 + + // Modifiers
+ 153 + + //
+ 154 + + //----------------------------------------------------------
+ 155 + +
+ 156 + + template<class InputIt, class>
+ 157 + + auto
+ 158 + +27 array::
+ 159 + + insert(
+ 160 + + const_iterator pos,
+ 161 + + InputIt first, InputIt last) ->
+ 162 + + iterator
+ 163 + + {
+ 164 + + BOOST_CORE_STATIC_ASSERT((
+ 165 + + std::is_constructible<value, decltype(*first)>::value));
+ 166 + +37 return insert(pos, first, last,
+ 167 + +23 iter_cat<InputIt>{});
+ 168 + + }
+ 169 + +
+ 170 + + template<class Arg>
+ 171 + + auto
+ 172 + +13 array::
+ 173 + + emplace(
+ 174 + + const_iterator pos,
+ 175 + + Arg&& arg) ->
+ 176 + + iterator
+ 177 + + {
+ 178 + +13 BOOST_ASSERT(
+ 179 + + pos >= begin() &&
+ 180 + + pos <= end());
+ 181 + +21 value jv(
+ 182 + +7 std::forward<Arg>(arg),
+ 183 + + storage());
+ 184 + +19 return insert(pos, pilfer(jv));
+ 185 + +12 }
+ 186 + +
+ 187 + + template<class Arg>
+ 188 + + value&
+ 189 + +7575 array::
+ 190 + + emplace_back(Arg&& arg)
+ 191 + + {
+ 192 + +7609 value jv(
+ 193 + +31 std::forward<Arg>(arg),
+ 194 + + storage());
+ 195 + +15139 return push_back(pilfer(jv));
+ 196 + +7572 }
+ 197 + +
+ 198 + + //----------------------------------------------------------
+ 199 + + //
+ 200 + + // Element access
+ 201 + + //
+ 202 + + //----------------------------------------------------------
+ 203 + +
+ 204 + + value&
+ 205 + +36 array::
+ 206 + + at(std::size_t pos, source_location const& loc) &
+ 207 + + {
+ 208 + +36 auto const& self = *this;
+ 209 + +36 return const_cast< value& >( self.at(pos, loc) );
+ 210 + + }
+ 211 + +
+ 212 + + value&&
+ 213 + +16 array::
+ 214 + + at(std::size_t pos, source_location const& loc) &&
+ 215 + + {
+ 216 + +16 return std::move( at(pos, loc) );
+ 217 + + }
+ 218 + +
+ 219 + + value&
+ 220 + +46 array::
+ 221 + + operator[](std::size_t pos) & noexcept
+ 222 + + {
+ 223 + +46 BOOST_ASSERT(pos < t_->size);
+ 224 + +46 return (*t_)[pos];
+ 225 + + }
+ 226 + +
+ 227 + + value&&
+ 228 + +4 array::
+ 229 + + operator[](std::size_t pos) && noexcept
+ 230 + + {
+ 231 + +4 return std::move( (*this)[pos] );
+ 232 + + }
+ 233 + +
+ 234 + + value const&
+ 235 + +6698 array::
+ 236 + + operator[](std::size_t pos) const& noexcept
+ 237 + + {
+ 238 + +6698 BOOST_ASSERT(pos < t_->size);
+ 239 + +6698 return (*t_)[pos];
+ 240 + + }
+ 241 + +
+ 242 + + value&
+ 243 + +5 array::
+ 244 + + front() & noexcept
+ 245 + + {
+ 246 + +5 BOOST_ASSERT(t_->size > 0);
+ 247 + +5 return (*t_)[0];
+ 248 + + }
+ 249 + +
+ 250 + + value&&
+ 251 + +2 array::
+ 252 + + front() && noexcept
+ 253 + + {
+ 254 + +2 return std::move( front() );
+ 255 + + }
+ 256 + +
+ 257 + + value const&
+ 258 + +1 array::
+ 259 + + front() const& noexcept
+ 260 + + {
+ 261 + +1 BOOST_ASSERT(t_->size > 0);
+ 262 + +1 return (*t_)[0];
+ 263 + + }
+ 264 + +
+ 265 + + value&
+ 266 + +7 array::
+ 267 + + back() & noexcept
+ 268 + + {
+ 269 + +7 BOOST_ASSERT(
+ 270 + + t_->size > 0);
+ 271 + +7 return (*t_)[t_->size - 1];
+ 272 + + }
+ 273 + +
+ 274 + + value&&
+ 275 + +2 array::
+ 276 + + back() && noexcept
+ 277 + + {
+ 278 + +2 return std::move( back() );
+ 279 + + }
+ 280 + +
+ 281 + + value const&
+ 282 + +1 array::
+ 283 + + back() const& noexcept
+ 284 + + {
+ 285 + +1 BOOST_ASSERT(
+ 286 + + t_->size > 0);
+ 287 + +1 return (*t_)[t_->size - 1];
+ 288 + + }
+ 289 + +
+ 290 + + value*
+ 291 + +1772 array::
+ 292 + + data() noexcept
+ 293 + + {
+ 294 + +1772 return &(*t_)[0];
+ 295 + + }
+ 296 + +
+ 297 + + value const*
+ 298 + +190 array::
+ 299 + + data() const noexcept
+ 300 + + {
+ 301 + +190 return &(*t_)[0];
+ 302 + + }
+ 303 + +
+ 304 + + value const*
+ 305 + +17 array::
+ 306 + + if_contains(
+ 307 + + std::size_t pos) const noexcept
+ 308 + + {
+ 309 + +17 if( pos < t_->size )
+ 310 + +14 return &(*t_)[pos];
+ 311 + +3 return nullptr;
+ 312 + + }
+ 313 + +
+ 314 + + value*
+ 315 + +3 array::
+ 316 + + if_contains(
+ 317 + + std::size_t pos) noexcept
+ 318 + + {
+ 319 + +3 if( pos < t_->size )
+ 320 + +2 return &(*t_)[pos];
+ 321 + +1 return nullptr;
+ 322 + + }
+ 323 + +
+ 324 + + //----------------------------------------------------------
+ 325 + + //
+ 326 + + // Iterators
+ 327 + + //
+ 328 + + //----------------------------------------------------------
+ 329 + +
+ 330 + + auto
+ 331 + +3838 array::
+ 332 + + begin() noexcept ->
+ 333 + + iterator
+ 334 + + {
+ 335 + +3838 return &(*t_)[0];
+ 336 + + }
+ 337 + +
+ 338 + + auto
+ 339 + +5663 array::
+ 340 + + begin() const noexcept ->
+ 341 + + const_iterator
+ 342 + + {
+ 343 + +5663 return &(*t_)[0];
+ 344 + + }
+ 345 + +
+ 346 + + auto
+ 347 + +3 array::
+ 348 + + cbegin() const noexcept ->
+ 349 + + const_iterator
+ 350 + + {
+ 351 + +3 return &(*t_)[0];
+ 352 + + }
+ 353 + +
+ 354 + + auto
+ 355 + +3991 array::
+ 356 + + end() noexcept ->
+ 357 + + iterator
+ 358 + + {
+ 359 + +3991 return &(*t_)[t_->size];
+ 360 + + }
+ 361 + +
+ 362 + + auto
+ 363 + +6186 array::
+ 364 + + end() const noexcept ->
+ 365 + + const_iterator
+ 366 + + {
+ 367 + +6186 return &(*t_)[t_->size];
+ 368 + + }
+ 369 + +
+ 370 + + auto
+ 371 + +3 array::
+ 372 + + cend() const noexcept ->
+ 373 + + const_iterator
+ 374 + + {
+ 375 + +3 return &(*t_)[t_->size];
+ 376 + + }
+ 377 + +
+ 378 + + auto
+ 379 + +3 array::
+ 380 + + rbegin() noexcept ->
+ 381 + + reverse_iterator
+ 382 + + {
+ 383 + +3 return reverse_iterator(end());
+ 384 + + }
+ 385 + +
+ 386 + + auto
+ 387 + +3 array::
+ 388 + + rbegin() const noexcept ->
+ 389 + + const_reverse_iterator
+ 390 + + {
+ 391 + +3 return const_reverse_iterator(end());
+ 392 + + }
+ 393 + +
+ 394 + + auto
+ 395 + +3 array::
+ 396 + + crbegin() const noexcept ->
+ 397 + + const_reverse_iterator
+ 398 + + {
+ 399 + +3 return const_reverse_iterator(end());
+ 400 + + }
+ 401 + +
+ 402 + + auto
+ 403 + +3 array::
+ 404 + + rend() noexcept ->
+ 405 + + reverse_iterator
+ 406 + + {
+ 407 + +3 return reverse_iterator(begin());
+ 408 + + }
+ 409 + +
+ 410 + + auto
+ 411 + +3 array::
+ 412 + + rend() const noexcept ->
+ 413 + + const_reverse_iterator
+ 414 + + {
+ 415 + +3 return const_reverse_iterator(begin());
+ 416 + + }
+ 417 + +
+ 418 + + auto
+ 419 + +3 array::
+ 420 + + crend() const noexcept ->
+ 421 + + const_reverse_iterator
+ 422 + + {
+ 423 + +3 return const_reverse_iterator(begin());
+ 424 + + }
+ 425 + +
+ 426 + + //----------------------------------------------------------
+ 427 + + //
+ 428 + + // Capacity
+ 429 + + //
+ 430 + + //----------------------------------------------------------
+ 431 + +
+ 432 + + std::size_t
+ 433 + +6511 array::
+ 434 + + size() const noexcept
+ 435 + + {
+ 436 + +6511 return t_->size;
+ 437 + + }
+ 438 + +
+ 439 + + constexpr
+ 440 + + std::size_t
+ 441 + +4131 array::
+ 442 + + max_size() noexcept
+ 443 + + {
+ 444 + + // max_size depends on the address model
+ 445 + + using min = std::integral_constant<std::size_t,
+ 446 + + (std::size_t(-1) - sizeof(table)) / sizeof(value)>;
+ 447 + + return min::value < BOOST_JSON_MAX_STRUCTURED_SIZE ?
+ 448 + +4131 min::value : BOOST_JSON_MAX_STRUCTURED_SIZE;
+ 449 + + }
+ 450 + +
+ 451 + + std::size_t
+ 452 + +848 array::
+ 453 + + capacity() const noexcept
+ 454 + + {
+ 455 + +848 return t_->capacity;
+ 456 + + }
+ 457 + +
+ 458 + + bool
+ 459 + +195 array::
+ 460 + + empty() const noexcept
+ 461 + + {
+ 462 + +195 return t_->size == 0;
+ 463 + + }
+ 464 + +
+ 465 + + void
+ 466 + +701 array::
+ 467 + + reserve(
+ 468 + + std::size_t new_capacity)
+ 469 + + {
+ 470 + + // never shrink
+ 471 + +701 if(new_capacity <= t_->capacity)
+ 472 + +37 return;
+ 473 + +664 reserve_impl(new_capacity);
+ 474 + + }
+ 475 + +
+ 476 + + //----------------------------------------------------------
+ 477 + + //
+ 478 + + // private
+ 479 + + //
+ 480 + + //----------------------------------------------------------
+ 481 + +
+ 482 + + template<class InputIt>
+ 483 + +19 array::
+ 484 + + array(
+ 485 + + InputIt first, InputIt last,
+ 486 + + storage_ptr sp,
+ 487 + + std::input_iterator_tag)
+ 488 + +19 : sp_(std::move(sp))
+ 489 + +19 , t_(&empty_)
+ 490 + + {
+ 491 + +19 revert_construct r(*this);
+ 492 + +86 while(first != last)
+ 493 + + {
+ 494 + +80 reserve(size() + 1);
+ 495 + +138 ::new(end()) value(
+ 496 + +136 *first++, sp_);
+ 497 + +67 ++t_->size;
+ 498 + + }
+ 499 + +6 r.commit();
+ 500 + +32 }
+ 501 + +
+ 502 + + template<class InputIt>
+ 503 + +18 array::
+ 504 + + array(
+ 505 + + InputIt first, InputIt last,
+ 506 + + storage_ptr sp,
+ 507 + + std::forward_iterator_tag)
+ 508 + +18 : sp_(std::move(sp))
+ 509 + + {
+ 510 + +18 std::size_t n =
+ 511 + +18 std::distance(first, last);
+ 512 + +18 if( n == 0 )
+ 513 + + {
+ 514 + +3 t_ = &empty_;
+ 515 + +3 return;
+ 516 + + }
+ 517 + +
+ 518 + +15 t_ = table::allocate(n, sp_);
+ 519 + +13 t_->size = 0;
+ 520 + +13 revert_construct r(*this);
+ 521 + +53 while(n--)
+ 522 + + {
+ 523 + +84 ::new(end()) value(
+ 524 + +41 *first++, sp_);
+ 525 + +40 ++t_->size;
+ 526 + + }
+ 527 + +12 r.commit();
+ 528 + +16 }
+ 529 + +
+ 530 + + template<class InputIt>
+ 531 + + auto
+ 532 + +13 array::
+ 533 + + insert(
+ 534 + + const_iterator pos,
+ 535 + + InputIt first, InputIt last,
+ 536 + + std::input_iterator_tag) ->
+ 537 + + iterator
+ 538 + + {
+ 539 + +13 BOOST_ASSERT(
+ 540 + + pos >= begin() && pos <= end());
+ 541 + +13 if(first == last)
+ 542 + +1 return data() + (pos - data());
+ 543 + +20 array temp(first, last, sp_);
+ 544 + +4 revert_insert r(
+ 545 + + pos, temp.size(), *this);
+ 546 + +2 relocate(
+ 547 + + r.p,
+ 548 + + temp.data(),
+ 549 + + temp.size());
+ 550 + +2 temp.t_->size = 0;
+ 551 + +2 return r.commit();
+ 552 + +4 }
+ 553 + +
+ 554 + + template<class InputIt>
+ 555 + + auto
+ 556 + +14 array::
+ 557 + + insert(
+ 558 + + const_iterator pos,
+ 559 + + InputIt first, InputIt last,
+ 560 + + std::forward_iterator_tag) ->
+ 561 + + iterator
+ 562 + + {
+ 563 + +14 std::size_t n =
+ 564 + +14 std::distance(first, last);
+ 565 + +14 revert_insert r(pos, n, *this);
+ 566 + +3050 while(n--)
+ 567 + + {
+ 568 + +3040 ::new(r.p) value(*first++);
+ 569 + +3040 ++r.p;
+ 570 + + }
+ 571 + +20 return r.commit();
+ 572 + +10 }
+ 573 + +
+ 574 + + } // namespace json
+ 575 + + } // namespace boost
+ 576 + +
+ 577 + + #endif
+ 578 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.array.hpp.6e0bda7bf6757e548b5faad83e899291.html b/json/gcovr/index.array.hpp.6e0bda7bf6757e548b5faad83e899291.html new file mode 100644 index 00000000..ef967dd1 --- /dev/null +++ b/json/gcovr/index.array.hpp.6e0bda7bf6757e548b5faad83e899291.html @@ -0,0 +1,13566 @@ + + + + + + array.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

array.hpp

+
+ + 100.0% Lines (29/29) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
array.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_ARRAY_HPP
+ 11 + + #define BOOST_JSON_ARRAY_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/json/detail/array.hpp>
+ 15 + + #include <boost/json/kind.hpp>
+ 16 + + #include <boost/json/pilfer.hpp>
+ 17 + + #include <boost/json/storage_ptr.hpp>
+ 18 + + #include <boost/system/result.hpp>
+ 19 + + #include <cstdlib>
+ 20 + + #include <initializer_list>
+ 21 + + #include <iterator>
+ 22 + +
+ 23 + + namespace boost {
+ 24 + + namespace json {
+ 25 + +
+ 26 + + #ifndef BOOST_JSON_DOCS
+ 27 + + class value;
+ 28 + + class value_ref;
+ 29 + + #endif
+ 30 + +
+ 31 + + /** A dynamically sized array of JSON values
+ 32 + +
+ 33 + + This is the type used to represent a JSON array as a modifiable container.
+ 34 + + The interface and performance characteristics are modeled after
+ 35 + + `std::vector<value>`.
+ 36 + +
+ 37 + + Elements are stored contiguously, which means that they can be accessed not
+ 38 + + only through iterators, but also using offsets to regular pointers to
+ 39 + + elements. A pointer to an element of an `array` may be passed to any
+ 40 + + function that expects a pointer to @ref value.
+ 41 + +
+ 42 + + The storage of the array is handled automatically, being expanded and
+ 43 + + contracted as needed. Arrays usually occupy more space than array language
+ 44 + + constructs, because more memory is allocated to handle future growth. This
+ 45 + + way an array does not need to reallocate each time an element is inserted,
+ 46 + + but only when the additional memory is used up. The total amount of
+ 47 + + allocated memory can be queried using the @ref capacity function. Extra
+ 48 + + memory can be relinquished by calling @ref shrink_to_fit.
+ 49 + +
+ 50 + +
+ 51 + + Reallocations are usually costly operations in terms of performance. The
+ 52 + + @ref reserve function can be used to eliminate reallocations if the number
+ 53 + + of elements is known beforehand.
+ 54 + +
+ 55 + + The complexity (efficiency) of common operations on arrays is as follows:
+ 56 + +
+ 57 + + @li Random access---constant *O(1)*.
+ 58 + + @li Insertion or removal of elements at the end - amortized
+ 59 + + constant *O(1)*.
+ 60 + + @li Insertion or removal of elements---linear in the distance to the end of
+ 61 + + the array *O(n)*.
+ 62 + +
+ 63 + + @par Allocators
+ 64 + +
+ 65 + + All elements stored in the container, and their children if any, will use
+ 66 + + the same memory resource that was used to construct the container.
+ 67 + +
+ 68 + + @par Thread Safety
+ 69 + +
+ 70 + + Non-const member functions may not be called concurrently with any other
+ 71 + + member functions.
+ 72 + +
+ 73 + + @par Satisfies
+ 74 + + [*ContiguousContainer*](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
+ 75 + + [*ReversibleContainer*](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer), and
+ 76 + + {req_SequenceContainer}.
+ 77 + + */
+ 78 + + class array
+ 79 + + {
+ 80 + + struct table;
+ 81 + + class revert_construct;
+ 82 + + class revert_insert;
+ 83 + + friend class value;
+ 84 + +
+ 85 + + storage_ptr sp_; // must come first
+ 86 + + kind k_ = kind::array; // must come second
+ 87 + + table* t_;
+ 88 + +
+ 89 + + BOOST_JSON_DECL
+ 90 + + static table empty_;
+ 91 + +
+ 92 + + inline
+ 93 + + static
+ 94 + + void
+ 95 + + relocate(
+ 96 + + value* dest,
+ 97 + + value* src,
+ 98 + + std::size_t n) noexcept;
+ 99 + +
+ 100 + + inline
+ 101 + + void
+ 102 + + destroy(
+ 103 + + value* first,
+ 104 + + value* last) noexcept;
+ 105 + +
+ 106 + + BOOST_JSON_DECL
+ 107 + + void
+ 108 + + destroy() noexcept;
+ 109 + +
+ 110 + + BOOST_JSON_DECL
+ 111 + + explicit
+ 112 + + array(detail::unchecked_array&& ua);
+ 113 + +
+ 114 + + public:
+ 115 + + /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
+ 116 + + using allocator_type = container::pmr::polymorphic_allocator<value>;
+ 117 + +
+ 118 + + /// The type used to represent unsigned integers
+ 119 + + using size_type = std::size_t;
+ 120 + +
+ 121 + + /// The type of each element
+ 122 + + using value_type = value;
+ 123 + +
+ 124 + + /// The type used to represent signed integers
+ 125 + + using difference_type = std::ptrdiff_t;
+ 126 + +
+ 127 + + /// A reference to an element
+ 128 + + using reference = value&;
+ 129 + +
+ 130 + + /// A const reference to an element
+ 131 + + using const_reference = value const&;
+ 132 + +
+ 133 + + /// A pointer to an element
+ 134 + + using pointer = value*;
+ 135 + +
+ 136 + + /// A const pointer to an element
+ 137 + + using const_pointer = value const*;
+ 138 + +
+ 139 + + /// A random access iterator to an element
+ 140 + + using iterator = value*;
+ 141 + +
+ 142 + + /// A random access const iterator to an element
+ 143 + + using const_iterator = value const*;
+ 144 + +
+ 145 + + /// A reverse random access iterator to an element
+ 146 + + using reverse_iterator =
+ 147 + + std::reverse_iterator<iterator>;
+ 148 + +
+ 149 + + /// A reverse random access const iterator to an element
+ 150 + + using const_reverse_iterator =
+ 151 + + std::reverse_iterator<const_iterator>;
+ 152 + +
+ 153 + + //------------------------------------------------------
+ 154 + +
+ 155 + + /** Destructor.
+ 156 + +
+ 157 + + The destructor for each element is called if needed, any used memory is
+ 158 + + deallocated, and shared ownership of the
+ 159 + + @ref boost::container::pmr::memory_resource is released.
+ 160 + +
+ 161 + + @par Complexity
+ 162 + + Linear in @ref size().
+ 163 + +
+ 164 + + @par Exception Safety
+ 165 + + No-throw guarantee.
+ 166 + + */
+ 167 + + BOOST_JSON_DECL
+ 168 + + ~array() noexcept;
+ 169 + +
+ 170 + + //------------------------------------------------------
+ 171 + +
+ 172 + + /** Constructors.
+ 173 + +
+ 174 + + Constructs an array.
+ 175 + +
+ 176 + + @li **(1)**, **(2)** the array is empty and has zero capacity.
+ 177 + +
+ 178 + + @li **(3)** the array is filled with `count` copies of `jv`.
+ 179 + +
+ 180 + + @li **(4)** the array is filled with `count` null values.
+ 181 + +
+ 182 + + @li **(5)** the array is filled with values in the range
+ 183 + + `[first, last)`, preserving order.
+ 184 + +
+ 185 + + @li **(6)** the array is filled with copies of the values in `init`,
+ 186 + + preserving order.
+ 187 + +
+ 188 + + @li **(7)**, **(8)** the array is filled with copies of the elements of
+ 189 + + `other`, preserving order.
+ 190 + +
+ 191 + + @li **(9)** the array acquires ownership of the contents of `other`.
+ 192 + +
+ 193 + + @li **(10)** equivalent to **(9)** if `*sp == *other.storage()`;
+ 194 + + otherwise equivalent to **(8)**.
+ 195 + +
+ 196 + + @li **(11)** the array acquires ownership of the contents of `other`
+ 197 + + using pilfer semantics. This is more efficient than move
+ 198 + + construction, when it is known that the moved-from object will be
+ 199 + + immediately destroyed afterwards.
+ 200 + +
+ 201 + + With **(2)**, **(4)**, **(5)**, **(6)**, **(8)**, **(10)** the
+ 202 + + constructed array uses memory resource of `sp`. With **(7)**, **(9)**,
+ 203 + + and **(11)** it uses `other`'s memory resource. In either case the
+ 204 + + array will share the ownership of the memory resource. With **(1)**
+ 205 + + and **(3)** it uses the
+ 206 + + \<\<default_memory_resource, default memory resource\>\>.
+ 207 + +
+ 208 + + After **(9)** `other` behaves as if newly constructed with its
+ 209 + + current storage pointer.
+ 210 + +
+ 211 + + After **(11)** `other` is not in a usable state and may only be
+ 212 + + destroyed.
+ 213 + +
+ 214 + + @par Constraints
+ 215 + +
+ 216 + + @code
+ 217 + + std::is_constructible_v<value, std::iterator_traits<InputIt>::reference>
+ 218 + + @endcode
+ 219 + +
+ 220 + + @par Complexity
+ 221 + + @li **(1)**, **(2)**, **(9)**, **(11)** constant.
+ 222 + + @li **(3)**, **(4)** linear in `count`.
+ 223 + + @li **(5)** linear in `std::distance(first, last)`
+ 224 + + @li **(6)** linear in `init.size()`.
+ 225 + + @li **(7)**, **(8)** linear in `other.size()`.
+ 226 + + @li **(10)** constant if `*sp == *other.storage()`; otherwise linear in
+ 227 + + `other.size()`.
+ 228 + +
+ 229 + + @par Exception Safety
+ 230 + + @li **(1)**, **(2)**, **(9)**, **(11)** no-throw guarantee.
+ 231 + + @li **(3)**, **(4)**, **(6)**--**(8)**, **(10)** strong
+ 232 + + guarantee.
+ 233 + + @li **(5)** strong guarantee if `InputIt` satisfies
+ 234 + + {req_ForwardIterator}, basic guarantee otherwise.
+ 235 + +
+ 236 + + Calls to `memory_resource::allocate` may throw.
+ 237 + +
+ 238 + + @see @ref pilfer,
+ 239 + + [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
+ 240 + + @{
+ 241 + + */
+ 242 + +79 array() noexcept
+ 243 + +79 : t_(&empty_)
+ 244 + + {
+ 245 + +79 }
+ 246 + +
+ 247 + + /** Overload
+ 248 + + @param sp A pointer to the @ref boost::container::pmr::memory_resource
+ 249 + + to use. The container will acquire shared ownership of the memory
+ 250 + + resource.
+ 251 + + */
+ 252 + + explicit
+ 253 + +644 array(storage_ptr sp) noexcept
+ 254 + +644 : sp_(std::move(sp))
+ 255 + +644 , k_(kind::array)
+ 256 + +644 , t_(&empty_)
+ 257 + + {
+ 258 + +644 }
+ 259 + +
+ 260 + + /** Overload
+ 261 + + @param count The number of copies to insert.
+ 262 + + @param jv The value to be inserted.
+ 263 + + @param sp
+ 264 + + */
+ 265 + + BOOST_JSON_DECL
+ 266 + + array(
+ 267 + + std::size_t count,
+ 268 + + value const& jv,
+ 269 + + storage_ptr sp = {});
+ 270 + +
+ 271 + + /// Overload
+ 272 + + BOOST_JSON_DECL
+ 273 + + array(
+ 274 + + std::size_t count,
+ 275 + + storage_ptr sp = {});
+ 276 + +
+ 277 + + /** Overload
+ 278 + +
+ 279 + + @param first An input iterator pointing to the first element to insert,
+ 280 + + or pointing to the end of the range.
+ 281 + + @param last An input iterator pointing to the end of the range.
+ 282 + + @param sp
+ 283 + +
+ 284 + + @tparam InputIt a type satisfying the {req_InputIterator} requirement.
+ 285 + + */
+ 286 + + template<
+ 287 + + class InputIt
+ 288 + + #ifndef BOOST_JSON_DOCS
+ 289 + + ,class = typename std::enable_if<
+ 290 + + std::is_constructible<value,
+ 291 + + typename std::iterator_traits<
+ 292 + + InputIt>::reference>::value>::type
+ 293 + + #endif
+ 294 + + >
+ 295 + + array(
+ 296 + + InputIt first, InputIt last,
+ 297 + + storage_ptr sp = {});
+ 298 + +
+ 299 + + /** Overload
+ 300 + + @param init The initializer list with elements to insert.
+ 301 + + @param sp
+ 302 + + */
+ 303 + + BOOST_JSON_DECL
+ 304 + + array(
+ 305 + + std::initializer_list<value_ref> init,
+ 306 + + storage_ptr sp = {});
+ 307 + +
+ 308 + + /** Overload
+ 309 + + @param other Another array.
+ 310 + + */
+ 311 + + BOOST_JSON_DECL
+ 312 + + array(array const& other);
+ 313 + +
+ 314 + + /// Overload
+ 315 + + BOOST_JSON_DECL
+ 316 + + array(
+ 317 + + array const& other,
+ 318 + + storage_ptr sp);
+ 319 + +
+ 320 + + /// Overload
+ 321 + +188 array(array&& other) noexcept
+ 322 + +188 : sp_(other.sp_)
+ 323 + +376 , t_(detail::exchange(
+ 324 + +188 other.t_, &empty_))
+ 325 + + {
+ 326 + +188 }
+ 327 + +
+ 328 + + /// Overload
+ 329 + + BOOST_JSON_DECL
+ 330 + + array(
+ 331 + + array&& other,
+ 332 + + storage_ptr sp);
+ 333 + +
+ 334 + + /// Overload
+ 335 + +6 array(pilfered<array> other) noexcept
+ 336 + +6 : sp_(std::move(other.get().sp_))
+ 337 + +12 , t_(detail::exchange(
+ 338 + +6 other.get().t_, &empty_))
+ 339 + + {
+ 340 + +6 }
+ 341 + + /// @}
+ 342 + +
+ 343 + + /** Assignment operators.
+ 344 + +
+ 345 + + Replaces the contents of the array.
+ 346 + + @li **(1)** the contents are replaced with an element-wise copy of
+ 347 + + `other`.
+ 348 + + @li **(2)** takes ownership of `other`'s element storage if
+ 349 + + `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
+ 350 + + @li **(3)** the contents are replaced with a copy of the values in
+ 351 + + `init`.
+ 352 + +
+ 353 + + After **(2)**, the moved-from array behaves as if newly constructed
+ 354 + + with its current storage pointer.
+ 355 + +
+ 356 + + @par Complexity
+ 357 + + @li **(1)** linear in `size() + other.size()`.
+ 358 + + @li **(2)** constant if `*storage() == *other.storage()`; otherwise
+ 359 + + linear in `size() + other.size()`.
+ 360 + + @li **(1)** linear in `size() + init.size()`.
+ 361 + +
+ 362 + + @par Exception Safety
+ 363 + + {sp} **(2)** provides strong guarantee if
+ 364 + + `*storage() != *other.storage()` and no-throw guarantee otherwise.
+ 365 + + Other overloads provide strong guarantee.
+ 366 + + Calls to `memory_resource::allocate` may throw.
+ 367 + +
+ 368 + + @param other The array to copy.
+ 369 + +
+ 370 + + @return `*this`
+ 371 + +
+ 372 + + @{
+ 373 + + */
+ 374 + + BOOST_JSON_DECL
+ 375 + + array&
+ 376 + + operator=(array const& other);
+ 377 + +
+ 378 + + /** Overload
+ 379 + + @param other The array to move.
+ 380 + + */
+ 381 + + BOOST_JSON_DECL
+ 382 + + array&
+ 383 + + operator=(array&& other);
+ 384 + +
+ 385 + + /** Overload
+ 386 + + @param init The initializer list to copy.
+ 387 + + */
+ 388 + + BOOST_JSON_DECL
+ 389 + + array&
+ 390 + + operator=(
+ 391 + + std::initializer_list<value_ref> init);
+ 392 + + /// @}
+ 393 + +
+ 394 + + /** Return the associated memory resource.
+ 395 + +
+ 396 + + This function returns a smart pointer to the
+ 397 + + @ref boost::container::pmr::memory_resource used by the container.
+ 398 + +
+ 399 + + @par Complexity
+ 400 + + Constant.
+ 401 + +
+ 402 + + @par Exception Safety
+ 403 + + No-throw guarantee.
+ 404 + + */
+ 405 + + storage_ptr const&
+ 406 + +15208 storage() const noexcept
+ 407 + + {
+ 408 + +15208 return sp_;
+ 409 + + }
+ 410 + +
+ 411 + + /** Return the associated allocator.
+ 412 + +
+ 413 + + This function returns an instance of @ref allocator_type constructed
+ 414 + + from the associated @ref boost::container::pmr::memory_resource.
+ 415 + +
+ 416 + + @par Complexity
+ 417 + + Constant.
+ 418 + +
+ 419 + + @par Exception Safety
+ 420 + + No-throw guarantee.
+ 421 + + */
+ 422 + + allocator_type
+ 423 + +1 get_allocator() const noexcept
+ 424 + + {
+ 425 + +1 return sp_.get();
+ 426 + + }
+ 427 + +
+ 428 + + //------------------------------------------------------
+ 429 + + //
+ 430 + + // Element access
+ 431 + + //
+ 432 + + //------------------------------------------------------
+ 433 + +
+ 434 + + /** Access an element, with bounds checking.
+ 435 + +
+ 436 + + Returns @ref boost::system::result containing a reference to the
+ 437 + + element specified at location `pos`, if `pos` is within the range of
+ 438 + + the container. Otherwise the result contains an `error_code`.
+ 439 + +
+ 440 + + @par Exception Safety
+ 441 + + No-throw guarantee.
+ 442 + +
+ 443 + + @param pos A zero-based index.
+ 444 + +
+ 445 + + @par Complexity
+ 446 + + Constant.
+ 447 + +
+ 448 + + @{
+ 449 + + */
+ 450 + + BOOST_JSON_DECL
+ 451 + + system::result<value&>
+ 452 + + try_at(std::size_t pos) noexcept;
+ 453 + +
+ 454 + + BOOST_JSON_DECL
+ 455 + + system::result<value const&>
+ 456 + + try_at(std::size_t pos) const noexcept;
+ 457 + + /// @}
+ 458 + +
+ 459 + + /** Access an element, with bounds checking.
+ 460 + +
+ 461 + + Returns a reference to the element specified at location `pos`, with
+ 462 + + bounds checking. If `pos` is not within the range of the container, an
+ 463 + + exception of type @ref boost::system::system_error is thrown.
+ 464 + +
+ 465 + + @par Complexity
+ 466 + + Constant.
+ 467 + +
+ 468 + + @param pos A zero-based index.
+ 469 + +
+ 470 + + @param loc `source_location` to use in thrown exception; the source
+ 471 + + location of the call site by default.
+ 472 + +
+ 473 + + @throw `boost::system::system_error` `pos >= size()`.
+ 474 + +
+ 475 + + @{
+ 476 + + */
+ 477 + + inline
+ 478 + + value&
+ 479 + + at(
+ 480 + + std::size_t pos,
+ 481 + + source_location const& loc = BOOST_CURRENT_LOCATION) &;
+ 482 + +
+ 483 + + inline
+ 484 + + value&&
+ 485 + + at(
+ 486 + + std::size_t pos,
+ 487 + + source_location const& loc = BOOST_CURRENT_LOCATION) &&;
+ 488 + +
+ 489 + + BOOST_JSON_DECL
+ 490 + + value const&
+ 491 + + at(
+ 492 + + std::size_t pos,
+ 493 + + source_location const& loc = BOOST_CURRENT_LOCATION) const&;
+ 494 + + /// @}
+ 495 + +
+ 496 + + /** Access an element.
+ 497 + +
+ 498 + + Returns a reference to the element specified at
+ 499 + + location `pos`. No bounds checking is performed.
+ 500 + +
+ 501 + + @pre `pos < size()`
+ 502 + +
+ 503 + + @par Complexity
+ 504 + + Constant.
+ 505 + +
+ 506 + + @param pos A zero-based index
+ 507 + +
+ 508 + + @{
+ 509 + + */
+ 510 + + inline
+ 511 + + value&
+ 512 + + operator[](std::size_t pos) & noexcept;
+ 513 + +
+ 514 + + inline
+ 515 + + value&&
+ 516 + + operator[](std::size_t pos) && noexcept;
+ 517 + +
+ 518 + + inline
+ 519 + + value const&
+ 520 + + operator[](std::size_t pos) const& noexcept;
+ 521 + + /// @}
+ 522 + +
+ 523 + + /** Access the first element.
+ 524 + +
+ 525 + + Returns a reference to the first element.
+ 526 + +
+ 527 + + @pre `! empty()`
+ 528 + +
+ 529 + + @par Complexity
+ 530 + + Constant.
+ 531 + +
+ 532 + + @{
+ 533 + + */
+ 534 + + inline
+ 535 + + value&
+ 536 + + front() & noexcept;
+ 537 + +
+ 538 + + inline
+ 539 + + value&&
+ 540 + + front() && noexcept;
+ 541 + +
+ 542 + + inline
+ 543 + + value const&
+ 544 + + front() const& noexcept;
+ 545 + + /// @}
+ 546 + +
+ 547 + + /** Access the last element.
+ 548 + +
+ 549 + + Returns a reference to the last element.
+ 550 + +
+ 551 + + @pre `!empty()`
+ 552 + +
+ 553 + + @par Complexity
+ 554 + + Constant.
+ 555 + +
+ 556 + + @{
+ 557 + + */
+ 558 + + inline
+ 559 + + value&
+ 560 + + back() & noexcept;
+ 561 + +
+ 562 + + inline
+ 563 + + value&&
+ 564 + + back() && noexcept;
+ 565 + +
+ 566 + + inline
+ 567 + + value const&
+ 568 + + back() const& noexcept;
+ 569 + + /// @}
+ 570 + +
+ 571 + + /** Access the underlying array directly.
+ 572 + +
+ 573 + + Returns a pointer to the underlying array serving as element storage.
+ 574 + + The value returned is such that the range `[data(), data() + size())`
+ 575 + + is always a valid range, even if the container is empty.
+ 576 + +
+ 577 + + @note
+ 578 + + If `size() == 0`, the function may or may not return
+ 579 + + a null pointer.
+ 580 + +
+ 581 + + @par Complexity
+ 582 + + Constant.
+ 583 + +
+ 584 + + @par Exception Safety
+ 585 + + No-throw guarantee.
+ 586 + +
+ 587 + + @{
+ 588 + + */
+ 589 + + inline
+ 590 + + value*
+ 591 + + data() noexcept;
+ 592 + +
+ 593 + + inline
+ 594 + + value const*
+ 595 + + data() const noexcept;
+ 596 + + /// @}
+ 597 + +
+ 598 + + /** Return a pointer to an element if it exists.
+ 599 + +
+ 600 + + This function returns a pointer to the element at index `pos` when the
+ 601 + + index is less then the size of the container. Otherwise it returns
+ 602 + + null.
+ 603 + +
+ 604 + + @par Example
+ 605 + + @code
+ 606 + + if( auto p = arr.if_contains( 1 ) )
+ 607 + + std::cout << *p;
+ 608 + + @endcode
+ 609 + +
+ 610 + + @par Complexity
+ 611 + + Constant.
+ 612 + +
+ 613 + + @par Exception Safety
+ 614 + + No-throw guarantee.
+ 615 + +
+ 616 + + @param pos The index of the element to return.
+ 617 + +
+ 618 + + @{
+ 619 + + */
+ 620 + + inline
+ 621 + + value const*
+ 622 + + if_contains(std::size_t pos) const noexcept;
+ 623 + +
+ 624 + + inline
+ 625 + + value*
+ 626 + + if_contains(std::size_t pos) noexcept;
+ 627 + + /// @}
+ 628 + +
+ 629 + + //------------------------------------------------------
+ 630 + + //
+ 631 + + // Iterators
+ 632 + + //
+ 633 + + //------------------------------------------------------
+ 634 + +
+ 635 + + /** Return an iterator to the first element.
+ 636 + +
+ 637 + + If the container is empty, @ref end() is returned.
+ 638 + +
+ 639 + + @par Complexity
+ 640 + + Constant.
+ 641 + +
+ 642 + + @par Exception Safety
+ 643 + + No-throw guarantee.
+ 644 + +
+ 645 + + @{
+ 646 + + */
+ 647 + + inline
+ 648 + + iterator
+ 649 + + begin() noexcept;
+ 650 + +
+ 651 + + inline
+ 652 + + const_iterator
+ 653 + + begin() const noexcept;
+ 654 + + /// @}
+ 655 + +
+ 656 + + /** Return a const iterator to the first element.
+ 657 + +
+ 658 + + If the container is empty, @ref cend() is returned.
+ 659 + +
+ 660 + + @par Complexity
+ 661 + + Constant.
+ 662 + +
+ 663 + + @par Exception Safety
+ 664 + + No-throw guarantee.
+ 665 + + */
+ 666 + + inline
+ 667 + + const_iterator
+ 668 + + cbegin() const noexcept;
+ 669 + +
+ 670 + + /** Return a const iterator past the last element.
+ 671 + +
+ 672 + + The returned iterator only acts as a sentinel. Dereferencing it results
+ 673 + + in undefined behavior.
+ 674 + +
+ 675 + + @par Complexity
+ 676 + + Constant.
+ 677 + +
+ 678 + + @par Exception Safety
+ 679 + + No-throw guarantee.
+ 680 + +
+ 681 + + @{
+ 682 + + */
+ 683 + + inline
+ 684 + + iterator
+ 685 + + end() noexcept;
+ 686 + +
+ 687 + + inline
+ 688 + + const_iterator
+ 689 + + end() const noexcept;
+ 690 + + /// @}
+ 691 + +
+ 692 + + /** Return a const iterator past the last element.
+ 693 + +
+ 694 + + The returned iterator only acts as a sentinel. Dereferencing it results
+ 695 + + in undefined behavior.
+ 696 + +
+ 697 + + @par Complexity
+ 698 + + Constant.
+ 699 + +
+ 700 + + @par Exception Safety
+ 701 + + No-throw guarantee.
+ 702 + + */
+ 703 + + inline
+ 704 + + const_iterator
+ 705 + + cend() const noexcept;
+ 706 + +
+ 707 + + /** Return a reverse iterator to the first element of the reversed container.
+ 708 + +
+ 709 + + The pointed-to element corresponds to the
+ 710 + + last element of the non-reversed container.
+ 711 + + If the container is empty, @ref rend() is returned.
+ 712 + +
+ 713 + + @par Complexity
+ 714 + + Constant.
+ 715 + +
+ 716 + + @par Exception Safety
+ 717 + + No-throw guarantee.
+ 718 + +
+ 719 + + @{
+ 720 + + */
+ 721 + + inline
+ 722 + + reverse_iterator
+ 723 + + rbegin() noexcept;
+ 724 + +
+ 725 + + inline
+ 726 + + const_reverse_iterator
+ 727 + + rbegin() const noexcept;
+ 728 + + /// @}
+ 729 + +
+ 730 + + /** Return a const reverse iterator to the first element of the reversed container.
+ 731 + +
+ 732 + + The pointed-to element corresponds to the
+ 733 + + last element of the non-reversed container.
+ 734 + + If the container is empty, @ref crend() is returned.
+ 735 + +
+ 736 + + @par Complexity
+ 737 + + Constant.
+ 738 + +
+ 739 + + @par Exception Safety
+ 740 + + No-throw guarantee.
+ 741 + + */
+ 742 + + inline
+ 743 + + const_reverse_iterator
+ 744 + + crbegin() const noexcept;
+ 745 + +
+ 746 + + /** Return a reverse iterator to the element following the last element of the reversed container.
+ 747 + +
+ 748 + + The pointed-to element corresponds to the element
+ 749 + + preceding the first element of the non-reversed container.
+ 750 + + The returned iterator only acts as a sentinel. Dereferencing it results
+ 751 + + in undefined behavior.
+ 752 + +
+ 753 + + @par Complexity
+ 754 + + Constant.
+ 755 + +
+ 756 + + @par Exception Safety
+ 757 + + No-throw guarantee.
+ 758 + +
+ 759 + + @{
+ 760 + + */
+ 761 + + inline
+ 762 + + reverse_iterator
+ 763 + + rend() noexcept;
+ 764 + +
+ 765 + + inline
+ 766 + + const_reverse_iterator
+ 767 + + rend() const noexcept;
+ 768 + + /// @}
+ 769 + +
+ 770 + + /** Return a const reverse iterator to the element following the last element of the reversed container.
+ 771 + +
+ 772 + + The pointed-to element corresponds to the element preceding the first
+ 773 + + element of the non-reversed container. The returned iterator only acts
+ 774 + + as a sentinel. Dereferencing it results in undefined behavior.
+ 775 + +
+ 776 + + @par Complexity
+ 777 + + Constant.
+ 778 + +
+ 779 + + @par Exception Safety
+ 780 + + No-throw guarantee.
+ 781 + + */
+ 782 + + inline
+ 783 + + const_reverse_iterator
+ 784 + + crend() const noexcept;
+ 785 + +
+ 786 + + //------------------------------------------------------
+ 787 + + //
+ 788 + + // Capacity
+ 789 + + //
+ 790 + + //------------------------------------------------------
+ 791 + +
+ 792 + + /** Return the number of elements in the array.
+ 793 + +
+ 794 + + This returns the number of elements in the array.
+ 795 + + The value returned may be different from the number
+ 796 + + returned from @ref capacity.
+ 797 + +
+ 798 + + @par Complexity
+ 799 + + Constant.
+ 800 + +
+ 801 + + @par Exception Safety
+ 802 + + No-throw guarantee.
+ 803 + + */
+ 804 + + inline
+ 805 + + std::size_t
+ 806 + + size() const noexcept;
+ 807 + +
+ 808 + + /** The maximum number of elements an array can hold.
+ 809 + +
+ 810 + + The maximum is an implementation-defined number. This value is
+ 811 + + a theoretical limit; at runtime, the actual maximum size may be less
+ 812 + + due to resource limits.
+ 813 + +
+ 814 + + @par Complexity
+ 815 + + Constant.
+ 816 + +
+ 817 + + @par Exception Safety
+ 818 + + No-throw guarantee.
+ 819 + + */
+ 820 + + static
+ 821 + + inline
+ 822 + + constexpr
+ 823 + + std::size_t
+ 824 + + max_size() noexcept;
+ 825 + +
+ 826 + + /** Return the number of elements that can be held in currently allocated memory.
+ 827 + +
+ 828 + + Returns the number of elements that the container has currently
+ 829 + + allocated space for. This number is never smaller than the value
+ 830 + + returned by @ref size().
+ 831 + +
+ 832 + + @par Complexity
+ 833 + + Constant.
+ 834 + +
+ 835 + + @par Exception Safety
+ 836 + + No-throw guarantee.
+ 837 + + */
+ 838 + + inline
+ 839 + + std::size_t
+ 840 + + capacity() const noexcept;
+ 841 + +
+ 842 + + /** Check if the array has no elements.
+ 843 + +
+ 844 + + Returns `true` if there are no elements in the
+ 845 + + array, i.e. @ref size() returns 0.
+ 846 + +
+ 847 + + @par Complexity
+ 848 + + Constant.
+ 849 + +
+ 850 + + @par Exception Safety
+ 851 + + No-throw guarantee.
+ 852 + + */
+ 853 + + inline
+ 854 + + bool
+ 855 + + empty() const noexcept;
+ 856 + +
+ 857 + + /** Increase the capacity to at least a certain amount.
+ 858 + +
+ 859 + + This increases the @ref capacity() to a value that is greater than or
+ 860 + + equal to `new_capacity`. If `new_capacity > capacity()`, new memory is
+ 861 + + allocated. Otherwise, the call has no effect. The number of elements
+ 862 + + and therefore the @ref size() of the container is not changed.
+ 863 + +
+ 864 + + If new memory is allocated, all iterators including any past-the-end
+ 865 + + iterators, and all references to the elements are invalidated.
+ 866 + + Otherwise, no iterators or references are invalidated.
+ 867 + +
+ 868 + + @par Complexity
+ 869 + + At most, linear in @ref size().
+ 870 + +
+ 871 + + @par Exception Safety
+ 872 + + Strong guarantee.
+ 873 + + Calls to `memory_resource::allocate` may throw.
+ 874 + +
+ 875 + + @param new_capacity The new capacity of the array.
+ 876 + +
+ 877 + + @throw boost::system::system_error `new_capacity >` @ref max_size().
+ 878 + + */
+ 879 + + inline
+ 880 + + void
+ 881 + + reserve(std::size_t new_capacity);
+ 882 + +
+ 883 + + /** Request the removal of unused capacity.
+ 884 + +
+ 885 + + This performs a non-binding request to reduce the
+ 886 + + capacity to the current size. The request may or
+ 887 + + may not be fulfilled. If reallocation occurs, all
+ 888 + + iterators including any past-the-end iterators,
+ 889 + + and all references to the elements are invalidated.
+ 890 + + Otherwise, no iterators or references are
+ 891 + + invalidated.
+ 892 + +
+ 893 + + @par Complexity
+ 894 + + At most, linear in @ref size().
+ 895 + +
+ 896 + + @par Exception Safety
+ 897 + + No-throw guarantee.
+ 898 + + */
+ 899 + + BOOST_JSON_DECL
+ 900 + + void
+ 901 + + shrink_to_fit() noexcept;
+ 902 + +
+ 903 + + //------------------------------------------------------
+ 904 + + //
+ 905 + + // Modifiers
+ 906 + + //
+ 907 + + //------------------------------------------------------
+ 908 + +
+ 909 + + /** Clear the contents.
+ 910 + +
+ 911 + + Erases all elements from the container. After this call, @ref size()
+ 912 + + returns zero but @ref capacity() is unchanged. All references,
+ 913 + + pointers, and iterators are invalidated
+ 914 + +
+ 915 + + @par Complexity
+ 916 + + Linear in @ref size().
+ 917 + +
+ 918 + + @par Exception Safety
+ 919 + + No-throw guarantee.
+ 920 + + */
+ 921 + + BOOST_JSON_DECL
+ 922 + + void
+ 923 + + clear() noexcept;
+ 924 + +
+ 925 + + /** Insert elements before the specified location.
+ 926 + +
+ 927 + + @li **(1)** and **(2)** insert a single new element before
+ 928 + + `pos`. **(1)** copy-constructs and **(2)** move-constructs the new
+ 929 + + element from `jv`.
+ 930 + + @li **(3)** inserts `count` copies of `jv` before `pos`.
+ 931 + + @li **(4)** the elements in the range `[first, last)` are inserted in
+ 932 + + order.
+ 933 + + @li **(5)** the elements of the initializer list `init` are inserted in
+ 934 + + order.
+ 935 + +
+ 936 + + Inserted values will be constructed using the container's
+ 937 + + associated @ref boost::container::pmr::memory_resource.
+ 938 + +
+ 939 + + @note Overload **(2)** is equivalent to **(1)** if
+ 940 + + `*jv.storage() != *this->storage()`.
+ 941 + +
+ 942 + + If the size of the array after insertion would have exceeded
+ 943 + + @ref capacity(), a reallocation occurs first, and all iterators and
+ 944 + + references are invalidated. Otherwise, only the iterators and
+ 945 + + references from the insertion point forward are invalidated. All
+ 946 + + past-the-end iterators are also invalidated.
+ 947 + +
+ 948 + + @pre
+ 949 + + `first` and `last` are not iterators into `*this`.
+ 950 + +
+ 951 + + @par Constraints
+ 952 + + @code
+ 953 + + ! std::is_convertible_v<InputIt, value>
+ 954 + + std::is_constructible_v<value, std::iterator_traits<InputIt>::reference>
+ 955 + + @endcode
+ 956 + +
+ 957 + + @par Complexity
+ 958 + + @li **(1)**, **(2)** linear in `std::distance(pos, end())`.
+ 959 + + @li **(3)** linear in `count + std::distance(pos, end())`.
+ 960 + + @li **(4)** linear in `std::distance(first, last) +
+ 961 + + std::distance(pos, end())`.
+ 962 + + @li **(5)** linear in `init.size() + std::distance(pos, end())`.
+ 963 + +
+ 964 + + @par Exception Safety
+ 965 + + {sp}**(4)** provides strong guarantee if `InputIt` satisfies
+ 966 + + {req_ForwardIterator}, and basic guarantee otherwise. Other overloads
+ 967 + + provide strong guarantee.
+ 968 + + Calls to `memory_resource::allocate` may throw.
+ 969 + +
+ 970 + + @param pos Iterator before which the new elements will
+ 971 + + be inserted. This may be the @ref end() iterator.
+ 972 + +
+ 973 + + @param jv The value to insert. A copy will be made
+ 974 + + using container's associated
+ 975 + + @ref boost::container::pmr::memory_resource.
+ 976 + +
+ 977 + + @return An iterator to the first inserted value, or `pos` if no values
+ 978 + + were inserted.
+ 979 + +
+ 980 + + @{
+ 981 + + */
+ 982 + + BOOST_JSON_DECL
+ 983 + + iterator
+ 984 + + insert(
+ 985 + + const_iterator pos,
+ 986 + + value const& jv);
+ 987 + +
+ 988 + + // Overload
+ 989 + + BOOST_JSON_DECL
+ 990 + + iterator
+ 991 + + insert(
+ 992 + + const_iterator pos,
+ 993 + + value&& jv);
+ 994 + +
+ 995 + +
+ 996 + + /** Overload
+ 997 + + @param count The number of copies to insert.
+ 998 + + @param pos
+ 999 + + @param jv
+ 1000 + + */
+ 1001 + + BOOST_JSON_DECL
+ 1002 + + iterator
+ 1003 + + insert(
+ 1004 + + const_iterator pos,
+ 1005 + + std::size_t count,
+ 1006 + + value const& jv);
+ 1007 + +
+ 1008 + + /** Overload
+ 1009 + +
+ 1010 + + @param first An input iterator pointing to the first element to insert,
+ 1011 + + or pointing to the end of the range.
+ 1012 + + @param last An input iterator pointing to the end of the range.
+ 1013 + + @param pos
+ 1014 + +
+ 1015 + + @tparam InputIt a type satisfying the requirements
+ 1016 + + of {req_InputIterator}.
+ 1017 + + */
+ 1018 + + template<
+ 1019 + + class InputIt
+ 1020 + + #ifndef BOOST_JSON_DOCS
+ 1021 + + ,class = typename std::enable_if<
+ 1022 + + std::is_constructible<value,
+ 1023 + + typename std::iterator_traits<
+ 1024 + + InputIt>::reference>::value>::type
+ 1025 + + #endif
+ 1026 + + >
+ 1027 + + iterator
+ 1028 + + insert(
+ 1029 + + const_iterator pos,
+ 1030 + + InputIt first, InputIt last);
+ 1031 + +
+ 1032 + + /** Overload
+ 1033 + + @param init The initializer list to insert
+ 1034 + + @param pos
+ 1035 + + */
+ 1036 + + BOOST_JSON_DECL
+ 1037 + + iterator
+ 1038 + + insert(
+ 1039 + + const_iterator pos,
+ 1040 + + std::initializer_list<value_ref> init);
+ 1041 + + /// @}
+ 1042 + +
+ 1043 + + /** Insert a constructed element in-place.
+ 1044 + +
+ 1045 + + Inserts a new element into the container directly before
+ 1046 + + `pos`. The element is constructed using placement-new
+ 1047 + + with the parameter `std::forward<Arg>(arg)`.
+ 1048 + + If `capacity() < size() + 1`,
+ 1049 + + a reallocation occurs first, and all iterators and
+ 1050 + + references are invalidated.
+ 1051 + + Otherwise, only the iterators and references from
+ 1052 + + the insertion point forward are invalidated. All
+ 1053 + + past-the-end iterators are also invalidated.
+ 1054 + +
+ 1055 + + @par Complexity
+ 1056 + + Linear in `std::distance(pos, end())`.
+ 1057 + +
+ 1058 + + @par Exception Safety
+ 1059 + + Strong guarantee.
+ 1060 + + Calls to `memory_resource::allocate` may throw.
+ 1061 + +
+ 1062 + + @param pos Iterator before which the element will
+ 1063 + + be inserted. This may be the @ref end() iterator.
+ 1064 + +
+ 1065 + + @param arg The argument to forward to the @ref value
+ 1066 + + constructor.
+ 1067 + +
+ 1068 + + @return An iterator to the inserted element
+ 1069 + + */
+ 1070 + + template<class Arg>
+ 1071 + + iterator
+ 1072 + + emplace(
+ 1073 + + const_iterator pos,
+ 1074 + + Arg&& arg);
+ 1075 + +
+ 1076 + + /** Remove elements from the array.
+ 1077 + +
+ 1078 + + @li **(1)** the element at `pos` is removed.
+ 1079 + + @li **(2)** the elements in the range `[first, last)` are removed.
+ 1080 + +
+ 1081 + + @par Complexity
+ 1082 + + @li **(1)** linear in `std::distance(pos, end())`.
+ 1083 + + @li **(2)** linear in `std::distance(first, end())`.
+ 1084 + +
+ 1085 + + @par Exception Safety
+ 1086 + + No-throw guarantee.
+ 1087 + +
+ 1088 + + @param pos Iterator to the element to remove
+ 1089 + +
+ 1090 + + @return Iterator following the last removed element. If that was the
+ 1091 + + last element of the array, the @ref end() iterator is returned.
+ 1092 + +
+ 1093 + + @{
+ 1094 + + */
+ 1095 + + BOOST_JSON_DECL
+ 1096 + + iterator
+ 1097 + + erase(const_iterator pos) noexcept;
+ 1098 + +
+ 1099 + + /** Overload
+ 1100 + + @param first An iterator pointing to the first element to erase, or
+ 1101 + + pointing to the end of the range.
+ 1102 + + @param last An iterator pointing to one past the last element to erase,
+ 1103 + + or pointing to the end of the range.
+ 1104 + + */
+ 1105 + + BOOST_JSON_DECL
+ 1106 + + iterator
+ 1107 + + erase(
+ 1108 + + const_iterator first,
+ 1109 + + const_iterator last) noexcept;
+ 1110 + + /// @}
+ 1111 + +
+ 1112 + + /** Add an element to the end.
+ 1113 + +
+ 1114 + + Insert a new element at the end of the container. **(1)**
+ 1115 + + copy-constructs the new element from `jv`, **(2)** move-constructs from
+ 1116 + + `jv`.
+ 1117 + +
+ 1118 + + If `capacity() < size() + 1`, a reallocation occurs first, and all
+ 1119 + + iterators and references are invalidated. Any past-the-end iterators
+ 1120 + + are always invalidated.
+ 1121 + +
+ 1122 + + The new element will be constructed using the container's associated
+ 1123 + + @ref boost::container::pmr::memory_resource.
+ 1124 + +
+ 1125 + + @par Complexity
+ 1126 + + Amortized constant.
+ 1127 + +
+ 1128 + + @par Exception Safety
+ 1129 + + Strong guarantee.
+ 1130 + + Calls to `memory_resource::allocate` may throw.
+ 1131 + +
+ 1132 + + @param jv The value to insert.
+ 1133 + +
+ 1134 + + @{
+ 1135 + + */
+ 1136 + + BOOST_JSON_DECL
+ 1137 + + void
+ 1138 + + push_back(value const& jv);
+ 1139 + +
+ 1140 + + BOOST_JSON_DECL
+ 1141 + + void
+ 1142 + + push_back(value&& jv);
+ 1143 + + /// @}
+ 1144 + +
+ 1145 + + /** Append a constructed element in-place.
+ 1146 + +
+ 1147 + + Appends a new element to the end of the container's
+ 1148 + + list of elements.
+ 1149 + + The element is constructed using placement-new
+ 1150 + + with the parameter `std::forward<Arg>(arg)`.
+ 1151 + + If `capacity() < size() + 1`,
+ 1152 + + a reallocation occurs first, and all iterators and
+ 1153 + + references are invalidated.
+ 1154 + + Otherwise, only the iterators and references from
+ 1155 + + the insertion point forward are invalidated. All
+ 1156 + + past-the-end iterators are also invalidated.
+ 1157 + +
+ 1158 + + @par Complexity
+ 1159 + + Amortized constant.
+ 1160 + +
+ 1161 + + @par Exception Safety
+ 1162 + + Strong guarantee.
+ 1163 + + Calls to `memory_resource::allocate` may throw.
+ 1164 + +
+ 1165 + + @param arg The argument to forward to the @ref value
+ 1166 + + constructor.
+ 1167 + +
+ 1168 + + @return A reference to the inserted element
+ 1169 + + */
+ 1170 + + template<class Arg>
+ 1171 + + value&
+ 1172 + + emplace_back(Arg&& arg);
+ 1173 + +
+ 1174 + + /** Remove the last element
+ 1175 + +
+ 1176 + + The last element of the container is erased.
+ 1177 + +
+ 1178 + + @pre
+ 1179 + + `! empty()`
+ 1180 + +
+ 1181 + + @par Exception Safety
+ 1182 + + No-throw guarantee.
+ 1183 + + */
+ 1184 + + BOOST_JSON_DECL
+ 1185 + + void
+ 1186 + + pop_back() noexcept;
+ 1187 + +
+ 1188 + + /** Change the number of elements stored.
+ 1189 + +
+ 1190 + + Resizes the container to contain `count` elements.
+ 1191 + +
+ 1192 + + @li If `size() > count`, the container is reduced to its first `count`
+ 1193 + + elements.
+ 1194 + + @li If `size() < count`, additional null values (**(1)**) or copies
+ 1195 + + of `jv` (**(2)**) are appended.
+ 1196 + +
+ 1197 + + If `capacity() < count`, a reallocation occurs first, and all iterators
+ 1198 + + and references are invalidated. Any past-the-end iterators are always
+ 1199 + + invalidated.
+ 1200 + +
+ 1201 + + @par Complexity
+ 1202 + + Linear in `size() + count`.
+ 1203 + +
+ 1204 + + @par Exception Safety
+ 1205 + + Strong guarantee.
+ 1206 + + Calls to `memory_resource::allocate` may throw.
+ 1207 + +
+ 1208 + + @param count The new size of the container.
+ 1209 + +
+ 1210 + + @{
+ 1211 + + */
+ 1212 + + BOOST_JSON_DECL
+ 1213 + + void
+ 1214 + + resize(std::size_t count);
+ 1215 + +
+ 1216 + + /** Overload
+ 1217 + + @param jv The @ref value to copy into the new elements.
+ 1218 + + @param count
+ 1219 + + */
+ 1220 + + BOOST_JSON_DECL
+ 1221 + + void
+ 1222 + + resize(
+ 1223 + + std::size_t count,
+ 1224 + + value const& jv);
+ 1225 + + /// @}
+ 1226 + +
+ 1227 + + /** Swap two arrays.
+ 1228 + +
+ 1229 + + Exchanges the contents of this array with another array. Ownership of
+ 1230 + + the respective @ref boost::container::pmr::memory_resource objects is
+ 1231 + + not transferred. If `this == &other`, this function call has no effect.
+ 1232 + +
+ 1233 + + @li If `*storage() == *other.storage()` all iterators and references
+ 1234 + + remain valid.
+ 1235 + +
+ 1236 + + @li Otherwise, the contents are logically swapped by making copies,
+ 1237 + + which can throw. In this case all iterators and references are
+ 1238 + + invalidated.
+ 1239 + +
+ 1240 + + @par Complexity
+ 1241 + + If `*storage() == *other.storage()`, then constant; otherwise linear in
+ 1242 + + `size() + other.size()`.
+ 1243 + +
+ 1244 + + @par Exception Safety
+ 1245 + + No-throw guarantee if `*storage() == *other.storage()`. Otherwise
+ 1246 + + strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 1247 + +
+ 1248 + + @param other The value to swap with.
+ 1249 + + */
+ 1250 + + BOOST_JSON_DECL
+ 1251 + + void
+ 1252 + + swap(array& other);
+ 1253 + +
+ 1254 + + /** Swap two arrays.
+ 1255 + +
+ 1256 + + Exchanges the contents of the array `lhs` with another array `rhs`.
+ 1257 + + Ownership of the respective @ref boost::container::pmr::memory_resource
+ 1258 + + objects is not transferred. If `&lhs == &rhs`, this function call has
+ 1259 + + no effect.
+ 1260 + +
+ 1261 + + @li If `*lhs.storage() == *rhs.storage()` all iterators and references
+ 1262 + + remain valid.
+ 1263 + +
+ 1264 + + @li Otherwise, the contents are logically swapped by making copies,
+ 1265 + + which can throw. In this case all iterators and references are
+ 1266 + + invalidated.
+ 1267 + +
+ 1268 + + @par Complexity
+ 1269 + + If `*lhs.storage() == *rhs.storage()`, then constant; otherwise linear
+ 1270 + + in `lhs.size() + rhs.size()`.
+ 1271 + +
+ 1272 + + @par Exception Safety
+ 1273 + + No-throw guarantee if `*lhs.storage() == *rhs.storage()`. Otherwise
+ 1274 + + strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 1275 + +
+ 1276 + + @param lhs The array to exchange.
+ 1277 + +
+ 1278 + + @param rhs The array to exchange.
+ 1279 + + If `&lhs == &rhs`, this function call has no effect.
+ 1280 + +
+ 1281 + + @see @ref array::swap
+ 1282 + + */
+ 1283 + + friend
+ 1284 + + void
+ 1285 + +1 swap(array& lhs, array& rhs)
+ 1286 + + {
+ 1287 + +1 lhs.swap(rhs);
+ 1288 + +1 }
+ 1289 + +
+ 1290 + + /** Compare two arrays for equality.
+ 1291 + +
+ 1292 + + Arrays are equal when their sizes are the same, and they are
+ 1293 + + element-for-element equal in order.
+ 1294 + +
+ 1295 + + @par Complexity
+ 1296 + + Linear in `lhs.size()`.
+ 1297 + +
+ 1298 + + @par Exception Safety
+ 1299 + + No-throw guarantee.
+ 1300 + + */
+ 1301 + + // inline friend speeds up overload resolution
+ 1302 + + friend
+ 1303 + + bool
+ 1304 + +76 operator==(
+ 1305 + + array const& lhs,
+ 1306 + + array const& rhs) noexcept
+ 1307 + + {
+ 1308 + +76 return lhs.equal(rhs);
+ 1309 + + }
+ 1310 + +
+ 1311 + + /** Compare two arrays for inequality.
+ 1312 + +
+ 1313 + + Arrays are equal when their sizes are the same, and they are
+ 1314 + + element-for-element equal in order.
+ 1315 + +
+ 1316 + + @par Complexity
+ 1317 + + Linear in `lhs.size()`.
+ 1318 + +
+ 1319 + + @par Exception Safety
+ 1320 + + No-throw guarantee.
+ 1321 + + */
+ 1322 + + // inline friend speeds up overload resolution
+ 1323 + + friend
+ 1324 + + bool
+ 1325 + +9 operator!=(
+ 1326 + + array const& lhs,
+ 1327 + + array const& rhs) noexcept
+ 1328 + + {
+ 1329 + +9 return ! (lhs == rhs);
+ 1330 + + }
+ 1331 + +
+ 1332 + + /** Serialize to an output stream.
+ 1333 + +
+ 1334 + + This function serializes an `array` as JSON into the output stream.
+ 1335 + +
+ 1336 + + @return Reference to `os`.
+ 1337 + +
+ 1338 + + @par Complexity
+ 1339 + + Constant or linear in the size of `arr`.
+ 1340 + +
+ 1341 + + @par Exception Safety
+ 1342 + + Strong guarantee.
+ 1343 + + Calls to `memory_resource::allocate` may throw.
+ 1344 + +
+ 1345 + + @param os The output stream to serialize to.
+ 1346 + +
+ 1347 + + @param arr The value to serialize.
+ 1348 + + */
+ 1349 + + BOOST_JSON_DECL
+ 1350 + + friend
+ 1351 + + std::ostream&
+ 1352 + + operator<<(
+ 1353 + + std::ostream& os,
+ 1354 + + array const& arr);
+ 1355 + +
+ 1356 + + private:
+ 1357 + + template<class It>
+ 1358 + + using iter_cat = typename
+ 1359 + + std::iterator_traits<It>::iterator_category;
+ 1360 + +
+ 1361 + + template<class InputIt>
+ 1362 + + array(
+ 1363 + + InputIt first, InputIt last,
+ 1364 + + storage_ptr sp,
+ 1365 + + std::input_iterator_tag);
+ 1366 + +
+ 1367 + + template<class InputIt>
+ 1368 + + array(
+ 1369 + + InputIt first, InputIt last,
+ 1370 + + storage_ptr sp,
+ 1371 + + std::forward_iterator_tag);
+ 1372 + +
+ 1373 + + inline
+ 1374 + + std::size_t
+ 1375 + + growth(std::size_t new_size) const;
+ 1376 + +
+ 1377 + + BOOST_JSON_DECL
+ 1378 + + void
+ 1379 + + reserve_impl(
+ 1380 + + std::size_t new_capacity);
+ 1381 + +
+ 1382 + + BOOST_JSON_DECL
+ 1383 + + value&
+ 1384 + + push_back(
+ 1385 + + pilfered<value> pv);
+ 1386 + +
+ 1387 + + BOOST_JSON_DECL
+ 1388 + + iterator
+ 1389 + + insert(
+ 1390 + + const_iterator pos,
+ 1391 + + pilfered<value> pv);
+ 1392 + +
+ 1393 + + template<class InputIt>
+ 1394 + + iterator
+ 1395 + + insert(
+ 1396 + + const_iterator pos,
+ 1397 + + InputIt first, InputIt last,
+ 1398 + + std::input_iterator_tag);
+ 1399 + +
+ 1400 + + template<class InputIt>
+ 1401 + + iterator
+ 1402 + + insert(
+ 1403 + + const_iterator pos,
+ 1404 + + InputIt first, InputIt last,
+ 1405 + + std::forward_iterator_tag);
+ 1406 + +
+ 1407 + + BOOST_JSON_DECL
+ 1408 + + bool
+ 1409 + + equal(array const& other) const noexcept;
+ 1410 + + };
+ 1411 + +
+ 1412 + + } // namespace json
+ 1413 + + } // namespace boost
+ 1414 + +
+ 1415 + + // std::hash specialization
+ 1416 + + #ifndef BOOST_JSON_DOCS
+ 1417 + + namespace std {
+ 1418 + + template <>
+ 1419 + + struct hash< ::boost::json::array > {
+ 1420 + + BOOST_JSON_DECL
+ 1421 + + std::size_t
+ 1422 + + operator()(::boost::json::array const& ja) const noexcept;
+ 1423 + + };
+ 1424 + + } // std
+ 1425 + + #endif
+ 1426 + +
+ 1427 + + // Must be included here for this file to stand alone
+ 1428 + + #include <boost/json/value.hpp>
+ 1429 + +
+ 1430 + + // includes are at the bottom of <boost/json/value.hpp>
+ 1431 + +
+ 1432 + + #endif
+ 1433 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.array.hpp.ffb272ea2be09d8caf7e569420bf69e3.html b/json/gcovr/index.array.hpp.ffb272ea2be09d8caf7e569420bf69e3.html new file mode 100644 index 00000000..e8cd067f --- /dev/null +++ b/json/gcovr/index.array.hpp.ffb272ea2be09d8caf7e569420bf69e3.html @@ -0,0 +1,2454 @@ + + + + + + detail/impl/array.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/impl/array.hpp

+
+ + 100.0% Lines (15/15) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/impl/array.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_IMPL_ARRAY_HPP
+ 11 + + #define BOOST_JSON_DETAIL_IMPL_ARRAY_HPP
+ 12 + +
+ 13 + + namespace boost {
+ 14 + + namespace json {
+ 15 + + namespace detail {
+ 16 + +
+ 17 + +2120 unchecked_array::
+ 18 + +854 ~unchecked_array()
+ 19 + + {
+ 20 + +2977 if(! data_ ||
+ 21 + +857 sp_.is_not_shared_and_deallocate_is_trivial())
+ 22 + +1266 return;
+ 23 + +919 for(unsigned long i = 0;
+ 24 + +919 i < size_; ++i)
+ 25 + +65 data_[i].~value();
+ 26 + +2120 }
+ 27 + +
+ 28 + + void
+ 29 + +1263 unchecked_array::
+ 30 + + relocate(value* dest) noexcept
+ 31 + + {
+ 32 + +1263 if(size_ > 0)
+ 33 + +1263 std::memcpy(
+ 34 + + static_cast<void*>(dest),
+ 35 + +1263 data_, size_ * sizeof(value));
+ 36 + +1263 data_ = nullptr;
+ 37 + +1263 }
+ 38 + +
+ 39 + + } // detail
+ 40 + + } // namespace json
+ 41 + + } // namespace boost
+ 42 + +
+ 43 + + #endif
+ 44 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.array.ipp.12b73a50f89b12e61f6c515c936b6c51.html b/json/gcovr/index.array.ipp.12b73a50f89b12e61f6c515c936b6c51.html new file mode 100644 index 00000000..f64b2f91 --- /dev/null +++ b/json/gcovr/index.array.ipp.12b73a50f89b12e61f6c515c936b6c51.html @@ -0,0 +1,8614 @@ + + + + + + impl/array.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/array.ipp

+
+ + 100.0% Lines (389/389) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/array.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_ARRAY_IPP
+ 11 + + #define BOOST_JSON_IMPL_ARRAY_IPP
+ 12 + +
+ 13 + + #include <boost/core/detail/static_assert.hpp>
+ 14 + + #include <boost/container_hash/hash.hpp>
+ 15 + + #include <boost/json/array.hpp>
+ 16 + + #include <boost/json/pilfer.hpp>
+ 17 + + #include <boost/json/detail/except.hpp>
+ 18 + + #include <cstdlib>
+ 19 + + #include <limits>
+ 20 + + #include <new>
+ 21 + + #include <utility>
+ 22 + +
+ 23 + + namespace boost {
+ 24 + + namespace json {
+ 25 + +
+ 26 + + //----------------------------------------------------------
+ 27 + +
+ 28 + + constexpr array::table::table() = default;
+ 29 + +
+ 30 + + // empty arrays point here
+ 31 + + BOOST_JSON_REQUIRE_CONST_INIT
+ 32 + + array::table array::empty_;
+ 33 + +
+ 34 + + auto
+ 35 + +2540 array::
+ 36 + + table::
+ 37 + + allocate(
+ 38 + + std::size_t capacity,
+ 39 + + storage_ptr const& sp) ->
+ 40 + + table*
+ 41 + + {
+ 42 + +2540 BOOST_ASSERT(capacity > 0);
+ 43 + +2540 if(capacity > array::max_size())
+ 44 + + {
+ 45 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 46 + +2 detail::throw_system_error( error::array_too_large, &loc );
+ 47 + + }
+ 48 + + auto p = reinterpret_cast<
+ 49 + +2538 table*>(sp->allocate(
+ 50 + + sizeof(table) +
+ 51 + +2538 capacity * sizeof(value),
+ 52 + + alignof(value)));
+ 53 + +2399 p->capacity = static_cast<
+ 54 + + std::uint32_t>(capacity);
+ 55 + +2399 return p;
+ 56 + + }
+ 57 + +
+ 58 + + void
+ 59 + +4415 array::
+ 60 + + table::
+ 61 + + deallocate(
+ 62 + + table* p,
+ 63 + + storage_ptr const& sp)
+ 64 + + {
+ 65 + +4415 if(p->capacity == 0)
+ 66 + +2020 return;
+ 67 + +2395 sp->deallocate(p,
+ 68 + + sizeof(table) +
+ 69 + +2395 p->capacity * sizeof(value),
+ 70 + + alignof(value));
+ 71 + + }
+ 72 + +
+ 73 + + //----------------------------------------------------------
+ 74 + +
+ 75 + +37 array::
+ 76 + + revert_insert::
+ 77 + + revert_insert(
+ 78 + + const_iterator pos,
+ 79 + + std::size_t n,
+ 80 + +37 array& arr)
+ 81 + +37 : arr_(&arr)
+ 82 + +37 , i_(pos - arr_->data())
+ 83 + +37 , n_(n)
+ 84 + + {
+ 85 + +37 BOOST_ASSERT(
+ 86 + + pos >= arr_->begin() &&
+ 87 + + pos <= arr_->end());
+ 88 + +74 if( n_ <= arr_->capacity() -
+ 89 + +37 arr_->size())
+ 90 + + {
+ 91 + + // fast path
+ 92 + +2 p = arr_->data() + i_;
+ 93 + +2 if(n_ == 0)
+ 94 + +1 return;
+ 95 + +1 relocate(
+ 96 + +1 p + n_,
+ 97 + + p,
+ 98 + +1 arr_->size() - i_);
+ 99 + +1 arr_->t_->size = static_cast<
+ 100 + + std::uint32_t>(
+ 101 + +1 arr_->t_->size + n_);
+ 102 + +1 return;
+ 103 + + }
+ 104 + +35 if(n_ > max_size() - arr_->size())
+ 105 + + {
+ 106 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 107 + +1 detail::throw_system_error( error::array_too_large, &loc );
+ 108 + + }
+ 109 + +34 auto t = table::allocate(
+ 110 + +34 arr_->growth(arr_->size() + n_),
+ 111 + +34 arr_->sp_);
+ 112 + +24 t->size = static_cast<std::uint32_t>(
+ 113 + +24 arr_->size() + n_);
+ 114 + +24 p = &(*t)[0] + i_;
+ 115 + +24 relocate(
+ 116 + +24 &(*t)[0],
+ 117 + +24 arr_->data(),
+ 118 + +24 i_);
+ 119 + +24 relocate(
+ 120 + +24 &(*t)[i_ + n_],
+ 121 + +24 arr_->data() + i_,
+ 122 + +24 arr_->size() - i_);
+ 123 + +24 t = detail::exchange(arr_->t_, t);
+ 124 + +24 table::deallocate(t, arr_->sp_);
+ 125 + + }
+ 126 + +
+ 127 + +26 array::
+ 128 + + revert_insert::
+ 129 + +8 ~revert_insert()
+ 130 + + {
+ 131 + +26 if(! arr_)
+ 132 + +18 return;
+ 133 + +8 BOOST_ASSERT(n_ != 0);
+ 134 + + auto const pos =
+ 135 + +8 arr_->data() + i_;
+ 136 + +8 arr_->destroy(pos, p);
+ 137 + +8 arr_->t_->size = static_cast<
+ 138 + + std::uint32_t>(
+ 139 + +8 arr_->t_->size - n_);
+ 140 + +8 relocate(
+ 141 + + pos,
+ 142 + +8 pos + n_,
+ 143 + +8 arr_->size() - i_);
+ 144 + +26 }
+ 145 + +
+ 146 + + //----------------------------------------------------------
+ 147 + +
+ 148 + + void
+ 149 + +25 array::
+ 150 + + destroy(
+ 151 + + value* first, value* last) noexcept
+ 152 + + {
+ 153 + +25 if(sp_.is_not_shared_and_deallocate_is_trivial())
+ 154 + +1 return;
+ 155 + +50 while(last-- != first)
+ 156 + +26 last->~value();
+ 157 + + }
+ 158 + +
+ 159 + + void
+ 160 + +3682 array::
+ 161 + + destroy() noexcept
+ 162 + + {
+ 163 + +3682 if(sp_.is_not_shared_and_deallocate_is_trivial())
+ 164 + +5 return;
+ 165 + +3677 auto last = end();
+ 166 + +3677 auto const first = begin();
+ 167 + +20810 while(last-- != first)
+ 168 + +17133 last->~value();
+ 169 + +3677 table::deallocate(t_, sp_);
+ 170 + + }
+ 171 + +
+ 172 + + //----------------------------------------------------------
+ 173 + + //
+ 174 + + // Special Members
+ 175 + + //
+ 176 + + //----------------------------------------------------------
+ 177 + +
+ 178 + +2120 array::
+ 179 + +2120 array(detail::unchecked_array&& ua)
+ 180 + +2120 : sp_(ua.storage())
+ 181 + + {
+ 182 + + BOOST_CORE_STATIC_ASSERT( alignof(table) == alignof(value) );
+ 183 + +2120 if(ua.size() == 0)
+ 184 + + {
+ 185 + +819 t_ = &empty_;
+ 186 + +819 return;
+ 187 + + }
+ 188 + +1301 t_= table::allocate(
+ 189 + +1301 ua.size(), sp_);
+ 190 + +1263 t_->size = static_cast<
+ 191 + +1263 std::uint32_t>(ua.size());
+ 192 + +1263 ua.relocate(data());
+ 193 + +38 }
+ 194 + +
+ 195 + +3618 array::
+ 196 + + ~array() noexcept
+ 197 + + {
+ 198 + +3618 destroy();
+ 199 + +3618 }
+ 200 + +
+ 201 + +35 array::
+ 202 + + array(
+ 203 + + std::size_t count,
+ 204 + + value const& v,
+ 205 + +35 storage_ptr sp)
+ 206 + +35 : sp_(std::move(sp))
+ 207 + + {
+ 208 + +35 if(count == 0)
+ 209 + + {
+ 210 + +1 t_ = &empty_;
+ 211 + +1 return;
+ 212 + + }
+ 213 + +63 t_= table::allocate(
+ 214 + +34 count, sp_);
+ 215 + +29 t_->size = 0;
+ 216 + +29 revert_construct r(*this);
+ 217 + +98 while(count--)
+ 218 + + {
+ 219 + +101 ::new(end()) value(v, sp_);
+ 220 + +69 ++t_->size;
+ 221 + + }
+ 222 + +13 r.commit();
+ 223 + +50 }
+ 224 + +
+ 225 + +16 array::
+ 226 + + array(
+ 227 + + std::size_t count,
+ 228 + +16 storage_ptr sp)
+ 229 + +16 : sp_(std::move(sp))
+ 230 + + {
+ 231 + +16 if(count == 0)
+ 232 + + {
+ 233 + +1 t_ = &empty_;
+ 234 + +1 return;
+ 235 + + }
+ 236 + +26 t_ = table::allocate(
+ 237 + +15 count, sp_);
+ 238 + +11 t_->size = static_cast<
+ 239 + + std::uint32_t>(count);
+ 240 + +11 auto p = data();
+ 241 + + do
+ 242 + + {
+ 243 + +34 ::new(p++) value(sp_);
+ 244 + + }
+ 245 + +34 while(--count);
+ 246 + +4 }
+ 247 + +
+ 248 + +8 array::
+ 249 + +8 array(array const& other)
+ 250 + +8 : array(other, other.sp_)
+ 251 + + {
+ 252 + +8 }
+ 253 + +
+ 254 + +153 array::
+ 255 + + array(
+ 256 + + array const& other,
+ 257 + +153 storage_ptr sp)
+ 258 + +153 : sp_(std::move(sp))
+ 259 + + {
+ 260 + +153 if(other.empty())
+ 261 + + {
+ 262 + +14 t_ = &empty_;
+ 263 + +14 return;
+ 264 + + }
+ 265 + +139 t_ = table::allocate(
+ 266 + +139 other.size(), sp_);
+ 267 + +120 t_->size = 0;
+ 268 + +120 revert_construct r(*this);
+ 269 + +120 auto src = other.data();
+ 270 + +120 auto dest = data();
+ 271 + +120 auto const n = other.size();
+ 272 + + do
+ 273 + + {
+ 274 + +13 ::new(dest++) value(
+ 275 + +2412 *src++, sp_);
+ 276 + +2373 ++t_->size;
+ 277 + + }
+ 278 + +2373 while(t_->size < n);
+ 279 + +107 r.commit();
+ 280 + +152 }
+ 281 + +
+ 282 + +262 array::
+ 283 + + array(
+ 284 + + array&& other,
+ 285 + +262 storage_ptr sp)
+ 286 + +262 : sp_(std::move(sp))
+ 287 + + {
+ 288 + +262 if(*sp_ == *other.sp_)
+ 289 + + {
+ 290 + + // same resource
+ 291 + +478 t_ = detail::exchange(
+ 292 + +239 other.t_, &empty_);
+ 293 + +243 return;
+ 294 + + }
+ 295 + +23 else if(other.empty())
+ 296 + + {
+ 297 + +4 t_ = &empty_;
+ 298 + +4 return;
+ 299 + + }
+ 300 + + // copy
+ 301 + +19 t_ = table::allocate(
+ 302 + +19 other.size(), sp_);
+ 303 + +14 t_->size = 0;
+ 304 + +14 revert_construct r(*this);
+ 305 + +14 auto src = other.data();
+ 306 + +14 auto dest = data();
+ 307 + +14 auto const n = other.size();
+ 308 + + do
+ 309 + + {
+ 310 + +6 ::new(dest++) value(
+ 311 + +48 *src++, sp_);
+ 312 + +30 ++t_->size;
+ 313 + + }
+ 314 + +30 while(t_->size < n);
+ 315 + +8 r.commit();
+ 316 + +25 }
+ 317 + +
+ 318 + +244 array::
+ 319 + + array(
+ 320 + + std::initializer_list<
+ 321 + + value_ref> init,
+ 322 + +244 storage_ptr sp)
+ 323 + +244 : sp_(std::move(sp))
+ 324 + + {
+ 325 + +244 if(init.size() == 0)
+ 326 + + {
+ 327 + +5 t_ = &empty_;
+ 328 + +5 return;
+ 329 + + }
+ 330 + +239 t_ = table::allocate(
+ 331 + +239 init.size(), sp_);
+ 332 + +212 t_->size = 0;
+ 333 + +212 revert_construct r(*this);
+ 334 + +212 value_ref::write_array(
+ 335 + +212 data(), init, sp_);
+ 336 + +197 t_->size = static_cast<
+ 337 + +197 std::uint32_t>(init.size());
+ 338 + +197 r.commit();
+ 339 + +254 }
+ 340 + +
+ 341 + + //----------------------------------------------------------
+ 342 + +
+ 343 + + array&
+ 344 + +16 array::
+ 345 + + operator=(array const& other)
+ 346 + + {
+ 347 + +32 array(other,
+ 348 + +12 storage()).swap(*this);
+ 349 + +12 return *this;
+ 350 + + }
+ 351 + +
+ 352 + + array&
+ 353 + +7 array::
+ 354 + + operator=(array&& other)
+ 355 + + {
+ 356 + +14 array(std::move(other),
+ 357 + +5 storage()).swap(*this);
+ 358 + +5 return *this;
+ 359 + + }
+ 360 + +
+ 361 + + array&
+ 362 + +9 array::
+ 363 + + operator=(
+ 364 + + std::initializer_list<value_ref> init)
+ 365 + + {
+ 366 + +18 array(init,
+ 367 + +5 storage()).swap(*this);
+ 368 + +5 return *this;
+ 369 + + }
+ 370 + +
+ 371 + + //----------------------------------------------------------
+ 372 + + //
+ 373 + + // Element access
+ 374 + + //
+ 375 + + //----------------------------------------------------------
+ 376 + +
+ 377 + + system::result<value&>
+ 378 + +12 array::try_at(std::size_t pos) noexcept
+ 379 + + {
+ 380 + +12 if(pos >= t_->size)
+ 381 + + {
+ 382 + +8 system::error_code ec;
+ 383 + +8 BOOST_JSON_FAIL(ec, error::out_of_range);
+ 384 + +8 return ec;
+ 385 + + }
+ 386 + +4 return (*t_)[pos];
+ 387 + + }
+ 388 + +
+ 389 + + system::result<value const&>
+ 390 + +106 array::try_at(std::size_t pos) const noexcept
+ 391 + + {
+ 392 + +106 if(pos >= t_->size)
+ 393 + + {
+ 394 + +12 system::error_code ec;
+ 395 + +12 BOOST_JSON_FAIL(ec, error::out_of_range);
+ 396 + +12 return ec;
+ 397 + + }
+ 398 + +94 return (*t_)[pos];
+ 399 + + }
+ 400 + +
+ 401 + + value const&
+ 402 + +100 array::
+ 403 + + array::at(std::size_t pos, source_location const& loc) const&
+ 404 + + {
+ 405 + +100 return try_at(pos).value(loc);
+ 406 + + }
+ 407 + +
+ 408 + + //----------------------------------------------------------
+ 409 + + //
+ 410 + + // Capacity
+ 411 + + //
+ 412 + + //----------------------------------------------------------
+ 413 + +
+ 414 + + void
+ 415 + +6 array::
+ 416 + + shrink_to_fit() noexcept
+ 417 + + {
+ 418 + +6 if(capacity() <= size())
+ 419 + +2 return;
+ 420 + +4 if(size() == 0)
+ 421 + + {
+ 422 + +1 table::deallocate(t_, sp_);
+ 423 + +1 t_ = &empty_;
+ 424 + +1 return;
+ 425 + + }
+ 426 + +
+ 427 + + #ifndef BOOST_NO_EXCEPTIONS
+ 428 + + try
+ 429 + + {
+ 430 + + #endif
+ 431 + +3 auto t = table::allocate(
+ 432 + +3 size(), sp_);
+ 433 + +4 relocate(
+ 434 + +2 &(*t)[0],
+ 435 + + data(),
+ 436 + + size());
+ 437 + +2 t->size = static_cast<
+ 438 + +2 std::uint32_t>(size());
+ 439 + +2 t = detail::exchange(
+ 440 + +2 t_, t);
+ 441 + +2 table::deallocate(t, sp_);
+ 442 + + #ifndef BOOST_NO_EXCEPTIONS
+ 443 + + }
+ 444 + +1 catch(...)
+ 445 + + {
+ 446 + + // eat the exception
+ 447 + +1 return;
+ 448 + +1 }
+ 449 + + #endif
+ 450 + + }
+ 451 + +
+ 452 + + //----------------------------------------------------------
+ 453 + + //
+ 454 + + // Modifiers
+ 455 + + //
+ 456 + + //----------------------------------------------------------
+ 457 + +
+ 458 + + void
+ 459 + +4 array::
+ 460 + + clear() noexcept
+ 461 + + {
+ 462 + +4 if(size() == 0)
+ 463 + +1 return;
+ 464 + +3 destroy(
+ 465 + + begin(), end());
+ 466 + +3 t_->size = 0;
+ 467 + + }
+ 468 + +
+ 469 + + auto
+ 470 + +3 array::
+ 471 + + insert(
+ 472 + + const_iterator pos,
+ 473 + + value const& v) ->
+ 474 + + iterator
+ 475 + + {
+ 476 + +3 return emplace(pos, v);
+ 477 + + }
+ 478 + +
+ 479 + + auto
+ 480 + +3 array::
+ 481 + + insert(
+ 482 + + const_iterator pos,
+ 483 + + value&& v) ->
+ 484 + + iterator
+ 485 + + {
+ 486 + +3 return emplace(pos, std::move(v));
+ 487 + + }
+ 488 + +
+ 489 + + auto
+ 490 + +10 array::
+ 491 + + insert(
+ 492 + + const_iterator pos,
+ 493 + + std::size_t count,
+ 494 + + value const& v) ->
+ 495 + + iterator
+ 496 + + {
+ 497 + + revert_insert r(
+ 498 + +10 pos, count, *this);
+ 499 + +17 while(count--)
+ 500 + + {
+ 501 + +16 ::new(r.p) value(v, sp_);
+ 502 + +10 ++r.p;
+ 503 + + }
+ 504 + +8 return r.commit();
+ 505 + +7 }
+ 506 + +
+ 507 + + auto
+ 508 + +3 array::
+ 509 + + insert(
+ 510 + + const_iterator pos,
+ 511 + + std::initializer_list<
+ 512 + + value_ref> init) ->
+ 513 + + iterator
+ 514 + + {
+ 515 + + revert_insert r(
+ 516 + +3 pos, init.size(), *this);
+ 517 + +2 value_ref::write_array(
+ 518 + +2 r.p, init, sp_);
+ 519 + +2 return r.commit();
+ 520 + +2 }
+ 521 + +
+ 522 + + auto
+ 523 + +7 array::
+ 524 + + erase(
+ 525 + + const_iterator pos) noexcept ->
+ 526 + + iterator
+ 527 + + {
+ 528 + +7 BOOST_ASSERT(
+ 529 + + pos >= begin() &&
+ 530 + + pos <= end());
+ 531 + +7 return erase(pos, pos + 1);
+ 532 + + }
+ 533 + +
+ 534 + + auto
+ 535 + +8 array::
+ 536 + + erase(
+ 537 + + const_iterator first,
+ 538 + + const_iterator last) noexcept ->
+ 539 + + iterator
+ 540 + + {
+ 541 + +8 BOOST_ASSERT(
+ 542 + + first >= begin() &&
+ 543 + + last >= first &&
+ 544 + + last <= end());
+ 545 + +8 std::size_t const n =
+ 546 + +8 last - first;
+ 547 + +8 auto const p = &(*t_)[0] +
+ 548 + +8 (first - &(*t_)[0]);
+ 549 + +8 destroy(p, p + n);
+ 550 + +8 relocate(p, p + n,
+ 551 + +8 t_->size - (last -
+ 552 + +8 &(*t_)[0]));
+ 553 + +8 t_->size = static_cast<
+ 554 + +8 std::uint32_t>(t_->size - n);
+ 555 + +8 return p;
+ 556 + + }
+ 557 + +
+ 558 + + void
+ 559 + +4 array::
+ 560 + + push_back(value const& v)
+ 561 + + {
+ 562 + +4 emplace_back(v);
+ 563 + +2 }
+ 564 + +
+ 565 + + void
+ 566 + +9 array::
+ 567 + + push_back(value&& v)
+ 568 + + {
+ 569 + +9 emplace_back(std::move(v));
+ 570 + +7 }
+ 571 + +
+ 572 + + void
+ 573 + +3 array::
+ 574 + + pop_back() noexcept
+ 575 + + {
+ 576 + +3 auto const p = &back();
+ 577 + +3 destroy(p, p + 1);
+ 578 + +3 --t_->size;
+ 579 + +3 }
+ 580 + +
+ 581 + + void
+ 582 + +15 array::
+ 583 + + resize(std::size_t count)
+ 584 + + {
+ 585 + +15 if(count <= t_->size)
+ 586 + + {
+ 587 + + // shrink
+ 588 + +4 destroy(
+ 589 + +2 &(*t_)[0] + count,
+ 590 + +2 &(*t_)[0] + t_->size);
+ 591 + +2 t_->size = static_cast<
+ 592 + + std::uint32_t>(count);
+ 593 + +2 return;
+ 594 + + }
+ 595 + +
+ 596 + +13 reserve(count);
+ 597 + +12 auto p = &(*t_)[t_->size];
+ 598 + +12 auto const end = &(*t_)[count];
+ 599 + +32 while(p != end)
+ 600 + +20 ::new(p++) value(sp_);
+ 601 + +12 t_->size = static_cast<
+ 602 + + std::uint32_t>(count);
+ 603 + + }
+ 604 + +
+ 605 + + void
+ 606 + +7 array::
+ 607 + + resize(
+ 608 + + std::size_t count,
+ 609 + + value const& v)
+ 610 + + {
+ 611 + +7 if(count <= size())
+ 612 + + {
+ 613 + + // shrink
+ 614 + +2 destroy(
+ 615 + +1 data() + count,
+ 616 + +1 data() + size());
+ 617 + +1 t_->size = static_cast<
+ 618 + + std::uint32_t>(count);
+ 619 + +1 return;
+ 620 + + }
+ 621 + +6 count -= size();
+ 622 + + revert_insert r(
+ 623 + +6 end(), count, *this);
+ 624 + +9 while(count--)
+ 625 + + {
+ 626 + +12 ::new(r.p) value(v, sp_);
+ 627 + +4 ++r.p;
+ 628 + + }
+ 629 + +1 r.commit();
+ 630 + +5 }
+ 631 + +
+ 632 + + void
+ 633 + +28 array::
+ 634 + + swap(array& other)
+ 635 + + {
+ 636 + +28 if(*sp_ == *other.sp_)
+ 637 + + {
+ 638 + +48 t_ = detail::exchange(
+ 639 + +24 other.t_, t_);
+ 640 + +24 return;
+ 641 + + }
+ 642 + + array temp1(
+ 643 + +4 std::move(*this),
+ 644 + +9 other.storage());
+ 645 + + array temp2(
+ 646 + +3 std::move(other),
+ 647 + +7 this->storage());
+ 648 + +2 this->~array();
+ 649 + +6 ::new(this) array(
+ 650 + +2 pilfer(temp2));
+ 651 + +2 other.~array();
+ 652 + +6 ::new(&other) array(
+ 653 + +2 pilfer(temp1));
+ 654 + +3 }
+ 655 + +
+ 656 + + //----------------------------------------------------------
+ 657 + + //
+ 658 + + // Private
+ 659 + + //
+ 660 + + //----------------------------------------------------------
+ 661 + +
+ 662 + + std::size_t
+ 663 + +776 array::
+ 664 + + growth(
+ 665 + + std::size_t new_size) const
+ 666 + + {
+ 667 + +776 if(new_size > max_size())
+ 668 + + {
+ 669 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 670 + +1 detail::throw_system_error( error::array_too_large, &loc );
+ 671 + + }
+ 672 + +775 std::size_t const old = capacity();
+ 673 + +775 if(old > max_size() - old / 2)
+ 674 + +1 return new_size;
+ 675 + +774 std::size_t const g =
+ 676 + +774 old + old / 2; // 1.5x
+ 677 + +774 if(g < new_size)
+ 678 + +694 return new_size;
+ 679 + +80 return g;
+ 680 + + }
+ 681 + +
+ 682 + + // precondition: new_capacity > capacity()
+ 683 + + void
+ 684 + +664 array::
+ 685 + + reserve_impl(
+ 686 + + std::size_t new_capacity)
+ 687 + + {
+ 688 + +664 BOOST_ASSERT(
+ 689 + + new_capacity > t_->capacity);
+ 690 + +663 auto t = table::allocate(
+ 691 + +664 growth(new_capacity), sp_);
+ 692 + +643 relocate(
+ 693 + +643 &(*t)[0],
+ 694 + +643 &(*t_)[0],
+ 695 + +643 t_->size);
+ 696 + +643 t->size = t_->size;
+ 697 + +643 t = detail::exchange(t_, t);
+ 698 + +643 table::deallocate(t, sp_);
+ 699 + +643 }
+ 700 + +
+ 701 + + // precondition: pv is not aliased
+ 702 + + value&
+ 703 + +7572 array::
+ 704 + + push_back(
+ 705 + + pilfered<value> pv)
+ 706 + + {
+ 707 + +7572 auto const n = t_->size;
+ 708 + +7572 if(n < t_->capacity)
+ 709 + + {
+ 710 + + // fast path
+ 711 + + auto& v = *::new(
+ 712 + +7505 &(*t_)[n]) value(pv);
+ 713 + +7505 ++t_->size;
+ 714 + +7505 return v;
+ 715 + + }
+ 716 + + auto const t =
+ 717 + +67 detail::exchange(t_,
+ 718 + + table::allocate(
+ 719 + +67 growth(n + 1),
+ 720 + +67 sp_));
+ 721 + + auto& v = *::new(
+ 722 + +62 &(*t_)[n]) value(pv);
+ 723 + +62 relocate(
+ 724 + +62 &(*t_)[0],
+ 725 + +62 &(*t)[0],
+ 726 + + n);
+ 727 + +62 t_->size = n + 1;
+ 728 + +62 table::deallocate(t, sp_);
+ 729 + +62 return v;
+ 730 + + }
+ 731 + +
+ 732 + + // precondition: pv is not aliased
+ 733 + + auto
+ 734 + +12 array::
+ 735 + + insert(
+ 736 + + const_iterator pos,
+ 737 + + pilfered<value> pv) ->
+ 738 + + iterator
+ 739 + + {
+ 740 + +12 BOOST_ASSERT(
+ 741 + + pos >= begin() &&
+ 742 + + pos <= end());
+ 743 + +12 std::size_t const n =
+ 744 + +12 t_->size;
+ 745 + + std::size_t const i =
+ 746 + +12 pos - &(*t_)[0];
+ 747 + +12 if(n < t_->capacity)
+ 748 + + {
+ 749 + + // fast path
+ 750 + + auto const p =
+ 751 + +1 &(*t_)[i];
+ 752 + +1 relocate(
+ 753 + + p + 1,
+ 754 + + p,
+ 755 + + n - i);
+ 756 + +1 ::new(p) value(pv);
+ 757 + +1 ++t_->size;
+ 758 + +1 return p;
+ 759 + + }
+ 760 + + auto t =
+ 761 + +11 table::allocate(
+ 762 + +11 growth(n + 1), sp_);
+ 763 + +6 auto const p = &(*t)[i];
+ 764 + +6 ::new(p) value(pv);
+ 765 + +6 relocate(
+ 766 + +6 &(*t)[0],
+ 767 + +6 &(*t_)[0],
+ 768 + + i);
+ 769 + +6 relocate(
+ 770 + + p + 1,
+ 771 + +6 &(*t_)[i],
+ 772 + + n - i);
+ 773 + +6 t->size = static_cast<
+ 774 + +6 std::uint32_t>(size() + 1);
+ 775 + +6 t = detail::exchange(t_, t);
+ 776 + +6 table::deallocate(t, sp_);
+ 777 + +6 return p;
+ 778 + + }
+ 779 + +
+ 780 + + //----------------------------------------------------------
+ 781 + +
+ 782 + + bool
+ 783 + +76 array::
+ 784 + + equal(
+ 785 + + array const& other) const noexcept
+ 786 + + {
+ 787 + +76 if(size() != other.size())
+ 788 + +2 return false;
+ 789 + +3236 for(std::size_t i = 0; i < size(); ++i)
+ 790 + +3168 if((*this)[i] != other[i])
+ 791 + +6 return false;
+ 792 + +68 return true;
+ 793 + + }
+ 794 + +
+ 795 + + } // namespace json
+ 796 + + } // namespace boost
+ 797 + +
+ 798 + + //----------------------------------------------------------
+ 799 + + //
+ 800 + + // std::hash specialization
+ 801 + + //
+ 802 + + //----------------------------------------------------------
+ 803 + +
+ 804 + + std::size_t
+ 805 + +12 std::hash<::boost::json::array>::operator()(
+ 806 + + ::boost::json::array const& ja) const noexcept
+ 807 + + {
+ 808 + +12 return ::boost::hash< ::boost::json::array >()( ja );
+ 809 + + }
+ 810 + +
+ 811 + + //----------------------------------------------------------
+ 812 + +
+ 813 + + #endif
+ 814 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.ascii_number.hpp.06e327eb6aa84eac97ab3143afde5536.html b/json/gcovr/index.ascii_number.hpp.06e327eb6aa84eac97ab3143afde5536.html new file mode 100644 index 00000000..779f4246 --- /dev/null +++ b/json/gcovr/index.ascii_number.hpp.06e327eb6aa84eac97ab3143afde5536.html @@ -0,0 +1,4334 @@ + + + + + + detail/charconv/detail/fast_float/ascii_number.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/fast_float/ascii_number.hpp

+
+ + 88.0% Lines (95/108) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/fast_float/ascii_number.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2020-2023 Daniel Lemire
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + + //
+ 6 + + // Derivative of: https://github.com/fastfloat/fast_float
+ 7 + +
+ 8 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_ASCII_NUMBER_HPP
+ 9 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_ASCII_NUMBER_HPP
+ 10 + +
+ 11 + + #include <boost/endian/conversion.hpp>
+ 12 + + #include <boost/json/detail/charconv/detail/fast_float/float_common.hpp>
+ 13 + + #include <cctype>
+ 14 + + #include <cstdint>
+ 15 + + #include <cstring>
+ 16 + + #include <iterator>
+ 17 + +
+ 18 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float {
+ 19 + +
+ 20 + + // Next function can be micro-optimized, but compilers are entirely
+ 21 + + // able to optimize it well.
+ 22 + + template <typename UC>
+ 23 + + BOOST_FORCEINLINE constexpr bool is_integer(UC c) noexcept {
+ 24 + +29053321 return !(c > UC('9') || c < UC('0'));
+ 25 + + }
+ 26 + +
+ 27 + + BOOST_FORCEINLINE constexpr uint64_t byteswap(uint64_t val) {
+ 28 + + return (val & 0xFF00000000000000) >> 56
+ 29 + + | (val & 0x00FF000000000000) >> 40
+ 30 + + | (val & 0x0000FF0000000000) >> 24
+ 31 + + | (val & 0x000000FF00000000) >> 8
+ 32 + + | (val & 0x00000000FF000000) << 8
+ 33 + + | (val & 0x0000000000FF0000) << 24
+ 34 + + | (val & 0x000000000000FF00) << 40
+ 35 + + | (val & 0x00000000000000FF) << 56;
+ 36 + + }
+ 37 + +
+ 38 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 39 + + uint64_t read_u64(const char *chars) {
+ 40 + +4835760 if (cpp20_and_in_constexpr()) {
+ 41 + + uint64_t val = 0;
+ 42 + + for(int i = 0; i < 8; ++i) {
+ 43 + + val |= uint64_t(*chars) << (i*8);
+ 44 + + ++chars;
+ 45 + + }
+ 46 + + return val;
+ 47 + + }
+ 48 + + uint64_t val;
+ 49 + +4835760 ::memcpy(&val, chars, sizeof(uint64_t));
+ 50 + +4835760 endian::little_to_native_inplace(val);
+ 51 + +4835760 return val;
+ 52 + + }
+ 53 + +
+ 54 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 55 + + void write_u64(uint8_t *chars, uint64_t val) {
+ 56 + + if (cpp20_and_in_constexpr()) {
+ 57 + + for(int i = 0; i < 8; ++i) {
+ 58 + + *chars = uint8_t(val);
+ 59 + + val >>= 8;
+ 60 + + ++chars;
+ 61 + + }
+ 62 + + return;
+ 63 + + }
+ 64 + + endian::native_to_little_inplace(val);
+ 65 + + ::memcpy(chars, &val, sizeof(uint64_t));
+ 66 + + }
+ 67 + +
+ 68 + + // credit @aqrit
+ 69 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 70 + + uint32_t parse_eight_digits_unrolled(uint64_t val) {
+ 71 + +2151895 constexpr uint64_t mask = 0x000000FF000000FF;
+ 72 + +2151895 constexpr uint64_t mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
+ 73 + +2151895 constexpr uint64_t mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
+ 74 + +2151895 val -= 0x3030303030303030;
+ 75 + +2151895 val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8;
+ 76 + +2151895 val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32;
+ 77 + +2151895 return uint32_t(val);
+ 78 + + }
+ 79 + +
+ 80 + + BOOST_FORCEINLINE constexpr
+ 81 + + uint32_t parse_eight_digits_unrolled(const char16_t *) noexcept {
+ 82 + + return 0;
+ 83 + + }
+ 84 + +
+ 85 + + BOOST_FORCEINLINE constexpr
+ 86 + + uint32_t parse_eight_digits_unrolled(const char32_t *) noexcept {
+ 87 + + return 0;
+ 88 + + }
+ 89 + +
+ 90 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 91 + + uint32_t parse_eight_digits_unrolled(const char *chars) noexcept {
+ 92 + +4303790 return parse_eight_digits_unrolled(read_u64(chars));
+ 93 + + }
+ 94 + +
+ 95 + + // credit @aqrit
+ 96 + + BOOST_FORCEINLINE constexpr bool is_made_of_eight_digits_fast(uint64_t val) noexcept {
+ 97 + +2683865 return !((((val + 0x4646464646464646) | (val - 0x3030303030303030)) & 0x8080808080808080));
+ 98 + + }
+ 99 + +
+ 100 + + BOOST_FORCEINLINE constexpr
+ 101 + + bool is_made_of_eight_digits_fast(const char16_t *) noexcept {
+ 102 + + return false;
+ 103 + + }
+ 104 + +
+ 105 + + BOOST_FORCEINLINE constexpr
+ 106 + + bool is_made_of_eight_digits_fast(const char32_t *) noexcept {
+ 107 + + return false;
+ 108 + + }
+ 109 + +
+ 110 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 111 + + bool is_made_of_eight_digits_fast(const char *chars) noexcept {
+ 112 + +5367730 return is_made_of_eight_digits_fast(read_u64(chars));
+ 113 + + }
+ 114 + +
+ 115 + + template <typename UC>
+ 116 + + struct parsed_number_string_t {
+ 117 + + int64_t exponent{0};
+ 118 + + uint64_t mantissa{0};
+ 119 + + UC const * lastmatch{nullptr};
+ 120 + + bool negative{false};
+ 121 + + bool valid{false};
+ 122 + + bool too_many_digits{false};
+ 123 + + // contains the range of the significant digits
+ 124 + + span<const UC> integer{}; // non-nullable
+ 125 + + span<const UC> fraction{}; // nullable
+ 126 + + };
+ 127 + + using byte_span = span<char>;
+ 128 + + using parsed_number_string = parsed_number_string_t<char>;
+ 129 + + // Assuming that you use no more than 19 digits, this will
+ 130 + + // parse an ASCII string.
+ 131 + + template <typename UC>
+ 132 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 133 + + parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, parse_options_t<UC> options) noexcept {
+ 134 + +1009310 chars_format const fmt = options.format;
+ 135 + +1009310 UC const decimal_point = options.decimal_point;
+ 136 + +
+ 137 + +1009310 parsed_number_string_t<UC> answer;
+ 138 + +1009310 answer.valid = false;
+ 139 + +1009310 answer.too_many_digits = false;
+ 140 + +1009310 answer.negative = (*p == UC('-'));
+ 141 + +1009310 if (*p == UC('-')) // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
+ 142 + + {
+ 143 + +3902 ++p;
+ 144 + +3902 if (p == pend) {
+ 145 + + return answer;
+ 146 + + }
+ 147 + +7804 if (!is_integer(*p) && (*p != decimal_point)) { // a sign must be followed by an integer or the dot
+ 148 + + return answer;
+ 149 + + }
+ 150 + + }
+ 151 + +1009310 UC const * const start_digits = p;
+ 152 + +
+ 153 + +1009310 uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad)
+ 154 + +
+ 155 + +40852898 while ((p != pend) && is_integer(*p)) {
+ 156 + + // a multiplication by 10 is cheaper than an arbitrary integer
+ 157 + + // multiplication
+ 158 + +19417139 i = 10 * i +
+ 159 + +19417139 uint64_t(*p - UC('0')); // might overflow, we will handle the overflow later
+ 160 + +19417139 ++p;
+ 161 + + }
+ 162 + +1009310 UC const * const end_of_integer_part = p;
+ 163 + +1009310 int64_t digit_count = int64_t(end_of_integer_part - start_digits);
+ 164 + +1009310 answer.integer = span<const UC>(start_digits, size_t(digit_count));
+ 165 + +1009310 int64_t exponent = 0;
+ 166 + +1009310 if ((p != pend) && (*p == decimal_point)) {
+ 167 + +1006820 ++p;
+ 168 + +1006820 UC const * before = p;
+ 169 + + // can occur at most twice without overflowing, but let it occur more, since
+ 170 + + // for integers with many digits, digit parsing is the primary bottleneck.
+ 171 + + if (std::is_same<UC,char>::value) {
+ 172 + +6837468 while ((std::distance(p, pend) >= 8) && is_made_of_eight_digits_fast(p)) {
+ 173 + +2139963 i = i * 100000000 + parse_eight_digits_unrolled(p); // in rare cases, this will overflow, but that's ok
+ 174 + +2139963 p += 8;
+ 175 + + }
+ 176 + + }
+ 177 + +8855670 while ((p != pend) && is_integer(*p)) {
+ 178 + +3423102 uint8_t digit = uint8_t(*p - UC('0'));
+ 179 + +3423102 ++p;
+ 180 + +3423102 i = i * 10 + digit; // in rare cases, this will overflow, but that's ok
+ 181 + + }
+ 182 + +1006820 exponent = before - p;
+ 183 + +1006820 answer.fraction = span<const UC>(before, size_t(p - before));
+ 184 + +1006820 digit_count -= exponent;
+ 185 + + }
+ 186 + + // we must have encountered at least one integer!
+ 187 + +1009310 if (digit_count == 0) {
+ 188 + + return answer;
+ 189 + + }
+ 190 + +1009310 int64_t exp_number = 0; // explicit exponential part
+ 191 + +1009310 if (((unsigned)fmt & (unsigned)chars_format::scientific) && (p != pend) && ((UC('e') == *p) || (UC('E') == *p))) {
+ 192 + +1005136 UC const * location_of_e = p;
+ 193 + +1005136 ++p;
+ 194 + +1005136 bool neg_exp = false;
+ 195 + +1005136 if ((p != pend) && (UC('-') == *p)) {
+ 196 + +499687 neg_exp = true;
+ 197 + +499687 ++p;
+ 198 + +505449 } else if ((p != pend) && (UC('+') == *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
+ 199 + + ++p;
+ 200 + + }
+ 201 + +2010272 if ((p == pend) || !is_integer(*p)) {
+ 202 + + if(!((unsigned)fmt & (unsigned)chars_format::fixed)) {
+ 203 + + // We are in error.
+ 204 + + return answer;
+ 205 + + }
+ 206 + + // Otherwise, we will be ignoring the 'e'.
+ 207 + + p = location_of_e;
+ 208 + + } else {
+ 209 + +7389308 while ((p != pend) && is_integer(*p)) {
+ 210 + +3192086 uint8_t digit = uint8_t(*p - UC('0'));
+ 211 + +3192086 if (exp_number < 0x10000000) {
+ 212 + +3192086 exp_number = 10 * exp_number + digit;
+ 213 + + }
+ 214 + +3192086 ++p;
+ 215 + + }
+ 216 + +1005136 if(neg_exp) { exp_number = - exp_number; }
+ 217 + +1005136 exponent += exp_number;
+ 218 + + }
+ 219 + +1005136 } else {
+ 220 + + // If it scientific and not fixed, we have to bail out.
+ 221 + +4174 if(((unsigned)fmt & (unsigned)chars_format::scientific) && !((unsigned)fmt & (unsigned)chars_format::fixed))
+ 222 + + {
+ 223 + + return answer;
+ 224 + + }
+ 225 + + }
+ 226 + +1009310 answer.lastmatch = p;
+ 227 + +1009310 answer.valid = true;
+ 228 + +
+ 229 + + // If we frequently had to deal with long strings of digits,
+ 230 + + // we could extend our code by using a 128-bit integer instead
+ 231 + + // of a 64-bit integer. However, this is uncommon.
+ 232 + + //
+ 233 + + // We can deal with up to 19 digits.
+ 234 + +1009310 if (digit_count > 19) { // this is uncommon
+ 235 + + // It is possible that the integer had an overflow.
+ 236 + + // We have to handle the case where we have 0.0000somenumber.
+ 237 + + // We need to be mindful of the case where we only have zeroes...
+ 238 + + // E.g., 0.000000000...000.
+ 239 + +1003241 UC const * start = start_digits;
+ 240 + +2111117 while ((start != pend) && (*start == UC('0') || *start == decimal_point)) {
+ 241 + +1107876 if(*start == UC('0')) { digit_count --; }
+ 242 + +1107876 start++;
+ 243 + + }
+ 244 + +1003241 if (digit_count > 19) {
+ 245 + +1000712 answer.too_many_digits = true;
+ 246 + + // Let us start again, this time, avoiding overflows.
+ 247 + + // We don't need to check if is_integer, since we use the
+ 248 + + // pre-tokenized spans from above.
+ 249 + +1000712 i = 0;
+ 250 + +1000712 p = answer.integer.ptr;
+ 251 + +1000712 UC const * int_end = p + answer.integer.len();
+ 252 + +1000712 constexpr uint64_t minimal_nineteen_digit_integer{1000000000000000000};
+ 253 + +19947772 while((i < minimal_nineteen_digit_integer) && (p != int_end)) {
+ 254 + +18947060 i = i * 10 + uint64_t(*p - UC('0'));
+ 255 + +18947060 ++p;
+ 256 + + }
+ 257 + +1000712 if (i >= minimal_nineteen_digit_integer) { // We have a big integers
+ 258 + +946260 exponent = end_of_integer_part - p + exp_number;
+ 259 + + } else { // We have a value with a fractional component.
+ 260 + +54452 p = answer.fraction.ptr;
+ 261 + +54452 UC const * frac_end = p + answer.fraction.len();
+ 262 + +121280 while((i < minimal_nineteen_digit_integer) && (p != frac_end)) {
+ 263 + +66828 i = i * 10 + uint64_t(*p - UC('0'));
+ 264 + +66828 ++p;
+ 265 + + }
+ 266 + +54452 exponent = answer.fraction.ptr - p + exp_number;
+ 267 + + }
+ 268 + + // We have now corrected both exponent and i, to a truncated value
+ 269 + + }
+ 270 + + }
+ 271 + +1009310 answer.exponent = exponent;
+ 272 + +1009310 answer.mantissa = i;
+ 273 + +1009310 return answer;
+ 274 + + }
+ 275 + +
+ 276 + + }}}}}} // namespace s
+ 277 + +
+ 278 + + #endif
+ 279 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.basic_parser.hpp.c9c83104d1acc54b93b6e51f63102df2.html b/json/gcovr/index.basic_parser.hpp.c9c83104d1acc54b93b6e51f63102df2.html new file mode 100644 index 00000000..901ad59d --- /dev/null +++ b/json/gcovr/index.basic_parser.hpp.c9c83104d1acc54b93b6e51f63102df2.html @@ -0,0 +1,7478 @@ + + + + + + basic_parser.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

basic_parser.hpp

+
+ + 100.0% Lines (11/11) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
basic_parser.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_BASIC_PARSER_HPP
+ 12 + + #define BOOST_JSON_BASIC_PARSER_HPP
+ 13 + +
+ 14 + + #include <boost/json/detail/config.hpp>
+ 15 + + #include <boost/json/detail/except.hpp>
+ 16 + + #include <boost/json/error.hpp>
+ 17 + + #include <boost/json/kind.hpp>
+ 18 + + #include <boost/json/parse_options.hpp>
+ 19 + + #include <boost/json/detail/stack.hpp>
+ 20 + + #include <boost/json/detail/stream.hpp>
+ 21 + + #include <boost/json/detail/utf8.hpp>
+ 22 + + #include <boost/json/detail/sbo_buffer.hpp>
+ 23 + +
+ 24 + + namespace boost {
+ 25 + + namespace json {
+ 26 + +
+ 27 + + /** An incremental SAX parser for serialized JSON.
+ 28 + +
+ 29 + + This implements a SAX-style parser, invoking a caller-supplied handler with
+ 30 + + each parsing event. To use, first declare a variable of type
+ 31 + + `basic_parser<T>` where `T` meets the handler requirements specified below.
+ 32 + + Then call @ref write_some one or more times with the input, setting
+ 33 + + `more = false` on the final buffer. The parsing events are realized through
+ 34 + + member function calls on the handler, which exists as a data member of the
+ 35 + + parser.
+ 36 + +
+ 37 + + The parser may dynamically allocate intermediate storage as needed to
+ 38 + + accommodate the nesting level of the input JSON. On subsequent invocations,
+ 39 + + the parser can cheaply re-use this memory, improving performance. This
+ 40 + + storage is freed when the parser is destroyed
+ 41 + +
+ 42 + + @par Usage
+ 43 + + To get the declaration and function definitions for this class it is
+ 44 + + necessary to include this file instead:
+ 45 + + @code
+ 46 + + #include <boost/json/basic_parser_impl.hpp>
+ 47 + + @endcode
+ 48 + +
+ 49 + + Users who wish to parse JSON into the DOM container @ref value will not use
+ 50 + + this class directly; instead they will create an instance of @ref parser or
+ 51 + + @ref stream_parser and use that instead. Alternatively, they may call the
+ 52 + + function @ref parse. This class is designed for users who wish to perform
+ 53 + + custom actions instead of building a @ref value. For example, to produce a
+ 54 + + DOM from an external library.
+ 55 + +
+ 56 + + @note
+ 57 + + By default, only conforming JSON using UTF-8 encoding is accepted. However,
+ 58 + + select non-compliant syntax can be allowed by construction using a
+ 59 + + @ref parse_options set to desired values.
+ 60 + +
+ 61 + + @par Handler
+ 62 + + The handler provided must be implemented as an object of class type which
+ 63 + + defines each of the required event member functions below. The event
+ 64 + + functions return a `bool` where `true` indicates success, and `false`
+ 65 + + indicates failure. If the member function returns `false`, it must set the
+ 66 + + error code to a suitable value. This error code will be returned by the
+ 67 + + write function to the caller.
+ 68 + +
+ 69 + + Handlers are required to declare the maximum limits on various elements. If
+ 70 + + these limits are exceeded during parsing, then parsing fails with an error.
+ 71 + +
+ 72 + + The following declaration meets the parser's handler requirements:
+ 73 + +
+ 74 + + @code
+ 75 + + struct handler
+ 76 + + {
+ 77 + + /// The maximum number of elements allowed in an array
+ 78 + + static constexpr std::size_t max_array_size = -1;
+ 79 + +
+ 80 + + /// The maximum number of elements allowed in an object
+ 81 + + static constexpr std::size_t max_object_size = -1;
+ 82 + +
+ 83 + + /// The maximum number of characters allowed in a string
+ 84 + + static constexpr std::size_t max_string_size = -1;
+ 85 + +
+ 86 + + /// The maximum number of characters allowed in a key
+ 87 + + static constexpr std::size_t max_key_size = -1;
+ 88 + +
+ 89 + + /// Called once when the JSON parsing begins.
+ 90 + + ///
+ 91 + + /// @return `true` on success.
+ 92 + + /// @param ec Set to the error, if any occurred.
+ 93 + + ///
+ 94 + + bool on_document_begin( error_code& ec );
+ 95 + +
+ 96 + + /// Called when the JSON parsing is done.
+ 97 + + ///
+ 98 + + /// @return `true` on success.
+ 99 + + /// @param ec Set to the error, if any occurred.
+ 100 + + ///
+ 101 + + bool on_document_end( error_code& ec );
+ 102 + +
+ 103 + + /// Called when the beginning of an array is encountered.
+ 104 + + ///
+ 105 + + /// @return `true` on success.
+ 106 + + /// @param ec Set to the error, if any occurred.
+ 107 + + ///
+ 108 + + bool on_array_begin( error_code& ec );
+ 109 + +
+ 110 + + /// Called when the end of the current array is encountered.
+ 111 + + ///
+ 112 + + /// @return `true` on success.
+ 113 + + /// @param n The number of elements in the array.
+ 114 + + /// @param ec Set to the error, if any occurred.
+ 115 + + ///
+ 116 + + bool on_array_end( std::size_t n, error_code& ec );
+ 117 + +
+ 118 + + /// Called when the beginning of an object is encountered.
+ 119 + + ///
+ 120 + + /// @return `true` on success.
+ 121 + + /// @param ec Set to the error, if any occurred.
+ 122 + + ///
+ 123 + + bool on_object_begin( error_code& ec );
+ 124 + +
+ 125 + + /// Called when the end of the current object is encountered.
+ 126 + + ///
+ 127 + + /// @return `true` on success.
+ 128 + + /// @param n The number of elements in the object.
+ 129 + + /// @param ec Set to the error, if any occurred.
+ 130 + + ///
+ 131 + + bool on_object_end( std::size_t n, error_code& ec );
+ 132 + +
+ 133 + + /// Called with characters corresponding to part of the current string.
+ 134 + + ///
+ 135 + + /// @return `true` on success.
+ 136 + + /// @param s The partial characters
+ 137 + + /// @param n The total size of the string thus far
+ 138 + + /// @param ec Set to the error, if any occurred.
+ 139 + + ///
+ 140 + + bool on_string_part( string_view s, std::size_t n, error_code& ec );
+ 141 + +
+ 142 + + /// Called with the last characters corresponding to the current string.
+ 143 + + ///
+ 144 + + /// @return `true` on success.
+ 145 + + /// @param s The remaining characters
+ 146 + + /// @param n The total size of the string
+ 147 + + /// @param ec Set to the error, if any occurred.
+ 148 + + ///
+ 149 + + bool on_string( string_view s, std::size_t n, error_code& ec );
+ 150 + +
+ 151 + + /// Called with characters corresponding to part of the current key.
+ 152 + + ///
+ 153 + + /// @return `true` on success.
+ 154 + + /// @param s The partial characters
+ 155 + + /// @param n The total size of the key thus far
+ 156 + + /// @param ec Set to the error, if any occurred.
+ 157 + + ///
+ 158 + + bool on_key_part( string_view s, std::size_t n, error_code& ec );
+ 159 + +
+ 160 + + /// Called with the last characters corresponding to the current key.
+ 161 + + ///
+ 162 + + /// @return `true` on success.
+ 163 + + /// @param s The remaining characters
+ 164 + + /// @param n The total size of the key
+ 165 + + /// @param ec Set to the error, if any occurred.
+ 166 + + ///
+ 167 + + bool on_key( string_view s, std::size_t n, error_code& ec );
+ 168 + +
+ 169 + + /// Called with the characters corresponding to part of the current number.
+ 170 + + ///
+ 171 + + /// @return `true` on success.
+ 172 + + /// @param s The partial characters
+ 173 + + /// @param ec Set to the error, if any occurred.
+ 174 + + ///
+ 175 + + bool on_number_part( string_view s, error_code& ec );
+ 176 + +
+ 177 + + /// Called when a signed integer is parsed.
+ 178 + + ///
+ 179 + + /// @return `true` on success.
+ 180 + + /// @param i The value
+ 181 + + /// @param s The remaining characters
+ 182 + + /// @param ec Set to the error, if any occurred.
+ 183 + + ///
+ 184 + + bool on_int64( int64_t i, string_view s, error_code& ec );
+ 185 + +
+ 186 + + /// Called when an unsigend integer is parsed.
+ 187 + + ///
+ 188 + + /// @return `true` on success.
+ 189 + + /// @param u The value
+ 190 + + /// @param s The remaining characters
+ 191 + + /// @param ec Set to the error, if any occurred.
+ 192 + + ///
+ 193 + + bool on_uint64( uint64_t u, string_view s, error_code& ec );
+ 194 + +
+ 195 + + /// Called when a double is parsed.
+ 196 + + ///
+ 197 + + /// @return `true` on success.
+ 198 + + /// @param d The value
+ 199 + + /// @param s The remaining characters
+ 200 + + /// @param ec Set to the error, if any occurred.
+ 201 + + ///
+ 202 + + bool on_double( double d, string_view s, error_code& ec );
+ 203 + +
+ 204 + + /// Called when a boolean is parsed.
+ 205 + + ///
+ 206 + + /// @return `true` on success.
+ 207 + + /// @param b The value
+ 208 + + /// @param s The remaining characters
+ 209 + + /// @param ec Set to the error, if any occurred.
+ 210 + + ///
+ 211 + + bool on_bool( bool b, error_code& ec );
+ 212 + +
+ 213 + + /// Called when a null is parsed.
+ 214 + + ///
+ 215 + + /// @return `true` on success.
+ 216 + + /// @param ec Set to the error, if any occurred.
+ 217 + + ///
+ 218 + + bool on_null( error_code& ec );
+ 219 + +
+ 220 + + /// Called with characters corresponding to part of the current comment.
+ 221 + + ///
+ 222 + + /// @return `true` on success.
+ 223 + + /// @param s The partial characters.
+ 224 + + /// @param ec Set to the error, if any occurred.
+ 225 + + ///
+ 226 + + bool on_comment_part( string_view s, error_code& ec );
+ 227 + +
+ 228 + + /// Called with the last characters corresponding to the current comment.
+ 229 + + ///
+ 230 + + /// @return `true` on success.
+ 231 + + /// @param s The remaining characters
+ 232 + + /// @param ec Set to the error, if any occurred.
+ 233 + + ///
+ 234 + + bool on_comment( string_view s, error_code& ec );
+ 235 + + };
+ 236 + + @endcode
+ 237 + +
+ 238 + + @see
+ 239 + + @ref parse,
+ 240 + + @ref stream_parser,
+ 241 + + \<\<examples_validate, validating parser example\>\>.
+ 242 + + */
+ 243 + + template<class Handler>
+ 244 + + class basic_parser
+ 245 + + {
+ 246 + + enum class state : char
+ 247 + + {
+ 248 + + doc1, doc3,
+ 249 + + com1, com2, com3, com4,
+ 250 + + lit1,
+ 251 + + str1, str2, str3, str4,
+ 252 + + str5, str6, str7, str8,
+ 253 + + sur1, sur2, sur3,
+ 254 + + sur4, sur5, sur6,
+ 255 + + obj1, obj2, obj3, obj4,
+ 256 + + obj5, obj6, obj7, obj8,
+ 257 + + obj9, obj10, obj11,
+ 258 + + arr1, arr2, arr3,
+ 259 + + arr4, arr5, arr6,
+ 260 + + num1, num2, num3, num4,
+ 261 + + num5, num6, num7, num8,
+ 262 + + exp1, exp2, exp3,
+ 263 + + val1, val2, val3
+ 264 + + };
+ 265 + +
+ 266 + + struct number
+ 267 + + {
+ 268 + + uint64_t mant;
+ 269 + + int bias;
+ 270 + + int exp;
+ 271 + + bool frac;
+ 272 + + bool neg;
+ 273 + + };
+ 274 + +
+ 275 + + template< bool StackEmpty_, char First_ >
+ 276 + + struct parse_number_helper;
+ 277 + +
+ 278 + + // optimization: must come first
+ 279 + + Handler h_;
+ 280 + +
+ 281 + + number num_;
+ 282 + + system::error_code ec_;
+ 283 + + detail::stack st_;
+ 284 + + detail::utf8_sequence seq_;
+ 285 + + unsigned u1_;
+ 286 + + unsigned u2_;
+ 287 + + bool more_; // false for final buffer
+ 288 + + bool done_ = false; // true on complete parse
+ 289 + + bool clean_ = true; // write_some exited cleanly
+ 290 + + const char* end_;
+ 291 + + detail::sbo_buffer<16 + 16 + 1 + 1> num_buf_;
+ 292 + + parse_options opt_;
+ 293 + + // how many levels deeper the parser can go
+ 294 + + std::size_t depth_ = opt_.max_depth;
+ 295 + + unsigned char cur_lit_ = 0;
+ 296 + + unsigned char lit_offset_ = 0;
+ 297 + +
+ 298 + + inline void reserve();
+ 299 + + inline const char* sentinel();
+ 300 + + inline bool incomplete(
+ 301 + + const detail::const_stream_wrapper& cs);
+ 302 + +
+ 303 + + #ifdef __INTEL_COMPILER
+ 304 + + #pragma warning push
+ 305 + + #pragma warning disable 2196
+ 306 + + #endif
+ 307 + +
+ 308 + + BOOST_NOINLINE
+ 309 + + inline
+ 310 + + const char*
+ 311 + + suspend_or_fail(state st);
+ 312 + +
+ 313 + + BOOST_NOINLINE
+ 314 + + inline
+ 315 + + const char*
+ 316 + + suspend_or_fail(
+ 317 + + state st,
+ 318 + + std::size_t n);
+ 319 + +
+ 320 + + BOOST_NOINLINE
+ 321 + + inline
+ 322 + + const char*
+ 323 + + fail(const char* p) noexcept;
+ 324 + +
+ 325 + + BOOST_NOINLINE
+ 326 + + inline
+ 327 + + const char*
+ 328 + + fail(
+ 329 + + const char* p,
+ 330 + + error ev,
+ 331 + + source_location const* loc) noexcept;
+ 332 + +
+ 333 + + BOOST_NOINLINE
+ 334 + + inline
+ 335 + + const char*
+ 336 + + maybe_suspend(
+ 337 + + const char* p,
+ 338 + + state st);
+ 339 + +
+ 340 + + BOOST_NOINLINE
+ 341 + + inline
+ 342 + + const char*
+ 343 + + maybe_suspend(
+ 344 + + const char* p,
+ 345 + + state st,
+ 346 + + std::size_t n);
+ 347 + +
+ 348 + + BOOST_NOINLINE
+ 349 + + inline
+ 350 + + const char*
+ 351 + + maybe_suspend(
+ 352 + + const char* p,
+ 353 + + state st,
+ 354 + + const number& num);
+ 355 + +
+ 356 + + BOOST_NOINLINE
+ 357 + + inline
+ 358 + + const char*
+ 359 + + suspend(
+ 360 + + const char* p,
+ 361 + + state st);
+ 362 + +
+ 363 + + BOOST_NOINLINE
+ 364 + + inline
+ 365 + + const char*
+ 366 + + suspend(
+ 367 + + const char* p,
+ 368 + + state st,
+ 369 + + const number& num);
+ 370 + +
+ 371 + + #ifdef __INTEL_COMPILER
+ 372 + + #pragma warning pop
+ 373 + + #endif
+ 374 + +
+ 375 + + template<bool StackEmpty_/*, bool Terminal_*/>
+ 376 + + const char* parse_comment(const char* p,
+ 377 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 378 + + /*std::integral_constant<bool, Terminal_>*/ bool terminal);
+ 379 + +
+ 380 + + template<bool StackEmpty_>
+ 381 + + const char* parse_document(const char* p,
+ 382 + + std::integral_constant<bool, StackEmpty_> stack_empty);
+ 383 + +
+ 384 + + template<bool StackEmpty_, bool AllowComments_/*,
+ 385 + + bool AllowTrailing_, bool AllowBadUTF8_*/>
+ 386 + + const char* parse_value(const char* p,
+ 387 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 388 + + std::integral_constant<bool, AllowComments_> allow_comments,
+ 389 + + /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
+ 390 + + /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
+ 391 + + bool allow_bad_utf16);
+ 392 + +
+ 393 + + template<bool AllowComments_/*,
+ 394 + + bool AllowTrailing_, bool AllowBadUTF8_*/>
+ 395 + + const char* resume_value(const char* p,
+ 396 + + std::integral_constant<bool, AllowComments_> allow_comments,
+ 397 + + /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
+ 398 + + /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
+ 399 + + bool allow_bad_utf16);
+ 400 + +
+ 401 + + template<bool StackEmpty_, bool AllowComments_/*,
+ 402 + + bool AllowTrailing_, bool AllowBadUTF8_*/>
+ 403 + + const char* parse_object(const char* p,
+ 404 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 405 + + std::integral_constant<bool, AllowComments_> allow_comments,
+ 406 + + /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
+ 407 + + /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
+ 408 + + bool allow_bad_utf16);
+ 409 + +
+ 410 + + template<bool StackEmpty_, bool AllowComments_/*,
+ 411 + + bool AllowTrailing_, bool AllowBadUTF8_*/>
+ 412 + + const char* parse_array(const char* p,
+ 413 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 414 + + std::integral_constant<bool, AllowComments_> allow_comments,
+ 415 + + /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
+ 416 + + /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
+ 417 + + bool allow_bad_utf16);
+ 418 + +
+ 419 + + template<class Literal>
+ 420 + + const char* parse_literal(const char* p, Literal literal);
+ 421 + +
+ 422 + + template<bool StackEmpty_, bool IsKey_>
+ 423 + + const char* parse_string(const char* p,
+ 424 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 425 + + std::integral_constant<bool, IsKey_> is_key,
+ 426 + + bool allow_bad_utf8,
+ 427 + + bool allow_bad_utf16);
+ 428 + +
+ 429 + + template<bool StackEmpty_>
+ 430 + + const char* parse_escaped(
+ 431 + + const char* p,
+ 432 + + std::size_t& total,
+ 433 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 434 + + bool is_key,
+ 435 + + bool allow_bad_utf16);
+ 436 + +
+ 437 + + template<bool StackEmpty_, char First_, number_precision Numbers_>
+ 438 + + const char* parse_number(const char* p,
+ 439 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 440 + + std::integral_constant<char, First_> first,
+ 441 + + std::integral_constant<number_precision, Numbers_> numbers);
+ 442 + +
+ 443 + + // intentionally private
+ 444 + + std::size_t
+ 445 + +173075 depth() const noexcept
+ 446 + + {
+ 447 + +173075 return opt_.max_depth - depth_;
+ 448 + + }
+ 449 + +
+ 450 + + public:
+ 451 + + /** Destructor.
+ 452 + +
+ 453 + + All dynamically allocated internal memory is freed.
+ 454 + +
+ 455 + + @par Effects
+ 456 + + @code
+ 457 + + handler().~Handler()
+ 458 + + @endcode
+ 459 + +
+ 460 + + @par Complexity
+ 461 + + Same as `~Handler()`.
+ 462 + +
+ 463 + + @par Exception Safety
+ 464 + + Same as `~Handler()`.
+ 465 + + */
+ 466 + +2164604 ~basic_parser() = default;
+ 467 + +
+ 468 + + /** Constructors.
+ 469 + +
+ 470 + + Overload **(1)** constructs the parser with the specified options, with
+ 471 + + any additional arguments forwarded to the handler's constructor.
+ 472 + +
+ 473 + + `basic_parser` is not copyable or movable, so the copy constructor is
+ 474 + + deleted.
+ 475 + +
+ 476 + + @par Complexity
+ 477 + + Same as `Handler( std::forward< Args >( args )... )`.
+ 478 + +
+ 479 + + @par Exception Safety
+ 480 + + Same as `Handler( std::forward< Args >( args )... )`.
+ 481 + +
+ 482 + + @param opt Configuration settings for the parser. If this structure is
+ 483 + + default constructed, the parser will accept only standard JSON.
+ 484 + + @param args Optional additional arguments forwarded to the handler's
+ 485 + + constructor.
+ 486 + +
+ 487 + + @{
+ 488 + + */
+ 489 + + template<class... Args>
+ 490 + + explicit
+ 491 + + basic_parser(
+ 492 + + parse_options const& opt,
+ 493 + + Args&&... args);
+ 494 + +
+ 495 + + /// Overload
+ 496 + + basic_parser(
+ 497 + + basic_parser const&) = delete;
+ 498 + + /// @}
+ 499 + +
+ 500 + + /** Assignment.
+ 501 + +
+ 502 + + This type cannot be copied or moved. The copy assignment is deleted.
+ 503 + + */
+ 504 + + basic_parser& operator=(
+ 505 + + basic_parser const&) = delete;
+ 506 + +
+ 507 + + /** Return a reference to the handler.
+ 508 + +
+ 509 + + This function provides access to the constructed
+ 510 + + instance of the handler owned by the parser.
+ 511 + +
+ 512 + + @par Complexity
+ 513 + + Constant.
+ 514 + +
+ 515 + + @par Exception Safety
+ 516 + + No-throw guarantee.
+ 517 + +
+ 518 + + @{
+ 519 + + */
+ 520 + + Handler&
+ 521 + +6310634 handler() noexcept
+ 522 + + {
+ 523 + +6310634 return h_;
+ 524 + + }
+ 525 + +
+ 526 + + Handler const&
+ 527 + +24 handler() const noexcept
+ 528 + + {
+ 529 + +24 return h_;
+ 530 + + }
+ 531 + + /// @}
+ 532 + +
+ 533 + + /** Return the last error.
+ 534 + +
+ 535 + + This returns the last error code which
+ 536 + + was generated in the most recent call
+ 537 + + to @ref write_some.
+ 538 + +
+ 539 + + @par Complexity
+ 540 + + Constant.
+ 541 + +
+ 542 + + @par Exception Safety
+ 543 + + No-throw guarantee.
+ 544 + + */
+ 545 + + system::error_code
+ 546 + +8 last_error() const noexcept
+ 547 + + {
+ 548 + +8 return ec_;
+ 549 + + }
+ 550 + +
+ 551 + + /** Check if a complete JSON text has been parsed.
+ 552 + +
+ 553 + + This function returns `true` when all of these conditions are met:
+ 554 + +
+ 555 + + @li A complete serialized JSON text has been presented to the parser,
+ 556 + + and
+ 557 + + @li No error or exception has occurred since the parser was
+ 558 + + constructed, or since the last call to @ref reset.
+ 559 + +
+ 560 + + @par Complexity
+ 561 + + Constant.
+ 562 + +
+ 563 + + @par Exception Safety
+ 564 + + No-throw guarantee.
+ 565 + + */
+ 566 + + bool
+ 567 + +4078231 done() const noexcept
+ 568 + + {
+ 569 + +4078231 return done_;
+ 570 + + }
+ 571 + +
+ 572 + + /** Reset the state, to parse a new document.
+ 573 + +
+ 574 + + This function discards the current parsing
+ 575 + + state, to prepare for parsing a new document.
+ 576 + + Dynamically allocated temporary memory used
+ 577 + + by the implementation is not deallocated.
+ 578 + +
+ 579 + + @par Complexity
+ 580 + + Constant.
+ 581 + +
+ 582 + + @par Exception Safety
+ 583 + + No-throw guarantee.
+ 584 + + */
+ 585 + + void
+ 586 + + reset() noexcept;
+ 587 + +
+ 588 + + /** Indicate a parsing failure.
+ 589 + +
+ 590 + + This changes the state of the parser to indicate that the parse has
+ 591 + + failed. A parser implementation can use this to fail the parser if
+ 592 + + needed due to external inputs.
+ 593 + +
+ 594 + + @attention
+ 595 + + If `! ec.failed()`, an implementation-defined error code that indicates
+ 596 + + failure will be stored instead.
+ 597 + +
+ 598 + + @par Complexity
+ 599 + + Constant.
+ 600 + +
+ 601 + + @par Exception Safety
+ 602 + + No-throw guarantee.
+ 603 + +
+ 604 + + @param ec The error code to set.
+ 605 + + */
+ 606 + + void
+ 607 + + fail(system::error_code ec) noexcept;
+ 608 + +
+ 609 + + /** Parse some of input characters as JSON, incrementally.
+ 610 + +
+ 611 + + This function parses the JSON text in the specified buffer, calling the
+ 612 + + handler to emit each SAX parsing event. The parse proceeds from the
+ 613 + + current state, which is at the beginning of a new JSON or in the middle
+ 614 + + of the current JSON if any characters were already parsed.
+ 615 + +
+ 616 + + The characters in the buffer are processed starting from the beginning,
+ 617 + + until one of the following conditions is met:
+ 618 + +
+ 619 + + @li All of the characters in the buffer have been parsed, or
+ 620 + + @li Some of the characters in the buffer have been parsed and the JSON
+ 621 + + is complete, or
+ 622 + + @li A parsing error occurs.
+ 623 + +
+ 624 + + The supplied buffer does not need to contain the entire JSON.
+ 625 + + Subsequent calls can provide more serialized data, allowing JSON to be
+ 626 + + processed incrementally. The end of the serialized JSON can be
+ 627 + + indicated by passing `more = false`.
+ 628 + +
+ 629 + + @par Complexity
+ 630 + + Linear in `size`.
+ 631 + +
+ 632 + + @par Exception Safety
+ 633 + + Basic guarantee. Calls to the handler may throw.
+ 634 + +
+ 635 + + Upon error or exception, subsequent calls will fail until @ref reset
+ 636 + + is called to parse a new JSON.
+ 637 + +
+ 638 + + @return The number of characters successfully
+ 639 + + parsed, which may be smaller than `size`.
+ 640 + +
+ 641 + + @param more `true` if there are possibly more buffers in the current
+ 642 + + JSON, otherwise `false`.
+ 643 + +
+ 644 + + @param data A pointer to a buffer of `size` characters to parse.
+ 645 + +
+ 646 + + @param size The number of characters pointed to by `data`.
+ 647 + +
+ 648 + + @param ec Set to the error, if any occurred.
+ 649 + +
+ 650 + + @{
+ 651 + + */
+ 652 + + std::size_t
+ 653 + + write_some(
+ 654 + + bool more,
+ 655 + + char const* data,
+ 656 + + std::size_t size,
+ 657 + + system::error_code& ec);
+ 658 + +
+ 659 + + std::size_t
+ 660 + + write_some(
+ 661 + + bool more,
+ 662 + + char const* data,
+ 663 + + std::size_t size,
+ 664 + + std::error_code& ec);
+ 665 + + /// @}
+ 666 + + };
+ 667 + +
+ 668 + + } // namespace json
+ 669 + + } // namespace boost
+ 670 + +
+ 671 + + #endif
+ 672 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.basic_parser_impl.hpp.5c3e10cbda02afe7ee8dcae02239f852.html b/json/gcovr/index.basic_parser_impl.hpp.5c3e10cbda02afe7ee8dcae02239f852.html new file mode 100644 index 00000000..404071f9 --- /dev/null +++ b/json/gcovr/index.basic_parser_impl.hpp.5c3e10cbda02afe7ee8dcae02239f852.html @@ -0,0 +1,25430 @@ + + + + + + basic_parser_impl.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

basic_parser_impl.hpp

+
+ + 98.3% Lines (1253/1275) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
basic_parser_impl.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_BASIC_PARSER_IMPL_HPP
+ 12 + + #define BOOST_JSON_BASIC_PARSER_IMPL_HPP
+ 13 + +
+ 14 + + #include <boost/json/detail/config.hpp>
+ 15 + + #include <boost/json/detail/literals.hpp>
+ 16 + + #include <boost/json/basic_parser.hpp>
+ 17 + + #include <boost/json/error.hpp>
+ 18 + + #include <boost/json/detail/buffer.hpp>
+ 19 + + #include <boost/json/detail/charconv/from_chars.hpp>
+ 20 + + #include <boost/json/detail/sse2.hpp>
+ 21 + + #include <boost/mp11/algorithm.hpp>
+ 22 + + #include <boost/mp11/integral.hpp>
+ 23 + + #include <cmath>
+ 24 + + #include <limits>
+ 25 + + #include <cstring>
+ 26 + +
+ 27 + + #ifdef _MSC_VER
+ 28 + + #pragma warning(push)
+ 29 + + #pragma warning(disable: 4702) // unreachable code
+ 30 + + #pragma warning(disable: 4127) // conditional expression is constant
+ 31 + + #endif
+ 32 + +
+ 33 + + /* This file must be manually included to get the
+ 34 + + function template definitions for basic_parser.
+ 35 + + */
+ 36 + +
+ 37 + + /* Reference:
+ 38 + +
+ 39 + + https://www.json.org/
+ 40 + +
+ 41 + + RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format
+ 42 + + https://tools.ietf.org/html/rfc7159
+ 43 + +
+ 44 + + https://ampl.com/netlib/fp/dtoa.c
+ 45 + + */
+ 46 + +
+ 47 + + #ifndef BOOST_JSON_DOCS
+ 48 + +
+ 49 + + namespace boost {
+ 50 + + namespace json {
+ 51 + + namespace detail {
+ 52 + +
+ 53 + + inline
+ 54 + + double
+ 55 + +1033693 pow10(int exp) noexcept
+ 56 + + {
+ 57 + + static double const tab[618] = {
+ 58 + + 1e-308, 1e-307, 1e-306, 1e-305, 1e-304, 1e-303, 1e-302, 1e-301,
+ 59 + +
+ 60 + + 1e-300, 1e-299, 1e-298, 1e-297, 1e-296, 1e-295, 1e-294, 1e-293, 1e-292, 1e-291,
+ 61 + + 1e-290, 1e-289, 1e-288, 1e-287, 1e-286, 1e-285, 1e-284, 1e-283, 1e-282, 1e-281,
+ 62 + + 1e-280, 1e-279, 1e-278, 1e-277, 1e-276, 1e-275, 1e-274, 1e-273, 1e-272, 1e-271,
+ 63 + + 1e-270, 1e-269, 1e-268, 1e-267, 1e-266, 1e-265, 1e-264, 1e-263, 1e-262, 1e-261,
+ 64 + + 1e-260, 1e-259, 1e-258, 1e-257, 1e-256, 1e-255, 1e-254, 1e-253, 1e-252, 1e-251,
+ 65 + + 1e-250, 1e-249, 1e-248, 1e-247, 1e-246, 1e-245, 1e-244, 1e-243, 1e-242, 1e-241,
+ 66 + + 1e-240, 1e-239, 1e-238, 1e-237, 1e-236, 1e-235, 1e-234, 1e-233, 1e-232, 1e-231,
+ 67 + + 1e-230, 1e-229, 1e-228, 1e-227, 1e-226, 1e-225, 1e-224, 1e-223, 1e-222, 1e-221,
+ 68 + + 1e-220, 1e-219, 1e-218, 1e-217, 1e-216, 1e-215, 1e-214, 1e-213, 1e-212, 1e-211,
+ 69 + + 1e-210, 1e-209, 1e-208, 1e-207, 1e-206, 1e-205, 1e-204, 1e-203, 1e-202, 1e-201,
+ 70 + +
+ 71 + + 1e-200, 1e-199, 1e-198, 1e-197, 1e-196, 1e-195, 1e-194, 1e-193, 1e-192, 1e-191,
+ 72 + + 1e-190, 1e-189, 1e-188, 1e-187, 1e-186, 1e-185, 1e-184, 1e-183, 1e-182, 1e-181,
+ 73 + + 1e-180, 1e-179, 1e-178, 1e-177, 1e-176, 1e-175, 1e-174, 1e-173, 1e-172, 1e-171,
+ 74 + + 1e-170, 1e-169, 1e-168, 1e-167, 1e-166, 1e-165, 1e-164, 1e-163, 1e-162, 1e-161,
+ 75 + + 1e-160, 1e-159, 1e-158, 1e-157, 1e-156, 1e-155, 1e-154, 1e-153, 1e-152, 1e-151,
+ 76 + + 1e-150, 1e-149, 1e-148, 1e-147, 1e-146, 1e-145, 1e-144, 1e-143, 1e-142, 1e-141,
+ 77 + + 1e-140, 1e-139, 1e-138, 1e-137, 1e-136, 1e-135, 1e-134, 1e-133, 1e-132, 1e-131,
+ 78 + + 1e-130, 1e-129, 1e-128, 1e-127, 1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121,
+ 79 + + 1e-120, 1e-119, 1e-118, 1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111,
+ 80 + + 1e-110, 1e-109, 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, 1e-101,
+ 81 + +
+ 82 + + 1e-100, 1e-099, 1e-098, 1e-097, 1e-096, 1e-095, 1e-094, 1e-093, 1e-092, 1e-091,
+ 83 + + 1e-090, 1e-089, 1e-088, 1e-087, 1e-086, 1e-085, 1e-084, 1e-083, 1e-082, 1e-081,
+ 84 + + 1e-080, 1e-079, 1e-078, 1e-077, 1e-076, 1e-075, 1e-074, 1e-073, 1e-072, 1e-071,
+ 85 + + 1e-070, 1e-069, 1e-068, 1e-067, 1e-066, 1e-065, 1e-064, 1e-063, 1e-062, 1e-061,
+ 86 + + 1e-060, 1e-059, 1e-058, 1e-057, 1e-056, 1e-055, 1e-054, 1e-053, 1e-052, 1e-051,
+ 87 + + 1e-050, 1e-049, 1e-048, 1e-047, 1e-046, 1e-045, 1e-044, 1e-043, 1e-042, 1e-041,
+ 88 + + 1e-040, 1e-039, 1e-038, 1e-037, 1e-036, 1e-035, 1e-034, 1e-033, 1e-032, 1e-031,
+ 89 + + 1e-030, 1e-029, 1e-028, 1e-027, 1e-026, 1e-025, 1e-024, 1e-023, 1e-022, 1e-021,
+ 90 + + 1e-020, 1e-019, 1e-018, 1e-017, 1e-016, 1e-015, 1e-014, 1e-013, 1e-012, 1e-011,
+ 91 + + 1e-010, 1e-009, 1e-008, 1e-007, 1e-006, 1e-005, 1e-004, 1e-003, 1e-002, 1e-001,
+ 92 + +
+ 93 + + 1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009,
+ 94 + + 1e+010, 1e+011, 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019,
+ 95 + + 1e+020, 1e+021, 1e+022, 1e+023, 1e+024, 1e+025, 1e+026, 1e+027, 1e+028, 1e+029,
+ 96 + + 1e+030, 1e+031, 1e+032, 1e+033, 1e+034, 1e+035, 1e+036, 1e+037, 1e+038, 1e+039,
+ 97 + + 1e+040, 1e+041, 1e+042, 1e+043, 1e+044, 1e+045, 1e+046, 1e+047, 1e+048, 1e+049,
+ 98 + + 1e+050, 1e+051, 1e+052, 1e+053, 1e+054, 1e+055, 1e+056, 1e+057, 1e+058, 1e+059,
+ 99 + + 1e+060, 1e+061, 1e+062, 1e+063, 1e+064, 1e+065, 1e+066, 1e+067, 1e+068, 1e+069,
+ 100 + + 1e+070, 1e+071, 1e+072, 1e+073, 1e+074, 1e+075, 1e+076, 1e+077, 1e+078, 1e+079,
+ 101 + + 1e+080, 1e+081, 1e+082, 1e+083, 1e+084, 1e+085, 1e+086, 1e+087, 1e+088, 1e+089,
+ 102 + + 1e+090, 1e+091, 1e+092, 1e+093, 1e+094, 1e+095, 1e+096, 1e+097, 1e+098, 1e+099,
+ 103 + +
+ 104 + + 1e+100, 1e+101, 1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107, 1e+108, 1e+109,
+ 105 + + 1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116, 1e+117, 1e+118, 1e+119,
+ 106 + + 1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125, 1e+126, 1e+127, 1e+128, 1e+129,
+ 107 + + 1e+130, 1e+131, 1e+132, 1e+133, 1e+134, 1e+135, 1e+136, 1e+137, 1e+138, 1e+139,
+ 108 + + 1e+140, 1e+141, 1e+142, 1e+143, 1e+144, 1e+145, 1e+146, 1e+147, 1e+148, 1e+149,
+ 109 + + 1e+150, 1e+151, 1e+152, 1e+153, 1e+154, 1e+155, 1e+156, 1e+157, 1e+158, 1e+159,
+ 110 + + 1e+160, 1e+161, 1e+162, 1e+163, 1e+164, 1e+165, 1e+166, 1e+167, 1e+168, 1e+169,
+ 111 + + 1e+170, 1e+171, 1e+172, 1e+173, 1e+174, 1e+175, 1e+176, 1e+177, 1e+178, 1e+179,
+ 112 + + 1e+180, 1e+181, 1e+182, 1e+183, 1e+184, 1e+185, 1e+186, 1e+187, 1e+188, 1e+189,
+ 113 + + 1e+190, 1e+191, 1e+192, 1e+193, 1e+194, 1e+195, 1e+196, 1e+197, 1e+198, 1e+199,
+ 114 + +
+ 115 + + 1e+200, 1e+201, 1e+202, 1e+203, 1e+204, 1e+205, 1e+206, 1e+207, 1e+208, 1e+209,
+ 116 + + 1e+210, 1e+211, 1e+212, 1e+213, 1e+214, 1e+215, 1e+216, 1e+217, 1e+218, 1e+219,
+ 117 + + 1e+220, 1e+221, 1e+222, 1e+223, 1e+224, 1e+225, 1e+226, 1e+227, 1e+228, 1e+229,
+ 118 + + 1e+230, 1e+231, 1e+232, 1e+233, 1e+234, 1e+235, 1e+236, 1e+237, 1e+238, 1e+239,
+ 119 + + 1e+240, 1e+241, 1e+242, 1e+243, 1e+244, 1e+245, 1e+246, 1e+247, 1e+248, 1e+249,
+ 120 + + 1e+250, 1e+251, 1e+252, 1e+253, 1e+254, 1e+255, 1e+256, 1e+257, 1e+258, 1e+259,
+ 121 + + 1e+260, 1e+261, 1e+262, 1e+263, 1e+264, 1e+265, 1e+266, 1e+267, 1e+268, 1e+269,
+ 122 + + 1e+270, 1e+271, 1e+272, 1e+273, 1e+274, 1e+275, 1e+276, 1e+277, 1e+278, 1e+279,
+ 123 + + 1e+280, 1e+281, 1e+282, 1e+283, 1e+284, 1e+285, 1e+286, 1e+287, 1e+288, 1e+289,
+ 124 + + 1e+290, 1e+291, 1e+292, 1e+293, 1e+294, 1e+295, 1e+296, 1e+297, 1e+298, 1e+299,
+ 125 + +
+ 126 + + 1e+300, 1e+301, 1e+302, 1e+303, 1e+304, 1e+305, 1e+306, 1e+307, 1e+308 };
+ 127 + +
+ 128 + +1033693 if( exp > 308 )
+ 129 + + {
+ 130 + +341 return std::numeric_limits<double>::infinity();
+ 131 + + }
+ 132 + +1033352 else if( exp < -308 )
+ 133 + + {
+ 134 + + // due to the way pow10 is used by dec_to_float,
+ 135 + + // we can afford to return 0.0 here
+ 136 + +151 return 0.0;
+ 137 + + }
+ 138 + + else
+ 139 + + {
+ 140 + +1033201 exp += 308;
+ 141 + +1033201 BOOST_ASSERT(exp >= 0 && exp < 618);
+ 142 + +1033201 return tab[exp];
+ 143 + + }
+ 144 + + }
+ 145 + +
+ 146 + + inline
+ 147 + + double
+ 148 + +1033693 dec_to_float(
+ 149 + + std::uint64_t m,
+ 150 + + std::int32_t e,
+ 151 + + bool neg) noexcept
+ 152 + + {
+ 153 + + // convert to double explicitly to silence warnings
+ 154 + +1033693 double x = static_cast<double>(m);
+ 155 + +1033693 if(neg)
+ 156 + +13164 x = -x;
+ 157 + +
+ 158 + +1033693 if(e < -305)
+ 159 + + {
+ 160 + +5187 x *= 1e-305 ;
+ 161 + +5187 e += 305;
+ 162 + + }
+ 163 + +
+ 164 + +1033693 if(e >= -22 && e < 0)
+ 165 + +54813 return x / pow10(-e);
+ 166 + +
+ 167 + +978880 return x * pow10(e);
+ 168 + + }
+ 169 + +
+ 170 + + inline
+ 171 + + bool
+ 172 + + is_control(char c) noexcept
+ 173 + + {
+ 174 + + return static_cast<unsigned char>(c) < 32;
+ 175 + + }
+ 176 + +
+ 177 + + inline
+ 178 + + int
+ 179 + +66931 hex_digit(unsigned char c) noexcept
+ 180 + + {
+ 181 + + // by Peter Dimov
+ 182 + +66931 if( c >= '0' && c <= '9' )
+ 183 + +35759 return c - '0';
+ 184 + +31172 c &= ~0x20;
+ 185 + +31172 if( c >= 'A' && c <= 'F' )
+ 186 + +30562 return 10 + c - 'A';
+ 187 + +610 return -1;
+ 188 + + }
+ 189 + +
+ 190 + + } // detail
+ 191 + +
+ 192 + + //----------------------------------------------------------
+ 193 + +
+ 194 + + template< class Handler >
+ 195 + + template< bool StackEmpty_, char First_ >
+ 196 + + struct basic_parser<Handler>::
+ 197 + + parse_number_helper
+ 198 + + {
+ 199 + + basic_parser* parser;
+ 200 + + char const* p;
+ 201 + +
+ 202 + + template< std::size_t N >
+ 203 + + char const*
+ 204 + +2126871 operator()( mp11::mp_size_t<N> ) const
+ 205 + + {
+ 206 + +4248301 return parser->parse_number(
+ 207 + +2126871 p,
+ 208 + + std::integral_constant<bool, StackEmpty_>(),
+ 209 + + std::integral_constant<char, First_>(),
+ 210 + + std::integral_constant<
+ 211 + +2121431 number_precision, static_cast<number_precision>(N)>() );
+ 212 + + }
+ 213 + + };
+ 214 + +
+ 215 + + //----------------------------------------------------------
+ 216 + +
+ 217 + + template<class Handler>
+ 218 + + void
+ 219 + +210519 basic_parser<Handler>::
+ 220 + + reserve()
+ 221 + + {
+ 222 + +210519 if(BOOST_JSON_LIKELY(
+ 223 + + ! st_.empty()))
+ 224 + +37444 return;
+ 225 + + // Reserve the largest stack we need,
+ 226 + + // to avoid reallocation during suspend.
+ 227 + +346150 st_.reserve(
+ 228 + + sizeof(state) + // document parsing state
+ 229 + + (sizeof(state) +
+ 230 + +173075 sizeof(std::size_t)) * depth() + // array and object state + size
+ 231 + + sizeof(state) + // value parsing state
+ 232 + + sizeof(std::size_t) + // string size
+ 233 + + sizeof(state)); // comment state
+ 234 + + }
+ 235 + +
+ 236 + + //----------------------------------------------------------
+ 237 + + //
+ 238 + + // The sentinel value is returned by parse functions
+ 239 + + // to indicate that the parser failed, or suspended.
+ 240 + + // this is used as it is distinct from all valid values
+ 241 + + // for data in write
+ 242 + +
+ 243 + + template<class Handler>
+ 244 + + const char*
+ 245 + +5340863 basic_parser<Handler>::
+ 246 + + sentinel()
+ 247 + + {
+ 248 + + // the "+1" ensures that the returned pointer is unique even if
+ 249 + + // the given input buffer borders on this object
+ 250 + + return reinterpret_cast<
+ 251 + +5340863 const char*>(this) + 1;
+ 252 + + }
+ 253 + +
+ 254 + + template<class Handler>
+ 255 + + bool
+ 256 + +2459821 basic_parser<Handler>::
+ 257 + + incomplete(
+ 258 + + const detail::const_stream_wrapper& cs)
+ 259 + + {
+ 260 + +2459821 return cs.begin() == sentinel();
+ 261 + + }
+ 262 + +
+ 263 + + //----------------------------------------------------------
+ 264 + + //
+ 265 + + // These functions are declared with the BOOST_NOINLINE
+ 266 + + // attribute to avoid polluting the parsers hot-path.
+ 267 + + // They return the canary value to indicate suspension
+ 268 + + // or failure.
+ 269 + +
+ 270 + + template<class Handler>
+ 271 + + const char*
+ 272 + + basic_parser<Handler>::
+ 273 + + suspend_or_fail(state st)
+ 274 + + {
+ 275 + + if(BOOST_JSON_LIKELY(
+ 276 + + ! ec_ && more_))
+ 277 + + {
+ 278 + + // suspend
+ 279 + + reserve();
+ 280 + + st_.push_unchecked(st);
+ 281 + + }
+ 282 + + return sentinel();
+ 283 + + }
+ 284 + +
+ 285 + + template<class Handler>
+ 286 + + const char*
+ 287 + +56150 basic_parser<Handler>::
+ 288 + + suspend_or_fail(
+ 289 + + state st,
+ 290 + + std::size_t n)
+ 291 + + {
+ 292 + +56150 if(BOOST_JSON_LIKELY(
+ 293 + + ! ec_ && more_))
+ 294 + + {
+ 295 + + // suspend
+ 296 + +35836 reserve();
+ 297 + +35836 st_.push_unchecked(n);
+ 298 + +35836 st_.push_unchecked(st);
+ 299 + + }
+ 300 + +56150 return sentinel();
+ 301 + + }
+ 302 + +
+ 303 + +
+ 304 + + template<class Handler>
+ 305 + + const char*
+ 306 + +19005 basic_parser<Handler>::
+ 307 + + fail(const char* p) noexcept
+ 308 + + {
+ 309 + +19005 BOOST_ASSERT( p != sentinel() );
+ 310 + +19005 end_ = p;
+ 311 + +19005 return sentinel();
+ 312 + + }
+ 313 + +
+ 314 + + template<class Handler>
+ 315 + + const char*
+ 316 + +7772 basic_parser<Handler>::
+ 317 + + fail(
+ 318 + + const char* p,
+ 319 + + error ev,
+ 320 + + source_location const* loc) noexcept
+ 321 + + {
+ 322 + +7772 BOOST_ASSERT( p != sentinel() );
+ 323 + +7772 end_ = p;
+ 324 + +7772 ec_.assign(ev, loc);
+ 325 + +7772 return sentinel();
+ 326 + + }
+ 327 + +
+ 328 + + template<class Handler>
+ 329 + + const char*
+ 330 + +11289 basic_parser<Handler>::
+ 331 + + maybe_suspend(
+ 332 + + const char* p,
+ 333 + + state st)
+ 334 + + {
+ 335 + +11289 if( p != sentinel() )
+ 336 + +9424 end_ = p;
+ 337 + +11289 if(BOOST_JSON_LIKELY(more_))
+ 338 + + {
+ 339 + + // suspend
+ 340 + +11027 reserve();
+ 341 + +11027 st_.push_unchecked(st);
+ 342 + + }
+ 343 + +11289 return sentinel();
+ 344 + + }
+ 345 + +
+ 346 + + template<class Handler>
+ 347 + + const char*
+ 348 + +38223 basic_parser<Handler>::
+ 349 + + maybe_suspend(
+ 350 + + const char* p,
+ 351 + + state st,
+ 352 + + std::size_t n)
+ 353 + + {
+ 354 + +38223 BOOST_ASSERT( p != sentinel() );
+ 355 + +38223 end_ = p;
+ 356 + +38223 if(BOOST_JSON_LIKELY(more_))
+ 357 + + {
+ 358 + + // suspend
+ 359 + +37823 reserve();
+ 360 + +37823 st_.push_unchecked(n);
+ 361 + +37823 st_.push_unchecked(st);
+ 362 + + }
+ 363 + +38223 return sentinel();
+ 364 + + }
+ 365 + +
+ 366 + + template<class Handler>
+ 367 + + const char*
+ 368 + +1123 basic_parser<Handler>::
+ 369 + + maybe_suspend(
+ 370 + + const char* p,
+ 371 + + state st,
+ 372 + + const number& num)
+ 373 + + {
+ 374 + +1123 BOOST_ASSERT( p != sentinel() );
+ 375 + +1123 end_ = p;
+ 376 + +1123 if(BOOST_JSON_LIKELY(more_))
+ 377 + + {
+ 378 + + // suspend
+ 379 + +1123 num_ = num;
+ 380 + +1123 reserve();
+ 381 + +1123 st_.push_unchecked(st);;
+ 382 + + }
+ 383 + +1123 return sentinel();
+ 384 + + }
+ 385 + +
+ 386 + + template<class Handler>
+ 387 + + const char*
+ 388 + +88656 basic_parser<Handler>::
+ 389 + + suspend(
+ 390 + + const char* p,
+ 391 + + state st)
+ 392 + + {
+ 393 + +88656 BOOST_ASSERT( p != sentinel() );
+ 394 + +88656 end_ = p;
+ 395 + + // suspend
+ 396 + +88656 reserve();
+ 397 + +88656 st_.push_unchecked(st);
+ 398 + +88656 return sentinel();
+ 399 + + }
+ 400 + +
+ 401 + + template<class Handler>
+ 402 + + const char*
+ 403 + +36054 basic_parser<Handler>::
+ 404 + + suspend(
+ 405 + + const char* p,
+ 406 + + state st,
+ 407 + + const number& num)
+ 408 + + {
+ 409 + +36054 BOOST_ASSERT( p != sentinel() );
+ 410 + +36054 end_ = p;
+ 411 + + // suspend
+ 412 + +36054 num_ = num;
+ 413 + +36054 reserve();
+ 414 + +36054 st_.push_unchecked(st);
+ 415 + +36054 return sentinel();
+ 416 + + }
+ 417 + +
+ 418 + + template<class Handler>
+ 419 + + template<
+ 420 + + bool StackEmpty_/*,
+ 421 + + bool Terminal_*/>
+ 422 + + const char*
+ 423 + +21737 basic_parser<Handler>::
+ 424 + + parse_comment(const char* p,
+ 425 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 426 + + /*std::integral_constant<bool, Terminal_>*/ bool terminal)
+ 427 + + {
+ 428 + +21737 detail::const_stream_wrapper cs(p, end_);
+ 429 + +21737 const char* start = cs.begin();
+ 430 + + std::size_t remain;
+ 431 + +21737 if(! stack_empty && ! st_.empty())
+ 432 + + {
+ 433 + + state st;
+ 434 + +3507 st_.pop(st);
+ 435 + +3507 switch(st)
+ 436 + + {
+ 437 + + default: BOOST_JSON_UNREACHABLE();
+ 438 + +534 case state::com1: goto do_com1;
+ 439 + +2319 case state::com2: goto do_com2;
+ 440 + +438 case state::com3: goto do_com3;
+ 441 + +216 case state::com4: goto do_com4;
+ 442 + + }
+ 443 + + }
+ 444 + +18230 BOOST_ASSERT(*cs == '/');
+ 445 + +18230 ++cs;
+ 446 + +18764 do_com1:
+ 447 + +18764 if(BOOST_JSON_UNLIKELY(! cs))
+ 448 + +551 return maybe_suspend(cs.begin(), state::com1);
+ 449 + +18213 switch(*cs)
+ 450 + + {
+ 451 + +5 default:
+ 452 + + {
+ 453 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 454 + + = BOOST_CURRENT_LOCATION;
+ 455 + +5 return fail(cs.begin(), error::syntax, &loc);
+ 456 + + }
+ 457 + +10524 case '/':
+ 458 + +10524 ++cs;
+ 459 + +12843 do_com2:
+ 460 + + // KRYSTIAN TODO: this is a mess, we have to fix this
+ 461 + +12843 remain = cs.remain();
+ 462 + +25686 cs = remain ? static_cast<const char*>(
+ 463 + +12843 std::memchr(cs.begin(), '\n', remain)) : sentinel();
+ 464 + +12843 if(! cs.begin())
+ 465 + +2143 cs = sentinel();
+ 466 + +12843 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 467 + + {
+ 468 + + // if the doc does not terminate
+ 469 + + // with a newline, treat it as the
+ 470 + + // end of the comment
+ 471 + +2568 if(terminal && ! more_)
+ 472 + + {
+ 473 + +39 if(BOOST_JSON_UNLIKELY(! h_.on_comment(
+ 474 + + {start, cs.remain(start)}, ec_)))
+ 475 + +2 return fail(cs.end());
+ 476 + +35 return cs.end();
+ 477 + + }
+ 478 + +2529 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part(
+ 479 + + {start, cs.remain(start)}, ec_)))
+ 480 + +95 return fail(cs.end());
+ 481 + +2339 if(terminal)
+ 482 + +106 return suspend(cs.end(), state::com2);
+ 483 + +2233 return maybe_suspend(cs.end(), state::com2);
+ 484 + + }
+ 485 + +10275 break;
+ 486 + +1684 case '*':
+ 487 + + do
+ 488 + + {
+ 489 + +9368 ++cs;
+ 490 + +9806 do_com3:
+ 491 + + // KRYSTIAN TODO: this is a mess, we have to fix this
+ 492 + +9806 remain = cs.remain();
+ 493 + +19612 cs = remain ? static_cast<const char*>(
+ 494 + +9806 std::memchr(cs.begin(), '*', remain)) : sentinel();
+ 495 + +9806 if(! cs.begin())
+ 496 + +242 cs = sentinel();
+ 497 + + // stopped inside a c comment
+ 498 + +9806 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 499 + + {
+ 500 + +503 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part(
+ 501 + + {start, cs.remain(start)}, ec_)))
+ 502 + +30 return fail(cs.end());
+ 503 + +443 return maybe_suspend(cs.end(), state::com3);
+ 504 + + }
+ 505 + + // found a asterisk, check if the next char is a slash
+ 506 + +9303 ++cs;
+ 507 + +9519 do_com4:
+ 508 + +9519 if(BOOST_JSON_UNLIKELY(! cs))
+ 509 + + {
+ 510 + +259 if(BOOST_JSON_UNLIKELY(! h_.on_comment_part(
+ 511 + + {start, cs.used(start)}, ec_)))
+ 512 + +18 return fail(cs.begin());
+ 513 + +223 return maybe_suspend(cs.begin(), state::com4);
+ 514 + + }
+ 515 + + }
+ 516 + +9260 while(*cs != '/');
+ 517 + + }
+ 518 + +17851 ++cs;
+ 519 + +17851 if(BOOST_JSON_UNLIKELY(! h_.on_comment(
+ 520 + + {start, cs.used(start)}, ec_)))
+ 521 + +964 return fail(cs.begin());
+ 522 + +15923 return cs.begin();
+ 523 + + }
+ 524 + +
+ 525 + + template<class Handler>
+ 526 + + template<bool StackEmpty_>
+ 527 + + const char*
+ 528 + +2318407 basic_parser<Handler>::
+ 529 + + parse_document(const char* p,
+ 530 + + std::integral_constant<bool, StackEmpty_> stack_empty)
+ 531 + + {
+ 532 + +2318407 detail::const_stream_wrapper cs(p, end_);
+ 533 + +2318407 if(! stack_empty && ! st_.empty())
+ 534 + + {
+ 535 + + state st;
+ 536 + +169596 st_.peek(st);
+ 537 + +169596 switch(st)
+ 538 + + {
+ 539 + +83532 default: goto do_doc2;
+ 540 + +601 case state::doc1:
+ 541 + +601 st_.pop(st);
+ 542 + +601 goto do_doc1;
+ 543 + +85243 case state::doc3:
+ 544 + +85243 st_.pop(st);
+ 545 + +85243 goto do_doc3;
+ 546 + +220 case state::com1: case state::com2:
+ 547 + + case state::com3: case state::com4:
+ 548 + +220 goto do_doc4;
+ 549 + + }
+ 550 + + }
+ 551 + +2148811 do_doc1:
+ 552 + +2149412 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 553 + +2149412 if(BOOST_JSON_UNLIKELY(! cs))
+ 554 + +633 return maybe_suspend(cs.begin(), state::doc1);
+ 555 + +2148779 do_doc2:
+ 556 + +2232311 switch(+opt_.allow_comments |
+ 557 + +2232311 (opt_.allow_trailing_commas << 1) |
+ 558 + +2232311 (opt_.allow_invalid_utf8 << 2))
+ 559 + + {
+ 560 + + // no extensions
+ 561 + +2208646 default:
+ 562 + +2208646 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16);
+ 563 + +2193488 break;
+ 564 + + // comments
+ 565 + +13534 case 1:
+ 566 + +13534 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::false_type(), opt_.allow_invalid_utf16);
+ 567 + +11271 break;
+ 568 + + // trailing
+ 569 + +6710 case 2:
+ 570 + +6710 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16);
+ 571 + +5117 break;
+ 572 + + // comments & trailing
+ 573 + +761 case 3:
+ 574 + +761 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::false_type(), opt_.allow_invalid_utf16);
+ 575 + +761 break;
+ 576 + + // skip validation
+ 577 + +760 case 4:
+ 578 + +760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16);
+ 579 + +760 break;
+ 580 + + // comments & skip validation
+ 581 + +760 case 5:
+ 582 + +760 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::false_type(), std::true_type(), opt_.allow_invalid_utf16);
+ 583 + +760 break;
+ 584 + + // trailing & skip validation
+ 585 + +760 case 6:
+ 586 + +760 cs = parse_value(cs.begin(), stack_empty, std::false_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16);
+ 587 + +760 break;
+ 588 + + // comments & trailing & skip validation
+ 589 + +380 case 7:
+ 590 + +380 cs = parse_value(cs.begin(), stack_empty, std::true_type(), std::true_type(), std::true_type(), opt_.allow_invalid_utf16);
+ 591 + +380 break;
+ 592 + + }
+ 593 + +2213297 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 594 + + // the appropriate state has already been pushed into stack
+ 595 + +110735 return sentinel();
+ 596 + +2102562 do_doc3:
+ 597 + +2188137 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 598 + +2188137 if(BOOST_JSON_UNLIKELY(! cs))
+ 599 + + {
+ 600 + +2185539 if(more_)
+ 601 + +88550 return suspend(cs.begin(), state::doc3);
+ 602 + + }
+ 603 + +2598 else if(opt_.allow_comments && *cs == '/')
+ 604 + + {
+ 605 + +536 do_doc4:
+ 606 + +756 cs = parse_comment(cs.begin(), stack_empty, std::true_type());
+ 607 + +671 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 608 + +339 return sentinel();
+ 609 + +332 goto do_doc3;
+ 610 + + }
+ 611 + +2099051 return cs.begin();
+ 612 + + }
+ 613 + +
+ 614 + + template<class Handler>
+ 615 + + template<
+ 616 + + bool StackEmpty_,
+ 617 + + bool AllowComments_/*,
+ 618 + + bool AllowTrailing_,
+ 619 + + bool AllowBadUTF8_*/>
+ 620 + + const char*
+ 621 + +2349922 basic_parser<Handler>::
+ 622 + + parse_value(const char* p,
+ 623 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 624 + + std::integral_constant<bool, AllowComments_> allow_comments,
+ 625 + + /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
+ 626 + + /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
+ 627 + + bool allow_bad_utf16)
+ 628 + + {
+ 629 + +2349922 if(stack_empty || st_.empty())
+ 630 + + {
+ 631 + +2248022 loop:
+ 632 + +2252938 switch(*p)
+ 633 + + {
+ 634 + +22753 case '0':
+ 635 + +22753 return mp11::mp_with_index<3>(
+ 636 + +22753 static_cast<unsigned char>(opt_.numbers),
+ 637 + +22092 parse_number_helper<true, '0'>{ this, p });
+ 638 + +25178 case '-':
+ 639 + +25178 return mp11::mp_with_index<3>(
+ 640 + +25178 static_cast<unsigned char>(opt_.numbers),
+ 641 + +24066 parse_number_helper<true, '-'>{ this, p });
+ 642 + +2041766 case '1': case '2': case '3':
+ 643 + + case '4': case '5': case '6':
+ 644 + + case '7': case '8': case '9':
+ 645 + +2041766 return mp11::mp_with_index<3>(
+ 646 + +2041766 static_cast<unsigned char>(opt_.numbers),
+ 647 + +2038922 parse_number_helper<true, '+'>{ this, p });
+ 648 + +11379 case 'n':
+ 649 + +11379 return parse_literal( p, detail::literals_c<detail::literals::null>() );
+ 650 + +664 case 't':
+ 651 + +664 return parse_literal( p, detail::literals_c<detail::literals::true_>() );
+ 652 + +722 case 'f':
+ 653 + +722 return parse_literal( p, detail::literals_c<detail::literals::false_>() );
+ 654 + +681 case 'I':
+ 655 + +681 if( !opt_.allow_infinity_and_nan )
+ 656 + + {
+ 657 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 658 + + = BOOST_CURRENT_LOCATION;
+ 659 + +24 return fail(p, error::syntax, &loc);
+ 660 + + }
+ 661 + +657 return parse_literal( p, detail::literals_c<detail::literals::infinity>() );
+ 662 + +231 case 'N':
+ 663 + +231 if( !opt_.allow_infinity_and_nan )
+ 664 + + {
+ 665 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 666 + + = BOOST_CURRENT_LOCATION;
+ 667 + +30 return fail(p, error::syntax, &loc);
+ 668 + + }
+ 669 + +201 return parse_literal(p, detail::literals_c<detail::literals::nan>() );
+ 670 + +47576 case '"':
+ 671 + +47576 return parse_string(p, std::true_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16);
+ 672 + +20618 case '[':
+ 673 + +20618 return parse_array(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 674 + +74128 case '{':
+ 675 + +74128 return parse_object(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 676 + +6125 case '/':
+ 677 + +6125 if(! allow_comments)
+ 678 + + {
+ 679 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 680 + + = BOOST_CURRENT_LOCATION;
+ 681 + +284 return fail(p, error::syntax, &loc);
+ 682 + + }
+ 683 + +5841 p = parse_comment(p, stack_empty, std::false_type());
+ 684 + + // KRYSTIAN NOTE: incomplete takes const_stream, we either
+ 685 + + // can add an overload, change the existing one to take a pointer,
+ 686 + + // or just leave it as is
+ 687 + +5605 if(BOOST_JSON_UNLIKELY(p == sentinel()))
+ 688 + +591 return maybe_suspend(p, state::val2);
+ 689 + + BOOST_FALLTHROUGH;
+ 690 + + case ' ':
+ 691 + + case '\t':
+ 692 + + case '\n':
+ 693 + + case '\r':
+ 694 + +5026 p = detail::count_whitespace(p, end_);
+ 695 + +5026 if(BOOST_JSON_UNLIKELY(p == end_))
+ 696 + +110 return maybe_suspend(p, state::val1);
+ 697 + +4916 goto loop;
+ 698 + +1105 default:
+ 699 + + {
+ 700 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 701 + + = BOOST_CURRENT_LOCATION;
+ 702 + +1105 return fail(p, error::syntax, &loc);
+ 703 + + }
+ 704 + + }
+ 705 + + }
+ 706 + +101900 return resume_value(p, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 707 + + }
+ 708 + +
+ 709 + + template<class Handler>
+ 710 + + template<
+ 711 + + bool AllowComments_/*,
+ 712 + + bool AllowTrailing_,
+ 713 + + bool AllowBadUTF8_*/>
+ 714 + + const char*
+ 715 + +101900 basic_parser<Handler>::
+ 716 + + resume_value(const char* p,
+ 717 + + std::integral_constant<bool, AllowComments_> allow_comments,
+ 718 + + /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
+ 719 + + /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
+ 720 + + bool allow_bad_utf16)
+ 721 + + {
+ 722 + + state st;
+ 723 + +101900 st_.peek(st);
+ 724 + +101900 switch(st)
+ 725 + + {
+ 726 + + default: BOOST_JSON_UNREACHABLE();
+ 727 + +1924 case state::lit1:
+ 728 + +1924 return parse_literal(p, detail::literals_c<detail::literals::resume>() );
+ 729 + +
+ 730 + +20256 case state::str1: case state::str2:
+ 731 + + case state::str8:
+ 732 + +20256 return parse_string(p, std::false_type(), std::false_type(), allow_bad_utf8, allow_bad_utf16);
+ 733 + +
+ 734 + +5716 case state::arr1: case state::arr2:
+ 735 + + case state::arr3: case state::arr4:
+ 736 + + case state::arr5: case state::arr6:
+ 737 + +5716 return parse_array(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 738 + +
+ 739 + +35047 case state::obj1: case state::obj2:
+ 740 + + case state::obj3: case state::obj4:
+ 741 + + case state::obj5: case state::obj6:
+ 742 + + case state::obj7: case state::obj8:
+ 743 + + case state::obj9: case state::obj10:
+ 744 + + case state::obj11:
+ 745 + +35047 return parse_object(p, std::false_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 746 + +
+ 747 + +37174 case state::num1: case state::num2:
+ 748 + + case state::num3: case state::num4:
+ 749 + + case state::num5: case state::num6:
+ 750 + + case state::num7: case state::num8:
+ 751 + + case state::exp1: case state::exp2:
+ 752 + + case state::exp3:
+ 753 + +37174 return mp11::mp_with_index<3>(
+ 754 + +37174 static_cast<unsigned char>(opt_.numbers),
+ 755 + +36351 parse_number_helper<false, 0>{ this, p });
+ 756 + +
+ 757 + + // KRYSTIAN NOTE: these are special cases
+ 758 + +108 case state::val1:
+ 759 + + {
+ 760 + +108 st_.pop(st);
+ 761 + +108 BOOST_ASSERT(st_.empty());
+ 762 + +108 p = detail::count_whitespace(p, end_);
+ 763 + +108 if(BOOST_JSON_UNLIKELY(p == end_))
+ 764 + + return maybe_suspend(p, state::val1);
+ 765 + +108 return parse_value(p, std::true_type(), allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 766 + + }
+ 767 + +
+ 768 + +1608 case state::val2:
+ 769 + + {
+ 770 + +1608 st_.pop(st);
+ 771 + +1608 p = parse_comment(p, std::false_type(), std::false_type());
+ 772 + +1590 if(BOOST_JSON_UNLIKELY(p == sentinel()))
+ 773 + +1274 return maybe_suspend(p, state::val2);
+ 774 + +316 if(BOOST_JSON_UNLIKELY( p == end_ ))
+ 775 + +77 return maybe_suspend(p, state::val3);
+ 776 + +239 BOOST_ASSERT(st_.empty());
+ 777 + +239 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 778 + + }
+ 779 + +
+ 780 + +67 case state::val3:
+ 781 + + {
+ 782 + +67 st_.pop(st);
+ 783 + +67 return parse_value(p, std::true_type(), std::true_type(), allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 784 + + }
+ 785 + + }
+ 786 + + }
+ 787 + +
+ 788 + + template<class Handler>
+ 789 + + template<class Literal>
+ 790 + + const char*
+ 791 + +16563 basic_parser<Handler>::
+ 792 + + parse_literal(const char* p, Literal)
+ 793 + + {
+ 794 + + using L = detail::literals;
+ 795 + +
+ 796 + + std::size_t cur_lit;
+ 797 + + std::size_t offset;
+ 798 + +
+ 799 + +16563 detail::const_stream_wrapper cs(p, end_);
+ 800 + + BOOST_IF_CONSTEXPR( Literal::value != L::resume )
+ 801 + + {
+ 802 + +13632 constexpr std::size_t index = literal_index(Literal::value);
+ 803 + +13632 constexpr char const* literal = detail::literal_strings[index];
+ 804 + +13632 constexpr std::size_t sz = detail::literal_sizes[index];
+ 805 + +
+ 806 + +13632 if(BOOST_JSON_LIKELY( cs.remain() >= sz ))
+ 807 + + {
+ 808 + +11982 int const cmp = std::memcmp(cs.begin(), literal, sz);
+ 809 + +11982 if( cmp != 0 )
+ 810 + + {
+ 811 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 812 + +197 return fail(cs.begin(), error::syntax, &loc);
+ 813 + + }
+ 814 + +
+ 815 + + BOOST_IF_CONSTEXPR( Literal::value == L::null )
+ 816 + + {
+ 817 + +10787 if(BOOST_JSON_UNLIKELY(
+ 818 + + ! h_.on_null(ec_)))
+ 819 + +161 return fail(cs.begin());
+ 820 + + }
+ 821 + + else BOOST_IF_CONSTEXPR( Literal::value == L::true_ )
+ 822 + + {
+ 823 + +384 if(BOOST_JSON_UNLIKELY(
+ 824 + + ! h_.on_bool(true, ec_)))
+ 825 + +14 return fail(cs.begin());
+ 826 + + }
+ 827 + + else BOOST_IF_CONSTEXPR( Literal::value == L::false_ )
+ 828 + + {
+ 829 + +406 if(BOOST_JSON_UNLIKELY(
+ 830 + + ! h_.on_bool(false, ec_)))
+ 831 + +13 return fail(cs.begin());
+ 832 + + }
+ 833 + + else BOOST_IF_CONSTEXPR( Literal::value == L::infinity )
+ 834 + + {
+ 835 + +103 if(BOOST_JSON_UNLIKELY(
+ 836 + + ! h_.on_double(
+ 837 + + std::numeric_limits<double>::infinity(),
+ 838 + + string_view(literal, sz),
+ 839 + + ec_)))
+ 840 + +13 return fail(cs.begin());
+ 841 + + }
+ 842 + + else BOOST_IF_CONSTEXPR( Literal::value == L::neg_infinity )
+ 843 + + {
+ 844 + +9 if(BOOST_JSON_UNLIKELY(
+ 845 + + ! h_.on_double(
+ 846 + + -std::numeric_limits<double>::infinity(),
+ 847 + + string_view(literal, sz),
+ 848 + + ec_)))
+ 849 + +1 return fail(cs.begin());
+ 850 + + }
+ 851 + + else BOOST_IF_CONSTEXPR( Literal::value == L::nan )
+ 852 + + {
+ 853 + +96 if(BOOST_JSON_UNLIKELY(
+ 854 + + ! h_.on_double(
+ 855 + + std::numeric_limits<double>::quiet_NaN(),
+ 856 + + string_view(literal, sz),
+ 857 + + ec_)))
+ 858 + +12 return fail(cs.begin());
+ 859 + + }
+ 860 + + else
+ 861 + + {
+ 862 + + BOOST_JSON_UNREACHABLE();
+ 863 + + }
+ 864 + +
+ 865 + +11361 cs += sz;
+ 866 + +11361 return cs.begin();
+ 867 + + }
+ 868 + +
+ 869 + +1650 offset = 0;
+ 870 + +1650 cur_lit = index;
+ 871 + + }
+ 872 + + else
+ 873 + + {
+ 874 + + state st;
+ 875 + +2931 st_.pop(st);
+ 876 + +2931 BOOST_ASSERT( st == state::lit1 );
+ 877 + +
+ 878 + +2931 cur_lit = cur_lit_;
+ 879 + +2931 offset = lit_offset_;
+ 880 + + }
+ 881 + +
+ 882 + +4581 std::size_t const lit_size = detail::literal_sizes[cur_lit];
+ 883 + +4581 std::size_t const size = (std::min)( lit_size - offset, cs.remain() );
+ 884 + +4581 int cmp = 0;
+ 885 + +4581 if(BOOST_JSON_LIKELY( cs.begin() ))
+ 886 + +4580 cmp = std::memcmp(
+ 887 + +4580 cs.begin(), detail::literal_strings[cur_lit] + offset, size );
+ 888 + +4581 if( cmp != 0 )
+ 889 + + {
+ 890 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 891 + +699 return fail(cs.begin(), error::syntax, &loc);
+ 892 + + }
+ 893 + +
+ 894 + +3882 if(BOOST_JSON_UNLIKELY( offset + size < lit_size ))
+ 895 + + {
+ 896 + +1990 BOOST_ASSERT( cur_lit < 256 );
+ 897 + +1990 cur_lit_ = static_cast<unsigned char>( cur_lit );
+ 898 + +1990 BOOST_ASSERT( offset + size < 256 );
+ 899 + +1990 lit_offset_ = static_cast<unsigned char>( offset + size );
+ 900 + +1990 return maybe_suspend(cs.begin() + size, state::lit1);
+ 901 + + }
+ 902 + +
+ 903 + +1892 switch( static_cast<L>(cur_lit) )
+ 904 + + {
+ 905 + +472 case L::null:
+ 906 + +472 if(BOOST_JSON_UNLIKELY(
+ 907 + + ! h_.on_null(ec_)))
+ 908 + +61 return fail(cs.begin());
+ 909 + +351 break;
+ 910 + +152 case L::true_:
+ 911 + +152 if(BOOST_JSON_UNLIKELY(
+ 912 + + ! h_.on_bool(true, ec_)))
+ 913 + +22 return fail(cs.begin());
+ 914 + +109 break;
+ 915 + +198 case L::false_:
+ 916 + +198 if(BOOST_JSON_UNLIKELY(
+ 917 + + ! h_.on_bool(false, ec_)))
+ 918 + +28 return fail(cs.begin());
+ 919 + +142 break;
+ 920 + +308 case L::infinity:
+ 921 + +308 if(BOOST_JSON_UNLIKELY(
+ 922 + + ! h_.on_double(
+ 923 + + std::numeric_limits<double>::infinity(),
+ 924 + + string_view(
+ 925 + + detail::literal_strings[ literal_index(L::infinity) ],
+ 926 + + detail::literal_sizes[ literal_index(L::infinity) ]),
+ 927 + + ec_)))
+ 928 + +49 return fail(cs.begin());
+ 929 + +210 break;
+ 930 + +686 case L::neg_infinity:
+ 931 + +686 if(BOOST_JSON_UNLIKELY(
+ 932 + + ! h_.on_double(
+ 933 + + -std::numeric_limits<double>::infinity(),
+ 934 + + string_view(
+ 935 + + detail::literal_strings[ literal_index(L::neg_infinity) ],
+ 936 + + detail::literal_sizes[ literal_index(L::neg_infinity) ]),
+ 937 + + ec_)))
+ 938 + +102 return fail(cs.begin());
+ 939 + +482 break;
+ 940 + +76 case L::nan:
+ 941 + +76 if(BOOST_JSON_UNLIKELY(
+ 942 + + ! h_.on_double(
+ 943 + + std::numeric_limits<double>::quiet_NaN(),
+ 944 + + string_view(
+ 945 + + detail::literal_strings[ literal_index(L::nan) ],
+ 946 + + detail::literal_sizes[ literal_index(L::nan) ]),
+ 947 + + ec_)))
+ 948 + +12 return fail(cs.begin());
+ 949 + +52 break;
+ 950 + + default: BOOST_JSON_UNREACHABLE();
+ 951 + + }
+ 952 + +
+ 953 + +1346 cs += size;
+ 954 + +1346 return cs.begin();
+ 955 + + }
+ 956 + +
+ 957 + + //----------------------------------------------------------
+ 958 + +
+ 959 + + template<class Handler>
+ 960 + + template<bool StackEmpty_, bool IsKey_>
+ 961 + + const char*
+ 962 + +161297 basic_parser<Handler>::
+ 963 + + parse_string(const char* p,
+ 964 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 965 + + std::integral_constant<bool, IsKey_> is_key,
+ 966 + + bool allow_bad_utf8,
+ 967 + + bool allow_bad_utf16)
+ 968 + + {
+ 969 + +161297 detail::const_stream_wrapper cs(p, end_);
+ 970 + + std::size_t total;
+ 971 + + char const* start;
+ 972 + + std::size_t size;
+ 973 + +161297 if(! stack_empty && ! st_.empty())
+ 974 + + {
+ 975 + + state st;
+ 976 + +32896 st_.pop(st);
+ 977 + +32896 st_.pop(total);
+ 978 + +32896 switch(st)
+ 979 + + {
+ 980 + + default: BOOST_JSON_UNREACHABLE();
+ 981 + +3149 case state::str2: goto do_str2;
+ 982 + +1861 case state::str8: goto do_str8;
+ 983 + +27886 case state::str1: break;
+ 984 + + }
+ 985 + + }
+ 986 + + else
+ 987 + + {
+ 988 + +128401 BOOST_ASSERT(*cs == '\x22'); // '"'
+ 989 + +128401 ++cs;
+ 990 + +128401 total = 0;
+ 991 + + }
+ 992 + +
+ 993 + +164779 do_str1:
+ 994 + +164779 start = cs.begin();
+ 995 + +329558 cs = allow_bad_utf8?
+ 996 + +2177 detail::count_valid<true>(cs.begin(), cs.end()):
+ 997 + +162602 detail::count_valid<false>(cs.begin(), cs.end());
+ 998 + +164779 size = cs.used(start);
+ 999 + +164779 if(is_key)
+ 1000 + + {
+ 1001 + +46685 BOOST_ASSERT(total <= Handler::max_key_size);
+ 1002 + +93996 if(BOOST_JSON_UNLIKELY(size >
+ 1003 + + Handler::max_key_size - total))
+ 1004 + + {
+ 1005 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1006 + + = BOOST_CURRENT_LOCATION;
+ 1007 + +3 return fail(cs.begin(), error::key_too_large, &loc);
+ 1008 + + }
+ 1009 + + }
+ 1010 + + else
+ 1011 + + {
+ 1012 + +35321 BOOST_ASSERT(total <= Handler::max_string_size);
+ 1013 + +70783 if(BOOST_JSON_UNLIKELY(size >
+ 1014 + + Handler::max_string_size - total))
+ 1015 + + {
+ 1016 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1017 + + = BOOST_CURRENT_LOCATION;
+ 1018 + +3 return fail(cs.begin(), error::string_too_large, &loc);
+ 1019 + + }
+ 1020 + + }
+ 1021 + +164773 total += size;
+ 1022 + +164773 if(BOOST_JSON_UNLIKELY(! cs))
+ 1023 + + {
+ 1024 + + // call handler if the string isn't empty
+ 1025 + +30220 if(BOOST_JSON_LIKELY(size))
+ 1026 + + {
+ 1027 + + {
+ 1028 + +27063 bool r = is_key?
+ 1029 + +12402 h_.on_key_part( {start, size}, total, ec_ ):
+ 1030 + +15995 h_.on_string_part( {start, size}, total, ec_ );
+ 1031 + +
+ 1032 + +25955 if(BOOST_JSON_UNLIKELY(!r))
+ 1033 + + {
+ 1034 + +1110 return fail(cs.begin());
+ 1035 + + }
+ 1036 + + }
+ 1037 + + }
+ 1038 + +28002 return maybe_suspend(cs.begin(), state::str1, total);
+ 1039 + + }
+ 1040 + + // at this point all valid characters have been skipped, so any remaining
+ 1041 + + // if there are any more characters, they are either escaped, or incomplete
+ 1042 + + // utf8, or invalid utf8
+ 1043 + +134553 if(BOOST_JSON_UNLIKELY(*cs != '\x22')) // '"'
+ 1044 + + {
+ 1045 + + // sequence is invalid or incomplete
+ 1046 + +15068 if((*cs & 0x80) && !allow_bad_utf8)
+ 1047 + + {
+ 1048 + +3462 seq_.save(cs.begin(), cs.remain());
+ 1049 + +3462 if(BOOST_JSON_UNLIKELY(seq_.complete()))
+ 1050 + + {
+ 1051 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1052 + + = BOOST_CURRENT_LOCATION;
+ 1053 + +1557 return fail(cs.begin(), error::syntax, &loc);
+ 1054 + + }
+ 1055 + +1905 if(BOOST_JSON_LIKELY(size))
+ 1056 + + {
+ 1057 + +245 bool const r = is_key?
+ 1058 + +22 h_.on_key_part( {start, size}, total, ec_ ):
+ 1059 + +245 h_.on_string_part( {start, size}, total, ec_ );
+ 1060 + +223 if(BOOST_JSON_UNLIKELY( !r ))
+ 1061 + +22 return fail( cs.begin() );
+ 1062 + + }
+ 1063 + +1861 return maybe_suspend(cs.end(), state::str8, total);
+ 1064 + + }
+ 1065 + +11606 else if(BOOST_JSON_LIKELY(*cs == '\\'))
+ 1066 + + {
+ 1067 + + // flush unescaped run from input
+ 1068 + +11497 if(BOOST_JSON_LIKELY(size))
+ 1069 + + {
+ 1070 + +4250 bool const r = is_key?
+ 1071 + +1226 h_.on_key_part( {start, size}, total, ec_ ):
+ 1072 + +3554 h_.on_string_part( {start, size}, total, ec_ );
+ 1073 + +3766 if(BOOST_JSON_UNLIKELY( !r ))
+ 1074 + +484 return fail( cs.begin() );
+ 1075 + + }
+ 1076 + +7247 do_str2:
+ 1077 + +13678 cs = parse_escaped(cs.begin(), total, stack_empty, is_key, allow_bad_utf16);
+ 1078 + +12716 if(BOOST_JSON_UNLIKELY( incomplete(cs) ))
+ 1079 + +5473 return suspend_or_fail(state::str2, total);
+ 1080 + +
+ 1081 + +7243 goto do_str1;
+ 1082 + + }
+ 1083 + + // illegal control
+ 1084 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 1085 + +109 return fail(cs.begin(), error::syntax, &loc);
+ 1086 + + }
+ 1087 + +
+ 1088 + + {
+ 1089 + +119485 bool r = is_key?
+ 1090 + +84509 h_.on_key( {start, size}, total, ec_ ):
+ 1091 + +41985 h_.on_string( {start, size}, total, ec_ );
+ 1092 + +
+ 1093 + +115111 if(BOOST_JSON_UNLIKELY(!r))
+ 1094 + + {
+ 1095 + +4318 return fail(cs.begin());
+ 1096 + + }
+ 1097 + + }
+ 1098 + +
+ 1099 + +110793 ++cs;
+ 1100 + +110793 return cs.begin();
+ 1101 + +
+ 1102 + +1861 do_str8:
+ 1103 + +1861 uint8_t needed = seq_.needed();
+ 1104 + +1861 if(BOOST_JSON_UNLIKELY( !seq_.append(cs.begin(), cs.remain()) ))
+ 1105 + + return maybe_suspend(cs.end(), state::str8, total);
+ 1106 + +1861 if(BOOST_JSON_UNLIKELY( !seq_.valid() ))
+ 1107 + + {
+ 1108 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 1109 + +210 return fail(cs.begin(), error::syntax, &loc);
+ 1110 + + }
+ 1111 + + {
+ 1112 + +1651 bool const r = is_key?
+ 1113 + +201 h_.on_key_part( {seq_.data(), seq_.length()}, total, ec_ ):
+ 1114 + +1651 h_.on_string_part( {seq_.data(), seq_.length()}, total, ec_ );
+ 1115 + +1450 if(BOOST_JSON_UNLIKELY( !r ))
+ 1116 + +201 return fail( cs.begin() );
+ 1117 + + }
+ 1118 + +1249 cs += needed;
+ 1119 + +1249 goto do_str1;
+ 1120 + + }
+ 1121 + +
+ 1122 + + template<class Handler>
+ 1123 + + template<bool StackEmpty_>
+ 1124 + + const char*
+ 1125 + +13678 basic_parser<Handler>::
+ 1126 + + parse_escaped(
+ 1127 + + const char* p,
+ 1128 + + std::size_t& total,
+ 1129 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 1130 + + bool is_key,
+ 1131 + + bool allow_bad_utf16)
+ 1132 + + {
+ 1133 + +13678 constexpr unsigned urc = 0xFFFD; // Unicode replacement character
+ 1134 + +13678 auto const ev_too_large = is_key?
+ 1135 + + error::key_too_large : error::string_too_large;
+ 1136 + +13678 auto const max_size = is_key?
+ 1137 + + Handler::max_key_size : Handler::max_string_size;
+ 1138 + + int digit;
+ 1139 + +
+ 1140 + + //---------------------------------------------------------------
+ 1141 + + //
+ 1142 + + // To handle escapes, a local temporary buffer accumulates
+ 1143 + + // the unescaped result. The algorithm attempts to fill the
+ 1144 + + // buffer to capacity before invoking the handler.
+ 1145 + + // In some cases the temporary buffer needs to be flushed
+ 1146 + + // before it is full:
+ 1147 + + // * When the closing double quote is seen
+ 1148 + + // * When there in no more input (and more is expected later)
+ 1149 + + // A goal of the algorithm is to call the handler as few times
+ 1150 + + // as possible. Thus, when the first escape is encountered,
+ 1151 + + // the algorithm attempts to fill the temporary buffer first.
+ 1152 + + //
+ 1153 + +13678 detail::buffer<BOOST_JSON_STACK_BUFFER_SIZE> temp;
+ 1154 + +
+ 1155 + + // Unescaped JSON is never larger than its escaped version.
+ 1156 + + // To efficiently process only what will fit in the temporary buffer,
+ 1157 + + // the size of the input stream is temporarily "clipped" to the size
+ 1158 + + // of the temporary buffer.
+ 1159 + + // handle escaped character
+ 1160 + +13678 detail::clipped_const_stream cs(p, end_);
+ 1161 + +13678 cs.clip(temp.max_size());
+ 1162 + +
+ 1163 + +13678 if(! stack_empty && ! st_.empty())
+ 1164 + + {
+ 1165 + + state st;
+ 1166 + +3149 st_.pop(st);
+ 1167 + +3149 switch(st)
+ 1168 + + {
+ 1169 + + default: BOOST_JSON_UNREACHABLE();
+ 1170 + +528 case state::str3: goto do_str3;
+ 1171 + +392 case state::str4: goto do_str4;
+ 1172 + +390 case state::str5: goto do_str5;
+ 1173 + +389 case state::str6: goto do_str6;
+ 1174 + +386 case state::str7: goto do_str7;
+ 1175 + +232 case state::sur1: goto do_sur1;
+ 1176 + +188 case state::sur2: goto do_sur2;
+ 1177 + +164 case state::sur3: goto do_sur3;
+ 1178 + +162 case state::sur4: goto do_sur4;
+ 1179 + +160 case state::sur5: goto do_sur5;
+ 1180 + +158 case state::sur6: goto do_sur6;
+ 1181 + + }
+ 1182 + + }
+ 1183 + +
+ 1184 + +3781 while(true)
+ 1185 + + {
+ 1186 + +14310 BOOST_ASSERT( temp.capacity() );
+ 1187 + +14310 BOOST_ASSERT(*cs == '\\');
+ 1188 + +14310 ++cs;
+ 1189 + +15169 do_str3:
+ 1190 + +15374 if(BOOST_JSON_UNLIKELY(! cs))
+ 1191 + + {
+ 1192 + +561 if(BOOST_JSON_LIKELY(! temp.empty()))
+ 1193 + + {
+ 1194 + + BOOST_ASSERT(total <= max_size);
+ 1195 + +100 if(BOOST_JSON_UNLIKELY(
+ 1196 + + temp.size() > max_size - total))
+ 1197 + + {
+ 1198 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1199 + + = BOOST_CURRENT_LOCATION;
+ 1200 + + return fail(cs.begin(), ev_too_large, &loc);
+ 1201 + + }
+ 1202 + +100 total += temp.size();
+ 1203 + + {
+ 1204 + +91 bool r = is_key
+ 1205 + +100 ? h_.on_key_part(temp.get(), total, ec_)
+ 1206 + +100 : h_.on_string_part(temp.get(), total, ec_);
+ 1207 + +
+ 1208 + +91 if(BOOST_JSON_UNLIKELY(!r))
+ 1209 + + {
+ 1210 + +9 return fail(cs.begin());
+ 1211 + + }
+ 1212 + + }
+ 1213 + +82 temp.clear();
+ 1214 + + }
+ 1215 + +543 cs.clip(temp.max_size());
+ 1216 + +543 if(BOOST_JSON_UNLIKELY(! cs))
+ 1217 + +543 return maybe_suspend(cs.begin(), state::str3);
+ 1218 + + }
+ 1219 + +14813 switch(*cs)
+ 1220 + + {
+ 1221 + +191 default:
+ 1222 + + {
+ 1223 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1224 + + = BOOST_CURRENT_LOCATION;
+ 1225 + +191 return fail(cs.begin(), error::syntax, &loc);
+ 1226 + + }
+ 1227 + +265 case '\x22': // '"'
+ 1228 + +265 temp.push_back('\x22');
+ 1229 + +265 ++cs;
+ 1230 + +265 break;
+ 1231 + +178 case '\\':
+ 1232 + +178 temp.push_back('\\');
+ 1233 + +178 ++cs;
+ 1234 + +178 break;
+ 1235 + +96 case '/':
+ 1236 + +96 temp.push_back('/');
+ 1237 + +96 ++cs;
+ 1238 + +96 break;
+ 1239 + +112 case 'b':
+ 1240 + +112 temp.push_back('\x08');
+ 1241 + +112 ++cs;
+ 1242 + +112 break;
+ 1243 + +108 case 'f':
+ 1244 + +108 temp.push_back('\x0c');
+ 1245 + +108 ++cs;
+ 1246 + +108 break;
+ 1247 + +1763 case 'n':
+ 1248 + +1763 temp.push_back('\x0a');
+ 1249 + +1763 ++cs;
+ 1250 + +1763 break;
+ 1251 + +146 case 'r':
+ 1252 + +146 temp.push_back('\x0d');
+ 1253 + +146 ++cs;
+ 1254 + +146 break;
+ 1255 + +266 case 't':
+ 1256 + +266 temp.push_back('\x09');
+ 1257 + +266 ++cs;
+ 1258 + +266 break;
+ 1259 + +11688 case 'u':
+ 1260 + + // utf16 escape
+ 1261 + + //
+ 1262 + + // fast path only when the buffer
+ 1263 + + // is large enough for 2 surrogates
+ 1264 + +11688 if(BOOST_JSON_LIKELY(cs.remain() > 10))
+ 1265 + + {
+ 1266 + + // KRYSTIAN TODO: this could be done
+ 1267 + + // with fewer instructions
+ 1268 + +11394 digit = detail::load_little_endian<4>(
+ 1269 + +5697 cs.begin() + 1);
+ 1270 + +5697 int d4 = detail::hex_digit(static_cast<
+ 1271 + +5697 unsigned char>(digit >> 24));
+ 1272 + +5697 int d3 = detail::hex_digit(static_cast<
+ 1273 + +5697 unsigned char>(digit >> 16));
+ 1274 + +5697 int d2 = detail::hex_digit(static_cast<
+ 1275 + +5697 unsigned char>(digit >> 8));
+ 1276 + +5697 int d1 = detail::hex_digit(static_cast<
+ 1277 + + unsigned char>(digit));
+ 1278 + +5697 if(BOOST_JSON_UNLIKELY(
+ 1279 + + (d1 | d2 | d3 | d4) == -1))
+ 1280 + + {
+ 1281 + +60 if(d1 != -1)
+ 1282 + +45 ++cs;
+ 1283 + +60 if(d2 != -1)
+ 1284 + +30 ++cs;
+ 1285 + +60 if(d3 != -1)
+ 1286 + +15 ++cs;
+ 1287 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1288 + + = BOOST_CURRENT_LOCATION;
+ 1289 + +60 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1290 + + }
+ 1291 + + // 32 bit unicode scalar value
+ 1292 + +5637 unsigned u1 =
+ 1293 + +5637 (d1 << 12) + (d2 << 8) +
+ 1294 + +5637 (d3 << 4) + d4;
+ 1295 + + // valid unicode scalar values are
+ 1296 + + // [0, D7FF] and [E000, 10FFFF]
+ 1297 + + // values within this range are valid utf-8
+ 1298 + + // code points and invalid leading surrogates.
+ 1299 + +5637 if(BOOST_JSON_LIKELY(
+ 1300 + + u1 < 0xd800 || u1 > 0xdfff))
+ 1301 + + {
+ 1302 + +1340 cs += 5;
+ 1303 + +1340 temp.append_utf8(u1);
+ 1304 + +1340 break;
+ 1305 + + }
+ 1306 + +4297 if(BOOST_JSON_UNLIKELY(u1 > 0xdbff))
+ 1307 + + {
+ 1308 + + // If it's an illegal leading surrogate and
+ 1309 + + // the parser does not allow it, return an error.
+ 1310 + +707 if(!allow_bad_utf16)
+ 1311 + + {
+ 1312 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1313 + + = BOOST_CURRENT_LOCATION;
+ 1314 + +122 return fail(cs.begin(), error::illegal_leading_surrogate,
+ 1315 + +122 &loc);
+ 1316 + + }
+ 1317 + + // Otherwise, append the Unicode replacement character
+ 1318 + + else
+ 1319 + + {
+ 1320 + +585 cs += 5;
+ 1321 + +585 temp.append_utf8(urc);
+ 1322 + +585 break;
+ 1323 + + }
+ 1324 + + }
+ 1325 + +3590 cs += 5;
+ 1326 + + // KRYSTIAN TODO: this can be a two byte load
+ 1327 + + // and a single comparison. We lose error information,
+ 1328 + + // but it's faster.
+ 1329 + +3590 if(BOOST_JSON_UNLIKELY(*cs != '\\'))
+ 1330 + + {
+ 1331 + + // If the next character is not a backslash and
+ 1332 + + // the parser does not allow it, return a syntax error.
+ 1333 + +156 if(!allow_bad_utf16)
+ 1334 + + {
+ 1335 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1336 + + = BOOST_CURRENT_LOCATION;
+ 1337 + +15 return fail(cs.begin(), error::syntax, &loc);
+ 1338 + + }
+ 1339 + + // Otherwise, append the Unicode replacement character since
+ 1340 + + // the first code point is a valid leading surrogate
+ 1341 + + else
+ 1342 + + {
+ 1343 + +141 temp.append_utf8(urc);
+ 1344 + +141 break;
+ 1345 + + }
+ 1346 + + }
+ 1347 + +3434 ++cs;
+ 1348 + +3434 if(BOOST_JSON_UNLIKELY(*cs != 'u'))
+ 1349 + + {
+ 1350 + +220 if (!allow_bad_utf16)
+ 1351 + + {
+ 1352 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1353 + + = BOOST_CURRENT_LOCATION;
+ 1354 + +15 return fail(cs.begin(), error::syntax, &loc);
+ 1355 + + }
+ 1356 + + // Otherwise, append the Unicode replacement character since
+ 1357 + + // the first code point is a valid leading surrogate
+ 1358 + + else
+ 1359 + + {
+ 1360 + +205 temp.append_utf8(urc);
+ 1361 + +205 goto do_str3;
+ 1362 + + }
+ 1363 + + }
+ 1364 + +3214 ++cs;
+ 1365 + +3214 digit = detail::load_little_endian<4>(cs.begin());
+ 1366 + +3214 d4 = detail::hex_digit(static_cast<
+ 1367 + +3214 unsigned char>(digit >> 24));
+ 1368 + +3214 d3 = detail::hex_digit(static_cast<
+ 1369 + +3214 unsigned char>(digit >> 16));
+ 1370 + +3214 d2 = detail::hex_digit(static_cast<
+ 1371 + +3214 unsigned char>(digit >> 8));
+ 1372 + +3214 d1 = detail::hex_digit(static_cast<
+ 1373 + + unsigned char>(digit));
+ 1374 + +3214 if(BOOST_JSON_UNLIKELY(
+ 1375 + + (d1 | d2 | d3 | d4) == -1))
+ 1376 + + {
+ 1377 + +90 if(d1 != -1)
+ 1378 + +75 ++cs;
+ 1379 + +90 if(d2 != -1)
+ 1380 + +45 ++cs;
+ 1381 + +90 if(d3 != -1)
+ 1382 + +15 ++cs;
+ 1383 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1384 + + = BOOST_CURRENT_LOCATION;
+ 1385 + +90 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1386 + + }
+ 1387 + +3124 unsigned u2 =
+ 1388 + +3124 (d1 << 12) + (d2 << 8) +
+ 1389 + +3124 (d3 << 4) + d4;
+ 1390 + + // Check if the second code point is a valid trailing surrogate.
+ 1391 + + // Valid trailing surrogates are [DC00, DFFF]
+ 1392 + +3124 if(BOOST_JSON_UNLIKELY(
+ 1393 + + u2 < 0xdc00 || u2 > 0xdfff))
+ 1394 + + {
+ 1395 + + // If not valid and the parser does not allow it, return an error.
+ 1396 + +1353 if(!allow_bad_utf16)
+ 1397 + + {
+ 1398 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1399 + + = BOOST_CURRENT_LOCATION;
+ 1400 + +136 return fail(cs.begin(), error::illegal_trailing_surrogate,
+ 1401 + +136 &loc);
+ 1402 + + }
+ 1403 + + // Append the replacement character for the
+ 1404 + + // first leading surrogate.
+ 1405 + +1217 cs += 4;
+ 1406 + +1217 temp.append_utf8(urc);
+ 1407 + + // Check if the second code point is a
+ 1408 + + // valid unicode scalar value (invalid leading
+ 1409 + + // or trailing surrogate)
+ 1410 + +1217 if (u2 < 0xd800 || u2 > 0xdbff)
+ 1411 + + {
+ 1412 + +524 temp.append_utf8(u2);
+ 1413 + +524 break;
+ 1414 + + }
+ 1415 + + // If it is a valid leading surrogate
+ 1416 + + else
+ 1417 + + {
+ 1418 + +693 u1_ = u2;
+ 1419 + +693 goto do_sur1;
+ 1420 + + }
+ 1421 + + }
+ 1422 + +1771 cs += 4;
+ 1423 + + // Calculate the Unicode code point from the surrogate pair and
+ 1424 + + // append the UTF-8 representation.
+ 1425 + +1771 unsigned cp =
+ 1426 + +1771 ((u1 - 0xd800) << 10) +
+ 1427 + + ((u2 - 0xdc00)) +
+ 1428 + + 0x10000;
+ 1429 + + // utf-16 surrogate pair
+ 1430 + +1771 temp.append_utf8(cp);
+ 1431 + +1771 break;
+ 1432 + + }
+ 1433 + + // flush
+ 1434 + +5991 if(BOOST_JSON_LIKELY(! temp.empty()))
+ 1435 + + {
+ 1436 + +3 BOOST_ASSERT(total <= max_size);
+ 1437 + +1722 if(BOOST_JSON_UNLIKELY(
+ 1438 + + temp.size() > max_size - total))
+ 1439 + + {
+ 1440 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1441 + + = BOOST_CURRENT_LOCATION;
+ 1442 + + return fail(cs.begin(), ev_too_large, &loc);
+ 1443 + + }
+ 1444 + +1722 total += temp.size();
+ 1445 + + {
+ 1446 + +1582 bool r = is_key
+ 1447 + +1722 ? h_.on_key_part(temp.get(), total, ec_)
+ 1448 + +1722 : h_.on_string_part(temp.get(), total, ec_);
+ 1449 + +
+ 1450 + +1582 if(BOOST_JSON_UNLIKELY(!r))
+ 1451 + + {
+ 1452 + +140 return fail(cs.begin());
+ 1453 + + }
+ 1454 + + }
+ 1455 + +1442 temp.clear();
+ 1456 + +1442 cs.clip(temp.max_size());
+ 1457 + + }
+ 1458 + +5711 ++cs;
+ 1459 + + // utf-16 escape
+ 1460 + +6103 do_str4:
+ 1461 + +6103 if(BOOST_JSON_UNLIKELY(! cs))
+ 1462 + +392 return maybe_suspend(cs.begin(), state::str4);
+ 1463 + +5711 digit = detail::hex_digit(*cs);
+ 1464 + +5711 if(BOOST_JSON_UNLIKELY(digit == -1))
+ 1465 + + {
+ 1466 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1467 + + = BOOST_CURRENT_LOCATION;
+ 1468 + +50 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1469 + + }
+ 1470 + +5661 ++cs;
+ 1471 + +5661 u1_ = digit << 12;
+ 1472 + +6051 do_str5:
+ 1473 + +6051 if(BOOST_JSON_UNLIKELY(! cs))
+ 1474 + +390 return maybe_suspend(cs.begin(), state::str5);
+ 1475 + +5661 digit = detail::hex_digit(*cs);
+ 1476 + +5661 if(BOOST_JSON_UNLIKELY(digit == -1))
+ 1477 + + {
+ 1478 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1479 + + = BOOST_CURRENT_LOCATION;
+ 1480 + +20 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1481 + + }
+ 1482 + +5641 ++cs;
+ 1483 + +5641 u1_ += digit << 8;
+ 1484 + +6030 do_str6:
+ 1485 + +6030 if(BOOST_JSON_UNLIKELY(! cs))
+ 1486 + +389 return maybe_suspend(cs.begin(), state::str6);
+ 1487 + +5641 digit = detail::hex_digit(*cs);
+ 1488 + +5641 if(BOOST_JSON_UNLIKELY(digit == -1))
+ 1489 + + {
+ 1490 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1491 + + = BOOST_CURRENT_LOCATION;
+ 1492 + +20 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1493 + + }
+ 1494 + +5621 ++cs;
+ 1495 + +5621 u1_ += digit << 4;
+ 1496 + +6007 do_str7:
+ 1497 + +6007 if(BOOST_JSON_UNLIKELY(! cs))
+ 1498 + +386 return maybe_suspend(cs.begin(), state::str7);
+ 1499 + +5621 digit = detail::hex_digit(*cs);
+ 1500 + +5621 if(BOOST_JSON_UNLIKELY(digit == -1))
+ 1501 + + {
+ 1502 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1503 + + = BOOST_CURRENT_LOCATION;
+ 1504 + +35 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1505 + + }
+ 1506 + +5586 ++cs;
+ 1507 + +5586 u1_ += digit;
+ 1508 + +5586 if(BOOST_JSON_LIKELY(
+ 1509 + + u1_ < 0xd800 || u1_ > 0xdfff))
+ 1510 + + {
+ 1511 + +1434 BOOST_ASSERT(temp.empty());
+ 1512 + + // utf-8 codepoint
+ 1513 + +1434 temp.append_utf8(u1_);
+ 1514 + +1434 break;
+ 1515 + + }
+ 1516 + +4152 if(BOOST_JSON_UNLIKELY(u1_ > 0xdbff))
+ 1517 + + {
+ 1518 + + // If it's an illegal leading surrogate and
+ 1519 + + // the parser does not allow it, return an error.
+ 1520 + +1585 if(!allow_bad_utf16)
+ 1521 + + {
+ 1522 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1523 + + = BOOST_CURRENT_LOCATION;
+ 1524 + +209 return fail(cs.begin(), error::illegal_leading_surrogate, &loc);
+ 1525 + + }
+ 1526 + + // Otherwise, append the Unicode replacement character
+ 1527 + + else
+ 1528 + + {
+ 1529 + +1376 BOOST_ASSERT(temp.empty());
+ 1530 + +1376 temp.append_utf8(urc);
+ 1531 + +1376 break;
+ 1532 + + }
+ 1533 + + }
+ 1534 + +2567 do_sur1:
+ 1535 + +3792 if(BOOST_JSON_UNLIKELY(! cs))
+ 1536 + +232 return maybe_suspend(cs.begin(), state::sur1);
+ 1537 + +3560 if(BOOST_JSON_UNLIKELY(*cs != '\\'))
+ 1538 + + {
+ 1539 + + // If the next character is not a backslash and
+ 1540 + + // the parser does not allow it, return a syntax error.
+ 1541 + +952 if(!allow_bad_utf16)
+ 1542 + + {
+ 1543 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1544 + + = BOOST_CURRENT_LOCATION;
+ 1545 + +149 return fail(cs.begin(), error::syntax, &loc);
+ 1546 + + }
+ 1547 + + // Otherwise, append the Unicode replacement character since
+ 1548 + + // the first code point is a valid leading surrogate
+ 1549 + + else
+ 1550 + + {
+ 1551 + +803 temp.append_utf8(urc);
+ 1552 + +803 break;
+ 1553 + + }
+ 1554 + + }
+ 1555 + +2608 ++cs;
+ 1556 + +2796 do_sur2:
+ 1557 + +2796 if(BOOST_JSON_UNLIKELY(! cs))
+ 1558 + +188 return maybe_suspend(cs.begin(), state::sur2);
+ 1559 + +2608 if(BOOST_JSON_UNLIKELY(*cs != 'u'))
+ 1560 + + {
+ 1561 + +396 if (!allow_bad_utf16)
+ 1562 + + {
+ 1563 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1564 + + = BOOST_CURRENT_LOCATION;
+ 1565 + +65 return fail(cs.begin(), error::syntax, &loc);
+ 1566 + + }
+ 1567 + + // Otherwise, append the Unicode replacement character since
+ 1568 + + // the first code point is a valid leading surrogate
+ 1569 + + else
+ 1570 + + {
+ 1571 + +331 temp.append_utf8(urc);
+ 1572 + +331 goto do_str3;
+ 1573 + + }
+ 1574 + + }
+ 1575 + +2212 ++cs;
+ 1576 + +2376 do_sur3:
+ 1577 + +2376 if(BOOST_JSON_UNLIKELY(! cs))
+ 1578 + +164 return maybe_suspend(cs.begin(), state::sur3);
+ 1579 + +2212 digit = detail::hex_digit(*cs);
+ 1580 + +2212 if(BOOST_JSON_UNLIKELY(digit == -1))
+ 1581 + + {
+ 1582 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1583 + + = BOOST_CURRENT_LOCATION;
+ 1584 + +35 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1585 + + }
+ 1586 + +2177 ++cs;
+ 1587 + +2177 u2_ = digit << 12;
+ 1588 + +2339 do_sur4:
+ 1589 + +2339 if(BOOST_JSON_UNLIKELY(! cs))
+ 1590 + +162 return maybe_suspend(cs.begin(), state::sur4);
+ 1591 + +2177 digit = detail::hex_digit(*cs);
+ 1592 + +2177 if(BOOST_JSON_UNLIKELY(digit == -1))
+ 1593 + + {
+ 1594 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1595 + + = BOOST_CURRENT_LOCATION;
+ 1596 + +35 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1597 + + }
+ 1598 + +2142 ++cs;
+ 1599 + +2142 u2_ += digit << 8;
+ 1600 + +2302 do_sur5:
+ 1601 + +2302 if(BOOST_JSON_UNLIKELY(! cs))
+ 1602 + +160 return maybe_suspend(cs.begin(), state::sur5);
+ 1603 + +2142 digit = detail::hex_digit(*cs);
+ 1604 + +2142 if(BOOST_JSON_UNLIKELY(digit == -1))
+ 1605 + + {
+ 1606 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1607 + + = BOOST_CURRENT_LOCATION;
+ 1608 + +20 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1609 + + }
+ 1610 + +2122 ++cs;
+ 1611 + +2122 u2_ += digit << 4;
+ 1612 + +2280 do_sur6:
+ 1613 + +2280 if(BOOST_JSON_UNLIKELY(! cs))
+ 1614 + +158 return maybe_suspend(cs.begin(), state::sur6);
+ 1615 + +2122 digit = detail::hex_digit(*cs);
+ 1616 + +2122 if(BOOST_JSON_UNLIKELY(digit == -1))
+ 1617 + + {
+ 1618 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1619 + + = BOOST_CURRENT_LOCATION;
+ 1620 + +20 return fail(cs.begin(), error::expected_hex_digit, &loc);
+ 1621 + + }
+ 1622 + +2102 ++cs;
+ 1623 + +2102 u2_ += digit;
+ 1624 + + // Check if the second code point is a valid trailing surrogate.
+ 1625 + + // Valid trailing surrogates are [DC00, DFFF]
+ 1626 + +2102 if(BOOST_JSON_UNLIKELY(
+ 1627 + + u2_ < 0xdc00 || u2_ > 0xdfff))
+ 1628 + + {
+ 1629 + + // If not valid and the parser does not allow it, return an error.
+ 1630 + +580 if(!allow_bad_utf16)
+ 1631 + + {
+ 1632 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1633 + + = BOOST_CURRENT_LOCATION;
+ 1634 + +60 return fail(cs.begin(), error::illegal_trailing_surrogate, &loc);
+ 1635 + + }
+ 1636 + + // Append the replacement character for the
+ 1637 + + // first leading surrogate.
+ 1638 + +520 temp.append_utf8(urc);
+ 1639 + + // Check if the second code point is a
+ 1640 + + // valid unicode scalar value (invalid leading
+ 1641 + + // or trailing surrogate)
+ 1642 + +520 if (u2_ < 0xd800 || u2_ > 0xdbff)
+ 1643 + + {
+ 1644 + +220 temp.append_utf8(u2_);
+ 1645 + +220 break;
+ 1646 + + }
+ 1647 + + // If it is a valid leading surrogate
+ 1648 + + else
+ 1649 + + {
+ 1650 + +300 u1_ = u2_;
+ 1651 + +300 goto do_sur1;
+ 1652 + + }
+ 1653 + + }
+ 1654 + + // Calculate the Unicode code point from the surrogate pair and
+ 1655 + + // append the UTF-8 representation.
+ 1656 + +1522 unsigned cp =
+ 1657 + +1522 ((u1_ - 0xd800) << 10) +
+ 1658 + +1522 ((u2_ - 0xdc00)) +
+ 1659 + + 0x10000;
+ 1660 + + // utf-16 surrogate pair
+ 1661 + +1522 temp.append_utf8(cp);
+ 1662 + + }
+ 1663 + +
+ 1664 + + // flush
+ 1665 + +12650 if(BOOST_JSON_UNLIKELY( !cs ) || *cs != '\\')
+ 1666 + +8869 break;
+ 1667 + + }
+ 1668 + +
+ 1669 + +8869 if(BOOST_JSON_LIKELY( temp.size() ))
+ 1670 + + {
+ 1671 + +433 BOOST_ASSERT(total <= max_size);
+ 1672 + +8869 if(BOOST_JSON_UNLIKELY( temp.size() > max_size - total ))
+ 1673 + + {
+ 1674 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1675 + + = BOOST_CURRENT_LOCATION;
+ 1676 + + return fail(cs.begin(), ev_too_large, &loc);
+ 1677 + + }
+ 1678 + +
+ 1679 + +8869 total += temp.size();
+ 1680 + +8056 bool const r = is_key
+ 1681 + +8869 ? h_.on_key_part(temp.get(), total, ec_)
+ 1682 + +8152 : h_.on_string_part(temp.get(), total, ec_);
+ 1683 + +8056 if(BOOST_JSON_UNLIKELY( !r ))
+ 1684 + +813 return fail( cs.begin() );
+ 1685 + + }
+ 1686 + +
+ 1687 + +7243 return cs.begin();
+ 1688 + + }
+ 1689 + +
+ 1690 + + //----------------------------------------------------------
+ 1691 + +
+ 1692 + + template<class Handler>
+ 1693 + + template<
+ 1694 + + bool StackEmpty_,
+ 1695 + + bool AllowComments_/*,
+ 1696 + + bool AllowTrailing_,
+ 1697 + + bool AllowBadUTF8_*/>
+ 1698 + + const char*
+ 1699 + +109175 basic_parser<Handler>::
+ 1700 + + parse_object(const char* p,
+ 1701 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 1702 + + std::integral_constant<bool, AllowComments_> allow_comments,
+ 1703 + + /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
+ 1704 + + /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
+ 1705 + + bool allow_bad_utf16)
+ 1706 + + {
+ 1707 + +109175 detail::const_stream_wrapper cs(p, end_);
+ 1708 + + std::size_t size;
+ 1709 + +109175 if(! stack_empty && ! st_.empty())
+ 1710 + + {
+ 1711 + + // resume
+ 1712 + + state st;
+ 1713 + +35047 st_.pop(st);
+ 1714 + +35047 st_.pop(size);
+ 1715 + +35047 switch(st)
+ 1716 + + {
+ 1717 + + default: BOOST_JSON_UNREACHABLE();
+ 1718 + +1595 case state::obj1: goto do_obj1;
+ 1719 + +235 case state::obj2: goto do_obj2;
+ 1720 + +12640 case state::obj3: goto do_obj3;
+ 1721 + +1690 case state::obj4: goto do_obj4;
+ 1722 + +251 case state::obj5: goto do_obj5;
+ 1723 + +1591 case state::obj6: goto do_obj6;
+ 1724 + +15444 case state::obj7: goto do_obj7;
+ 1725 + +426 case state::obj8: goto do_obj8;
+ 1726 + +660 case state::obj9: goto do_obj9;
+ 1727 + +181 case state::obj10: goto do_obj10;
+ 1728 + +334 case state::obj11: goto do_obj11;
+ 1729 + + }
+ 1730 + + }
+ 1731 + +74128 BOOST_ASSERT(*cs == '{');
+ 1732 + +74128 size = 0;
+ 1733 + +74128 if(BOOST_JSON_UNLIKELY(! depth_))
+ 1734 + + {
+ 1735 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 1736 + +3 return fail(cs.begin(), error::too_deep, &loc);
+ 1737 + + }
+ 1738 + +74125 --depth_;
+ 1739 + +74125 if(BOOST_JSON_UNLIKELY(
+ 1740 + + ! h_.on_object_begin(ec_)))
+ 1741 + +2040 return fail(cs.begin());
+ 1742 + +70047 ++cs;
+ 1743 + + // object:
+ 1744 + + // '{' *ws '}'
+ 1745 + + // '{' *ws string *ws ':' *ws value *ws *[ ',' *ws string *ws ':' *ws value *ws ] '}'
+ 1746 + +73613 do_obj1:
+ 1747 + +73613 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 1748 + +73613 if(BOOST_JSON_UNLIKELY(! cs))
+ 1749 + +1629 return maybe_suspend(cs.begin(), state::obj1, size);
+ 1750 + +71984 if(BOOST_JSON_LIKELY(*cs != '}'))
+ 1751 + + {
+ 1752 + +69085 if(BOOST_JSON_UNLIKELY(*cs != '\x22'))
+ 1753 + + {
+ 1754 + +2411 if(allow_comments && *cs == '/')
+ 1755 + + {
+ 1756 + +2139 do_obj2:
+ 1757 + +2374 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
+ 1758 + +2290 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 1759 + +319 return suspend_or_fail(state::obj2, size);
+ 1760 + +1971 goto do_obj1;
+ 1761 + + }
+ 1762 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1763 + + = BOOST_CURRENT_LOCATION;
+ 1764 + +272 return fail(cs.begin(), error::syntax, &loc);
+ 1765 + + }
+ 1766 + +66674 loop:
+ 1767 + +80826 if(BOOST_JSON_UNLIKELY(++size >
+ 1768 + + Handler::max_object_size))
+ 1769 + + {
+ 1770 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1771 + + = BOOST_CURRENT_LOCATION;
+ 1772 + +1 return fail(cs.begin(), error::object_too_large, &loc);
+ 1773 + + }
+ 1774 + +80825 do_obj3:
+ 1775 + +93465 cs = parse_string(cs.begin(), stack_empty, std::true_type(), allow_bad_utf8, allow_bad_utf16);
+ 1776 + +90509 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 1777 + +15584 return suspend_or_fail(state::obj3, size);
+ 1778 + +74925 do_obj4:
+ 1779 + +79086 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 1780 + +79086 if(BOOST_JSON_UNLIKELY(! cs))
+ 1781 + +1705 return maybe_suspend(cs.begin(), state::obj4, size);
+ 1782 + +77381 if(BOOST_JSON_UNLIKELY(*cs != ':'))
+ 1783 + + {
+ 1784 + +2925 if(allow_comments && *cs == '/')
+ 1785 + + {
+ 1786 + +2779 do_obj5:
+ 1787 + +3030 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
+ 1788 + +2876 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 1789 + +405 return suspend_or_fail(state::obj5, size);
+ 1790 + +2471 goto do_obj4;
+ 1791 + + }
+ 1792 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1793 + + = BOOST_CURRENT_LOCATION;
+ 1794 + +146 return fail(cs.begin(), error::syntax, &loc);
+ 1795 + + }
+ 1796 + +74456 ++cs;
+ 1797 + +76047 do_obj6:
+ 1798 + +76047 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 1799 + +76047 if(BOOST_JSON_UNLIKELY(! cs))
+ 1800 + +1621 return maybe_suspend(cs.begin(), state::obj6, size);
+ 1801 + +74426 do_obj7:
+ 1802 + +89870 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 1803 + +82521 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 1804 + +23589 return suspend_or_fail(state::obj7, size);
+ 1805 + +58932 do_obj8:
+ 1806 + +61194 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 1807 + +61194 if(BOOST_JSON_UNLIKELY(! cs))
+ 1808 + +441 return maybe_suspend(cs.begin(), state::obj8, size);
+ 1809 + +60753 if(BOOST_JSON_LIKELY(*cs == ','))
+ 1810 + + {
+ 1811 + +17792 ++cs;
+ 1812 + +19707 do_obj9:
+ 1813 + +19707 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 1814 + +19707 if(BOOST_JSON_UNLIKELY(! cs))
+ 1815 + +690 return maybe_suspend(cs.begin(), state::obj9, size);
+ 1816 + +
+ 1817 + + // loop for next element
+ 1818 + +19017 if(BOOST_JSON_LIKELY(*cs == '\x22'))
+ 1819 + +14152 goto loop;
+ 1820 + +4865 if(! allow_trailing || *cs != '}')
+ 1821 + + {
+ 1822 + +1644 if(allow_comments && *cs == '/')
+ 1823 + + {
+ 1824 + +1433 do_obj10:
+ 1825 + +1614 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
+ 1826 + +1525 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 1827 + +270 return suspend_or_fail(state::obj10, size);
+ 1828 + +1255 goto do_obj9;
+ 1829 + + }
+ 1830 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1831 + + = BOOST_CURRENT_LOCATION;
+ 1832 + +211 return fail(cs.begin(), error::syntax, &loc);
+ 1833 + + }
+ 1834 + + }
+ 1835 + +42961 else if(BOOST_JSON_UNLIKELY(*cs != '}'))
+ 1836 + + {
+ 1837 + +2325 if(allow_comments && *cs == '/')
+ 1838 + + {
+ 1839 + +2172 do_obj11:
+ 1840 + +2506 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
+ 1841 + +2338 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 1842 + +502 return suspend_or_fail(state::obj11, size);
+ 1843 + +1836 goto do_obj8;
+ 1844 + + }
+ 1845 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1846 + + = BOOST_CURRENT_LOCATION;
+ 1847 + +153 return fail(cs.begin(), error::syntax, &loc);
+ 1848 + + }
+ 1849 + + // got closing brace, fall through
+ 1850 + + }
+ 1851 + +46756 if(BOOST_JSON_UNLIKELY(
+ 1852 + + ! h_.on_object_end(size, ec_)))
+ 1853 + +1502 return fail(cs.begin());
+ 1854 + +43713 ++depth_;
+ 1855 + +43713 ++cs;
+ 1856 + +43713 return cs.begin();
+ 1857 + + }
+ 1858 + +
+ 1859 + + //----------------------------------------------------------
+ 1860 + +
+ 1861 + + template<class Handler>
+ 1862 + + template<
+ 1863 + + bool StackEmpty_,
+ 1864 + + bool AllowComments_/*,
+ 1865 + + bool AllowTrailing_,
+ 1866 + + bool AllowBadUTF8_*/>
+ 1867 + + const char*
+ 1868 + +26334 basic_parser<Handler>::
+ 1869 + + parse_array(const char* p,
+ 1870 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 1871 + + std::integral_constant<bool, AllowComments_> allow_comments,
+ 1872 + + /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
+ 1873 + + /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
+ 1874 + + bool allow_bad_utf16)
+ 1875 + + {
+ 1876 + +26334 detail::const_stream_wrapper cs(p, end_);
+ 1877 + + std::size_t size;
+ 1878 + +26334 if(! stack_empty && ! st_.empty())
+ 1879 + + {
+ 1880 + + // resume
+ 1881 + + state st;
+ 1882 + +5716 st_.pop(st);
+ 1883 + +5716 st_.pop(size);
+ 1884 + +5716 switch(st)
+ 1885 + + {
+ 1886 + + default: BOOST_JSON_UNREACHABLE();
+ 1887 + +1052 case state::arr1: goto do_arr1;
+ 1888 + +384 case state::arr2: goto do_arr2;
+ 1889 + +2924 case state::arr3: goto do_arr3;
+ 1890 + +391 case state::arr4: goto do_arr4;
+ 1891 + +671 case state::arr5: goto do_arr5;
+ 1892 + +294 case state::arr6: goto do_arr6;
+ 1893 + + }
+ 1894 + + }
+ 1895 + +20618 BOOST_ASSERT(*cs == '[');
+ 1896 + +20618 size = 0;
+ 1897 + +20618 if(BOOST_JSON_UNLIKELY(! depth_))
+ 1898 + + {
+ 1899 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 1900 + +34 return fail(cs.begin(), error::too_deep, &loc);
+ 1901 + + }
+ 1902 + +20584 --depth_;
+ 1903 + +20584 if(BOOST_JSON_UNLIKELY(
+ 1904 + + ! h_.on_array_begin(ec_)))
+ 1905 + +812 return fail(cs.begin());
+ 1906 + +18966 ++cs;
+ 1907 + + // array:
+ 1908 + + // '[' *ws ']'
+ 1909 + + // '[' *ws value *ws *[ ',' *ws value *ws ] ']'
+ 1910 + +21551 do_arr1:
+ 1911 + +21551 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 1912 + +21551 if(BOOST_JSON_UNLIKELY(! cs))
+ 1913 + +1073 return maybe_suspend(cs.begin(), state::arr1, size);
+ 1914 + +20478 if(BOOST_JSON_LIKELY(*cs != ']'))
+ 1915 + + {
+ 1916 + +18730 loop:
+ 1917 + +26193 if(allow_comments && *cs == '/')
+ 1918 + + {
+ 1919 + +1789 do_arr2:
+ 1920 + +2173 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
+ 1921 + +2045 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 1922 + +512 return suspend_or_fail(state::arr2, size);
+ 1923 + +1533 goto do_arr1;
+ 1924 + + }
+ 1925 + +24404 if(BOOST_JSON_UNLIKELY(++size >
+ 1926 + + Handler::max_array_size))
+ 1927 + + {
+ 1928 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1929 + + = BOOST_CURRENT_LOCATION;
+ 1930 + +1 return fail(cs.begin(), error::array_too_large, &loc);
+ 1931 + + }
+ 1932 + +24403 do_arr3:
+ 1933 + + // array is not empty, value required
+ 1934 + +27327 cs = parse_value(cs.begin(), stack_empty, allow_comments, allow_trailing, allow_bad_utf8, allow_bad_utf16);
+ 1935 + +24696 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 1936 + +9038 return suspend_or_fail(state::arr3, size);
+ 1937 + +15658 do_arr4:
+ 1938 + +17279 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 1939 + +17279 if(BOOST_JSON_UNLIKELY(! cs))
+ 1940 + +500 return maybe_suspend(cs.begin(), state::arr4, size);
+ 1941 + +16779 if(BOOST_JSON_LIKELY(*cs == ','))
+ 1942 + + {
+ 1943 + +9176 ++cs;
+ 1944 + +9847 do_arr5:
+ 1945 + +9847 cs = detail::count_whitespace(cs.begin(), cs.end());
+ 1946 + +9847 if(BOOST_JSON_UNLIKELY(! cs))
+ 1947 + +701 return maybe_suspend(cs.begin(), state::arr5, size);
+ 1948 + + // loop for next element
+ 1949 + +9146 if(! allow_trailing || *cs != ']')
+ 1950 + +7463 goto loop;
+ 1951 + + }
+ 1952 + +7603 else if(BOOST_JSON_UNLIKELY(*cs != ']'))
+ 1953 + + {
+ 1954 + +1969 if(allow_comments && *cs == '/')
+ 1955 + + {
+ 1956 + +1541 do_arr6:
+ 1957 + +1835 cs = parse_comment(cs.begin(), stack_empty, std::false_type());
+ 1958 + +1688 if(BOOST_JSON_UNLIKELY(incomplete(cs)))
+ 1959 + +458 return suspend_or_fail(state::arr6, size);
+ 1960 + +1230 goto do_arr4;
+ 1961 + + }
+ 1962 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 1963 + + = BOOST_CURRENT_LOCATION;
+ 1964 + +428 return fail(cs.begin(), error::syntax, &loc);
+ 1965 + + }
+ 1966 + + // got closing bracket; fall through
+ 1967 + + }
+ 1968 + +9065 if(BOOST_JSON_UNLIKELY(
+ 1969 + + ! h_.on_array_end(size, ec_)))
+ 1970 + +547 return fail(cs.begin());
+ 1971 + +7939 ++depth_;
+ 1972 + +7939 ++cs;
+ 1973 + +7939 return cs.begin();
+ 1974 + + }
+ 1975 + +
+ 1976 + + //----------------------------------------------------------
+ 1977 + +
+ 1978 + + template<class Handler>
+ 1979 + + template<bool StackEmpty_, char First_, number_precision Numbers_>
+ 1980 + + const char*
+ 1981 + +2126871 basic_parser<Handler>::
+ 1982 + + parse_number(const char* p,
+ 1983 + + std::integral_constant<bool, StackEmpty_> stack_empty,
+ 1984 + + std::integral_constant<char, First_> first,
+ 1985 + + std::integral_constant<number_precision, Numbers_> mode)
+ 1986 + + {
+ 1987 + +2126871 constexpr bool precise_parsing = mode == number_precision::precise;
+ 1988 + +2126871 constexpr bool no_parsing = mode == number_precision::none;
+ 1989 + +
+ 1990 + + // only one of these will be true if we are not resuming
+ 1991 + + // if negative then !zero_first && !nonzero_first
+ 1992 + + // if zero_first then !nonzero_first && !negative
+ 1993 + + // if nonzero_first then !zero_first && !negative
+ 1994 + +2126871 bool const negative = first == '-';
+ 1995 + +2126871 bool const zero_first = first == '0';
+ 1996 + +2126871 bool const nonzero_first = first == '+';
+ 1997 + +2126871 detail::const_stream_wrapper cs(p, end_);
+ 1998 + + number num;
+ 1999 + +2126871 const char* begin = cs.begin();
+ 2000 + +2126871 if(stack_empty || st_.empty())
+ 2001 + + {
+ 2002 + +2089697 num.bias = 0;
+ 2003 + +2089697 num.exp = 0;
+ 2004 + +2089697 num.frac = false;
+ 2005 + +2089697 num_buf_.clear();
+ 2006 + +
+ 2007 + + //----------------------------------
+ 2008 + + //
+ 2009 + + // '-'
+ 2010 + + // leading minus sign
+ 2011 + + //
+ 2012 + +2089697 BOOST_ASSERT(cs);
+ 2013 + + if(negative)
+ 2014 + +25178 ++cs;
+ 2015 + +
+ 2016 + +2089697 num.neg = negative;
+ 2017 + +2089697 num.frac = false;
+ 2018 + +2089697 num.exp = 0;
+ 2019 + +2089697 num.bias = 0;
+ 2020 + +
+ 2021 + + // fast path
+ 2022 + +2089697 if( cs.remain() >= 16 + 1 + 16 ) // digits . digits
+ 2023 + + {
+ 2024 + + int n1;
+ 2025 + +
+ 2026 + +9988 if( nonzero_first ||
+ 2027 + +9988 (negative && *cs != '0') )
+ 2028 + + {
+ 2029 + +2007317 n1 = detail::count_digits( cs.begin() );
+ 2030 + +2007317 BOOST_ASSERT(n1 >= 0 && n1 <= 16);
+ 2031 + +
+ 2032 + +1836 if( negative && n1 == 0 && opt_.allow_infinity_and_nan )
+ 2033 + + {
+ 2034 + +9 return parse_literal(
+ 2035 + + p - 1,
+ 2036 + +8 detail::literals_c<detail::literals::neg_infinity>());
+ 2037 + + }
+ 2038 + +
+ 2039 + +1827 if( ! nonzero_first && n1 == 0 )
+ 2040 + + {
+ 2041 + + // digit required
+ 2042 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2043 + + = BOOST_CURRENT_LOCATION;
+ 2044 + +2 return fail(cs.begin(), error::syntax, &loc);
+ 2045 + + }
+ 2046 + +
+ 2047 + + BOOST_IF_CONSTEXPR( !no_parsing )
+ 2048 + +2006458 num.mant = detail::parse_unsigned( 0, cs.begin(), n1 );
+ 2049 + + else
+ 2050 + +848 num.mant = 0;
+ 2051 + +
+ 2052 + +2007306 cs += n1;
+ 2053 + +
+ 2054 + + // integer or floating-point with
+ 2055 + + // >= 16 leading digits
+ 2056 + +2007306 if( n1 == 16 )
+ 2057 + + {
+ 2058 + +2001424 goto do_num2;
+ 2059 + + }
+ 2060 + + }
+ 2061 + + else
+ 2062 + + {
+ 2063 + + // 0. floating-point or 0e integer
+ 2064 + +21187 num.mant = 0;
+ 2065 + +21187 n1 = 0;
+ 2066 + +21187 ++cs;
+ 2067 + + }
+ 2068 + +
+ 2069 + + {
+ 2070 + +27069 const char c = *cs;
+ 2071 + +27069 if(c != '.')
+ 2072 + + {
+ 2073 + +9870 if((c | 32) == 'e')
+ 2074 + + {
+ 2075 + +6576 ++cs;
+ 2076 + +6576 goto do_exp1;
+ 2077 + + }
+ 2078 + + BOOST_IF_CONSTEXPR( negative && !no_parsing )
+ 2079 + +19 num.mant = ~num.mant + 1;
+ 2080 + +3294 goto finish_signed;
+ 2081 + + }
+ 2082 + + }
+ 2083 + +
+ 2084 + + // floating-point number
+ 2085 + +
+ 2086 + +17199 ++cs;
+ 2087 + +
+ 2088 + +17199 int n2 = detail::count_digits( cs.begin() );
+ 2089 + +17199 BOOST_ASSERT(n2 >= 0 && n2 <= 16);
+ 2090 + +
+ 2091 + +17199 if( n2 == 0 )
+ 2092 + + {
+ 2093 + + // digit required
+ 2094 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2095 + + = BOOST_CURRENT_LOCATION;
+ 2096 + +3 return fail(cs.begin(), error::syntax, &loc);
+ 2097 + + }
+ 2098 + +
+ 2099 + + // floating-point mantissa overflow
+ 2100 + +17196 if( n1 + n2 >= 19 )
+ 2101 + + {
+ 2102 + +122 goto do_num7;
+ 2103 + + }
+ 2104 + +
+ 2105 + + BOOST_IF_CONSTEXPR( !no_parsing )
+ 2106 + +12855 num.mant = detail::parse_unsigned( num.mant, cs.begin(), n2 );
+ 2107 + +
+ 2108 + +17074 BOOST_ASSERT(num.bias == 0);
+ 2109 + +
+ 2110 + +17074 num.bias -= n2;
+ 2111 + +
+ 2112 + +17074 cs += n2;
+ 2113 + +
+ 2114 + +17074 char ch = *cs;
+ 2115 + +
+ 2116 + +17074 if( (ch | 32) == 'e' )
+ 2117 + + {
+ 2118 + +110 ++cs;
+ 2119 + +110 goto do_exp1;
+ 2120 + + }
+ 2121 + +16964 else if( ch >= '0' && ch <= '9' )
+ 2122 + + {
+ 2123 + +10017 goto do_num8;
+ 2124 + + }
+ 2125 + +
+ 2126 + +6947 goto finish_dub;
+ 2127 + + }
+ 2128 + + }
+ 2129 + + else
+ 2130 + + {
+ 2131 + +37174 num = num_;
+ 2132 + + state st;
+ 2133 + +37174 st_.pop(st);
+ 2134 + +37174 switch(st)
+ 2135 + + {
+ 2136 + + default: BOOST_JSON_UNREACHABLE();
+ 2137 + +602 case state::num1: goto do_num1;
+ 2138 + +6338 case state::num2: goto do_num2;
+ 2139 + +802 case state::num3: goto do_num3;
+ 2140 + +52 case state::num4: goto do_num4;
+ 2141 + +4537 case state::num5: goto do_num5;
+ 2142 + +666 case state::num6: goto do_num6;
+ 2143 + +616 case state::num7: goto do_num7;
+ 2144 + +10944 case state::num8: goto do_num8;
+ 2145 + +469 case state::exp1: goto do_exp1;
+ 2146 + +125 case state::exp2: goto do_exp2;
+ 2147 + +12023 case state::exp3: goto do_exp3;
+ 2148 + + }
+ 2149 + + }
+ 2150 + +
+ 2151 + + //----------------------------------
+ 2152 + + //
+ 2153 + + // DIGIT
+ 2154 + + // first digit
+ 2155 + + //
+ 2156 + +61795 do_num1:
+ 2157 + +15792 if(zero_first || nonzero_first ||
+ 2158 + +15792 BOOST_JSON_LIKELY(cs))
+ 2159 + + {
+ 2160 + +61073 char const c = *cs;
+ 2161 + + if(zero_first)
+ 2162 + + {
+ 2163 + +9718 ++cs;
+ 2164 + +9718 num.mant = 0;
+ 2165 + +9718 goto do_num6;
+ 2166 + + }
+ 2167 + +15070 else if(nonzero_first || BOOST_JSON_LIKELY(
+ 2168 + + c >= '1' && c <= '9'))
+ 2169 + + {
+ 2170 + +42533 ++cs;
+ 2171 + +42533 num.mant = c - '0';
+ 2172 + + }
+ 2173 + +8822 else if(BOOST_JSON_UNLIKELY(
+ 2174 + + c == '0'))
+ 2175 + + {
+ 2176 + +7627 ++cs;
+ 2177 + +7627 num.mant = 0;
+ 2178 + +7627 goto do_num6;
+ 2179 + + }
+ 2180 + +1195 else if( (negative || num.neg) && opt_.allow_infinity_and_nan )
+ 2181 + + {
+ 2182 + +1007 st_.push(state::lit1);
+ 2183 + +1007 cur_lit_ = literal_index(detail::literals::neg_infinity);
+ 2184 + +1007 lit_offset_ = 1;
+ 2185 + +1007 return parse_literal(
+ 2186 + +961 cs.begin(), detail::literals_c<detail::literals::resume>() );
+ 2187 + + }
+ 2188 + + else
+ 2189 + + {
+ 2190 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2191 + + = BOOST_CURRENT_LOCATION;
+ 2192 + +188 return fail(cs.begin(), error::syntax, &loc);
+ 2193 + + }
+ 2194 + + }
+ 2195 + + else
+ 2196 + + {
+ 2197 + +722 if(BOOST_JSON_UNLIKELY(
+ 2198 + + ! h_.on_number_part(
+ 2199 + + {begin, cs.used(begin)}, ec_)))
+ 2200 + +60 return fail(cs.begin());
+ 2201 + +
+ 2202 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2203 + +64 num_buf_.append( begin, cs.used(begin) );
+ 2204 + +602 return maybe_suspend(
+ 2205 + +602 cs.begin(), state::num1, num);
+ 2206 + + }
+ 2207 + +
+ 2208 + + //----------------------------------
+ 2209 + + //
+ 2210 + + // 1*DIGIT
+ 2211 + + // significant digits left of decimal
+ 2212 + + //
+ 2213 + +2050295 do_num2:
+ 2214 + +2044036 if(negative || (!stack_empty && num.neg))
+ 2215 + + {
+ 2216 + +22400 for(;;)
+ 2217 + + {
+ 2218 + +30226 if(BOOST_JSON_UNLIKELY(! cs))
+ 2219 + + {
+ 2220 + +1921 if(BOOST_JSON_UNLIKELY(more_))
+ 2221 + + {
+ 2222 + +1469 if(BOOST_JSON_UNLIKELY(
+ 2223 + + ! h_.on_number_part(
+ 2224 + + {begin, cs.used(begin)}, ec_)))
+ 2225 + +69 return fail(cs.begin());
+ 2226 + +
+ 2227 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2228 + +32 num_buf_.append( begin, cs.used(begin) );
+ 2229 + +1331 return suspend(cs.begin(), state::num2, num);
+ 2230 + + }
+ 2231 + +452 goto finish_int;
+ 2232 + + }
+ 2233 + +28305 char const c = *cs;
+ 2234 + +28305 if(BOOST_JSON_LIKELY(
+ 2235 + + c >= '0' && c <= '9'))
+ 2236 + + {
+ 2237 + +23223 ++cs;
+ 2238 + + // 9223372036854775808 INT64_MIN
+ 2239 + +23223 if( num.mant > 922337203685477580 || (
+ 2240 + +22508 num.mant == 922337203685477580 && c > '8'))
+ 2241 + + break;
+ 2242 + + BOOST_IF_CONSTEXPR( !no_parsing )
+ 2243 + +22141 num.mant = 10 * num.mant + ( c - '0' );
+ 2244 + +22400 continue;
+ 2245 + + }
+ 2246 + +5082 goto do_num6; // [.eE]
+ 2247 + + }
+ 2248 + + }
+ 2249 + + else
+ 2250 + + {
+ 2251 + +6885037 for(;;)
+ 2252 + + {
+ 2253 + +8927506 if(BOOST_JSON_UNLIKELY(! cs))
+ 2254 + + {
+ 2255 + +6426 if(BOOST_JSON_UNLIKELY(more_))
+ 2256 + + {
+ 2257 + +5813 if(BOOST_JSON_UNLIKELY(
+ 2258 + + ! h_.on_number_part(
+ 2259 + + {begin, cs.used(begin)}, ec_)))
+ 2260 + +406 return fail(cs.begin());
+ 2261 + +
+ 2262 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2263 + +174 num_buf_.append( begin, cs.used(begin) );
+ 2264 + +5007 return suspend(cs.begin(), state::num2, num);
+ 2265 + + }
+ 2266 + +613 goto finish_int;
+ 2267 + + }
+ 2268 + +8921080 char const c = *cs;
+ 2269 + +8921080 if(BOOST_JSON_LIKELY(
+ 2270 + + c >= '0' && c <= '9'))
+ 2271 + + {
+ 2272 + +6888862 ++cs;
+ 2273 + + // 18446744073709551615 UINT64_MAX
+ 2274 + +6888862 if( num.mant > 1844674407370955161 || (
+ 2275 + +6885459 num.mant == 1844674407370955161 && c > '5'))
+ 2276 + + break;
+ 2277 + + BOOST_IF_CONSTEXPR( !no_parsing )
+ 2278 + +6879439 num.mant = 10 * num.mant + ( c - '0' );
+ 2279 + + }
+ 2280 + + else
+ 2281 + + {
+ 2282 + +2032218 goto do_num6; // [.eE]
+ 2283 + + }
+ 2284 + + }
+ 2285 + + }
+ 2286 + +4648 ++num.bias;
+ 2287 + +
+ 2288 + + //----------------------------------
+ 2289 + + //
+ 2290 + + // 1*DIGIT
+ 2291 + + // non-significant digits left of decimal
+ 2292 + + //
+ 2293 + +5450 do_num3:
+ 2294 + +11558 for(;;)
+ 2295 + + {
+ 2296 + +17008 if(BOOST_JSON_UNLIKELY(! cs))
+ 2297 + + {
+ 2298 + +1527 if(BOOST_JSON_UNLIKELY(more_))
+ 2299 + + {
+ 2300 + +894 if(BOOST_JSON_UNLIKELY(
+ 2301 + + ! h_.on_number_part(
+ 2302 + + {begin, cs.used(begin)}, ec_)))
+ 2303 + +46 return fail(cs.begin());
+ 2304 + +
+ 2305 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2306 + +12 num_buf_.append( begin, cs.used(begin) );
+ 2307 + +802 return suspend(cs.begin(), state::num3, num);
+ 2308 + + }
+ 2309 + +633 goto finish_dub;
+ 2310 + + }
+ 2311 + +15481 char const c = *cs;
+ 2312 + +15481 if(BOOST_JSON_UNLIKELY(
+ 2313 + + c >= '0' && c <= '9'))
+ 2314 + + {
+ 2315 + +11558 if(BOOST_JSON_UNLIKELY( num.bias + 1 == INT_MAX ))
+ 2316 + + {
+ 2317 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2318 + + = BOOST_CURRENT_LOCATION;
+ 2319 + + return fail(cs.begin(), error::exponent_overflow, &loc);
+ 2320 + + }
+ 2321 + +11558 ++cs;
+ 2322 + +11558 ++num.bias;
+ 2323 + + }
+ 2324 + +3923 else if(BOOST_JSON_LIKELY(
+ 2325 + + c == '.'))
+ 2326 + + {
+ 2327 + +2028 ++cs;
+ 2328 + +2028 break;
+ 2329 + + }
+ 2330 + +1895 else if((c | 32) == 'e')
+ 2331 + + {
+ 2332 + +546 ++cs;
+ 2333 + +546 goto do_exp1;
+ 2334 + + }
+ 2335 + + else
+ 2336 + + {
+ 2337 + +1349 goto finish_dub;
+ 2338 + + }
+ 2339 + + }
+ 2340 + +
+ 2341 + + //----------------------------------
+ 2342 + + //
+ 2343 + + // DIGIT
+ 2344 + + // first non-significant digit
+ 2345 + + // to the right of decimal
+ 2346 + + //
+ 2347 + +2080 do_num4:
+ 2348 + + {
+ 2349 + +2080 if(BOOST_JSON_UNLIKELY(! cs))
+ 2350 + + {
+ 2351 + +64 if(BOOST_JSON_UNLIKELY(
+ 2352 + + ! h_.on_number_part(
+ 2353 + + {begin, cs.used(begin)}, ec_)))
+ 2354 + +6 return fail(cs.begin());
+ 2355 + +
+ 2356 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2357 + +4 num_buf_.append( begin, cs.used(begin) );
+ 2358 + +52 return maybe_suspend(
+ 2359 + +52 cs.begin(), state::num4, num);
+ 2360 + + }
+ 2361 + +2016 char const c = *cs;
+ 2362 + +2016 if(BOOST_JSON_LIKELY(
+ 2363 + + //static_cast<unsigned char>(c - '0') < 10))
+ 2364 + + c >= '0' && c <= '9'))
+ 2365 + + {
+ 2366 + +1949 ++cs;
+ 2367 + + }
+ 2368 + + else
+ 2369 + + {
+ 2370 + + // digit required
+ 2371 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2372 + + = BOOST_CURRENT_LOCATION;
+ 2373 + +67 return fail(cs.begin(), error::syntax, &loc);
+ 2374 + + }
+ 2375 + + }
+ 2376 + +
+ 2377 + + //----------------------------------
+ 2378 + + //
+ 2379 + + // 1*DIGIT
+ 2380 + + // non-significant digits
+ 2381 + + // to the right of decimal
+ 2382 + + //
+ 2383 + +2013470 do_num5:
+ 2384 + +37889832 for(;;)
+ 2385 + + {
+ 2386 + +39903302 if(BOOST_JSON_UNLIKELY(! cs))
+ 2387 + + {
+ 2388 + +6112 if(BOOST_JSON_UNLIKELY(more_))
+ 2389 + + {
+ 2390 + +4577 if(BOOST_JSON_UNLIKELY(
+ 2391 + + ! h_.on_number_part(
+ 2392 + + {begin, cs.used(begin)}, ec_)))
+ 2393 + +20 return fail(cs.begin());
+ 2394 + +
+ 2395 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2396 + +178 num_buf_.append( begin, cs.used(begin) );
+ 2397 + +4537 return suspend(cs.begin(), state::num5, num);
+ 2398 + + }
+ 2399 + +1535 goto finish_dub;
+ 2400 + + }
+ 2401 + +39897190 char const c = *cs;
+ 2402 + +39897190 if(BOOST_JSON_LIKELY(
+ 2403 + + c >= '0' && c <= '9'))
+ 2404 + + {
+ 2405 + +37889832 ++cs;
+ 2406 + + }
+ 2407 + +2007358 else if((c | 32) == 'e')
+ 2408 + + {
+ 2409 + +2003236 ++cs;
+ 2410 + +2003236 goto do_exp1;
+ 2411 + + }
+ 2412 + + else
+ 2413 + + {
+ 2414 + +4122 goto finish_dub;
+ 2415 + + }
+ 2416 + + }
+ 2417 + +
+ 2418 + + //----------------------------------
+ 2419 + + //
+ 2420 + + // [.eE]
+ 2421 + + //
+ 2422 + +2055311 do_num6:
+ 2423 + + {
+ 2424 + +2055311 if(BOOST_JSON_UNLIKELY(! cs))
+ 2425 + + {
+ 2426 + +798 if(BOOST_JSON_UNLIKELY(more_))
+ 2427 + + {
+ 2428 + +751 if(BOOST_JSON_UNLIKELY(
+ 2429 + + ! h_.on_number_part(
+ 2430 + + {begin, cs.used(begin)}, ec_)))
+ 2431 + +42 return fail(cs.begin());
+ 2432 + +
+ 2433 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2434 + +98 num_buf_.append( begin, cs.used(begin) );
+ 2435 + +667 return suspend(cs.begin(), state::num6, num);
+ 2436 + + }
+ 2437 + +47 goto finish_int;
+ 2438 + + }
+ 2439 + +2054513 char const c = *cs;
+ 2440 + +2054513 if(BOOST_JSON_LIKELY(
+ 2441 + + c == '.'))
+ 2442 + + {
+ 2443 + +2016097 ++cs;
+ 2444 + + }
+ 2445 + +38416 else if((c | 32) == 'e')
+ 2446 + + {
+ 2447 + +9140 ++cs;
+ 2448 + +9140 goto do_exp1;
+ 2449 + + }
+ 2450 + + else
+ 2451 + + {
+ 2452 + +29276 goto finish_int;
+ 2453 + + }
+ 2454 + + }
+ 2455 + +
+ 2456 + + //----------------------------------
+ 2457 + + //
+ 2458 + + // DIGIT
+ 2459 + + // first significant digit
+ 2460 + + // to the right of decimal
+ 2461 + + //
+ 2462 + +2016835 do_num7:
+ 2463 + + {
+ 2464 + +2016835 if(BOOST_JSON_UNLIKELY(! cs))
+ 2465 + + {
+ 2466 + +691 if(BOOST_JSON_UNLIKELY(more_))
+ 2467 + + {
+ 2468 + +687 if(BOOST_JSON_UNLIKELY(
+ 2469 + + ! h_.on_number_part(
+ 2470 + + {begin, cs.used(begin)}, ec_)))
+ 2471 + +35 return fail(cs.begin());
+ 2472 + +
+ 2473 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2474 + +96 num_buf_.append( begin, cs.used(begin) );
+ 2475 + +617 return suspend(cs.begin(), state::num7, num);
+ 2476 + + }
+ 2477 + + // digit required
+ 2478 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2479 + + = BOOST_CURRENT_LOCATION;
+ 2480 + +4 return fail(cs.begin(), error::syntax, &loc);
+ 2481 + + }
+ 2482 + +2016144 char const c = *cs;
+ 2483 + +2016144 if(BOOST_JSON_UNLIKELY(
+ 2484 + + c < '0' || c > '9'))
+ 2485 + + {
+ 2486 + + // digit required
+ 2487 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2488 + + = BOOST_CURRENT_LOCATION;
+ 2489 + +169 return fail(cs.begin(), error::syntax, &loc);
+ 2490 + + }
+ 2491 + + }
+ 2492 + +
+ 2493 + + //----------------------------------
+ 2494 + + //
+ 2495 + + // 1*DIGIT
+ 2496 + + // significant digits
+ 2497 + + // to the right of decimal
+ 2498 + + //
+ 2499 + +2034436 do_num8:
+ 2500 + +3277926 for(;;)
+ 2501 + + {
+ 2502 + +5314862 if(BOOST_JSON_UNLIKELY(! cs))
+ 2503 + + {
+ 2504 + +12816 if(BOOST_JSON_UNLIKELY(more_))
+ 2505 + + {
+ 2506 + +11080 if(BOOST_JSON_UNLIKELY(
+ 2507 + + ! h_.on_number_part(
+ 2508 + + {begin, cs.used(begin)}, ec_)))
+ 2509 + +67 return fail(cs.begin());
+ 2510 + +
+ 2511 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2512 + +3442 num_buf_.append( begin, cs.used(begin) );
+ 2513 + +10945 return suspend(cs.begin(), state::num8, num);
+ 2514 + + }
+ 2515 + +1736 goto finish_dub;
+ 2516 + + }
+ 2517 + +5302046 char const c = *cs;
+ 2518 + +5302046 if(BOOST_JSON_LIKELY(
+ 2519 + + c >= '0' && c <= '9'))
+ 2520 + + {
+ 2521 + +5284910 ++cs;
+ 2522 + +5279817 if(!no_parsing && BOOST_JSON_LIKELY(
+ 2523 + + num.mant <= 9007199254740991)) // 2^53-1
+ 2524 + + {
+ 2525 + +3277926 if(BOOST_JSON_UNLIKELY( num.bias - 1 == INT_MIN ))
+ 2526 + + {
+ 2527 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2528 + + = BOOST_CURRENT_LOCATION;
+ 2529 + + return fail(cs.begin(), error::exponent_overflow, &loc);
+ 2530 + + }
+ 2531 + +3277926 --num.bias;
+ 2532 + +3277926 num.mant = 10 * num.mant + ( c - '0' );
+ 2533 + + }
+ 2534 + + else
+ 2535 + + {
+ 2536 + +2006984 goto do_num5;
+ 2537 + + }
+ 2538 + + }
+ 2539 + +17136 else if((c | 32) == 'e')
+ 2540 + + {
+ 2541 + +11133 ++cs;
+ 2542 + +11133 goto do_exp1;
+ 2543 + + }
+ 2544 + + else
+ 2545 + + {
+ 2546 + +6003 goto finish_dub;
+ 2547 + + }
+ 2548 + + }
+ 2549 + +
+ 2550 + + //----------------------------------
+ 2551 + + //
+ 2552 + + // *[+-]
+ 2553 + + //
+ 2554 + +2031210 do_exp1:
+ 2555 + +2031210 if(BOOST_JSON_UNLIKELY(! cs))
+ 2556 + + {
+ 2557 + +565 if(BOOST_JSON_UNLIKELY(
+ 2558 + + ! h_.on_number_part(
+ 2559 + + {begin, cs.used(begin)}, ec_)))
+ 2560 + +48 return fail(cs.begin());
+ 2561 + +
+ 2562 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2563 + +46 num_buf_.append( begin, cs.used(begin) );
+ 2564 + +469 return maybe_suspend(
+ 2565 + +469 cs.begin(), state::exp1, num);
+ 2566 + + }
+ 2567 + +2030645 if(*cs == '+')
+ 2568 + + {
+ 2569 + +1931 ++cs;
+ 2570 + + }
+ 2571 + +2028714 else if(*cs == '-')
+ 2572 + + {
+ 2573 + +1001935 ++cs;
+ 2574 + +1001935 num.frac = true;
+ 2575 + + }
+ 2576 + +
+ 2577 + + //----------------------------------
+ 2578 + + //
+ 2579 + + // DIGIT
+ 2580 + + // first digit of the exponent
+ 2581 + + //
+ 2582 + +1026779 do_exp2:
+ 2583 + + {
+ 2584 + +2030770 if(BOOST_JSON_UNLIKELY(! cs))
+ 2585 + + {
+ 2586 + +172 if(BOOST_JSON_UNLIKELY(more_))
+ 2587 + + {
+ 2588 + +163 if(BOOST_JSON_UNLIKELY(
+ 2589 + + ! h_.on_number_part(
+ 2590 + + {begin, cs.used(begin)}, ec_)))
+ 2591 + +19 return fail(cs.begin());
+ 2592 + +
+ 2593 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2594 + +4 num_buf_.append( begin, cs.used(begin) );
+ 2595 + +125 return suspend(cs.begin(), state::exp2, num);
+ 2596 + + }
+ 2597 + + // digit required
+ 2598 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2599 + + = BOOST_CURRENT_LOCATION;
+ 2600 + +9 return fail(cs.begin(), error::syntax, &loc);
+ 2601 + + }
+ 2602 + +2030598 char const c = *cs;
+ 2603 + +2030598 if(BOOST_JSON_UNLIKELY(
+ 2604 + + c < '0' || c > '9'))
+ 2605 + + {
+ 2606 + + // digit required
+ 2607 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2608 + + = BOOST_CURRENT_LOCATION;
+ 2609 + +508 return fail(cs.begin(), error::syntax, &loc);
+ 2610 + + }
+ 2611 + +2030090 ++cs;
+ 2612 + +2030090 num.exp = c - '0';
+ 2613 + + }
+ 2614 + +
+ 2615 + + //----------------------------------
+ 2616 + + //
+ 2617 + + // 1*DIGIT
+ 2618 + + // subsequent digits in the exponent
+ 2619 + + //
+ 2620 + +2042113 do_exp3:
+ 2621 + +5466102 for(;;)
+ 2622 + + {
+ 2623 + +7508215 if(BOOST_JSON_UNLIKELY(! cs))
+ 2624 + + {
+ 2625 + +2020530 if(BOOST_JSON_UNLIKELY(more_))
+ 2626 + + {
+ 2627 + +12177 if(BOOST_JSON_UNLIKELY(
+ 2628 + + ! h_.on_number_part(
+ 2629 + + {begin, cs.used(begin)}, ec_)))
+ 2630 + +77 return fail(cs.begin());
+ 2631 + +
+ 2632 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2633 + +2873 num_buf_.append( begin, cs.used(begin) );
+ 2634 + +12023 return suspend(cs.begin(), state::exp3, num);
+ 2635 + + }
+ 2636 + + }
+ 2637 + + else
+ 2638 + + {
+ 2639 + +5487685 char const c = *cs;
+ 2640 + +5487685 if(BOOST_JSON_LIKELY( c >= '0' && c <= '9' ))
+ 2641 + + {
+ 2642 + +5466102 if(BOOST_JSON_UNLIKELY(
+ 2643 + + // 2147483647 INT_MAX
+ 2644 + + num.exp > 214748364 ||
+ 2645 + + (num.exp == 214748364 && c > '7')
+ 2646 + + ))
+ 2647 + +3855 num.exp = INT_MAX;
+ 2648 + + else BOOST_IF_CONSTEXPR( !no_parsing )
+ 2649 + +4921395 num.exp = 10 * num.exp + ( c - '0' );
+ 2650 + +
+ 2651 + +5466102 ++cs;
+ 2652 + +5466102 continue;
+ 2653 + + }
+ 2654 + + }
+ 2655 + +2029936 BOOST_ASSERT(num.exp >= 0);
+ 2656 + +2029936 if ( num.frac )
+ 2657 + + {
+ 2658 + +1001799 if(BOOST_JSON_UNLIKELY( num.bias < (INT_MIN + num.exp) ))
+ 2659 + + {
+ 2660 + + // if exponent overflowed, bias is a very large negative
+ 2661 + + // number, and mantissa isn't zero, then we cannot parse the
+ 2662 + + // number correctly
+ 2663 + +91 if(BOOST_JSON_UNLIKELY(
+ 2664 + + (num.exp == INT_MAX) &&
+ 2665 + + (num.bias < 0) &&
+ 2666 + + (num.exp + num.bias < 308) &&
+ 2667 + + num.mant ))
+ 2668 + + {
+ 2669 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2670 + + = BOOST_CURRENT_LOCATION;
+ 2671 + + return fail(cs.begin(), error::exponent_overflow, &loc);
+ 2672 + + }
+ 2673 + +
+ 2674 + +91 num.bias = 0;
+ 2675 + +91 num.exp = INT_MAX;
+ 2676 + + }
+ 2677 + + }
+ 2678 + +1028137 else if (BOOST_JSON_UNLIKELY( num.bias > (INT_MAX - num.exp) ))
+ 2679 + + {
+ 2680 + + // if exponent overflowed, bias is a very large positive number,
+ 2681 + + // and mantissa isn't zero, then we cannot parse the
+ 2682 + + // number correctly
+ 2683 + + if(BOOST_JSON_UNLIKELY(
+ 2684 + + (num.exp == INT_MAX) &&
+ 2685 + + (num.bias > 0) &&
+ 2686 + + (num.exp - num.bias < 308) &&
+ 2687 + + num.mant ))
+ 2688 + + {
+ 2689 + + BOOST_STATIC_CONSTEXPR source_location loc
+ 2690 + + = BOOST_CURRENT_LOCATION;
+ 2691 + + return fail(cs.begin(), error::exponent_overflow, &loc);
+ 2692 + + }
+ 2693 + +
+ 2694 + + num.bias = 0;
+ 2695 + + num.exp = INT_MAX;
+ 2696 + + }
+ 2697 + +2029936 goto finish_dub;
+ 2698 + + }
+ 2699 + +
+ 2700 + +30388 finish_int:
+ 2701 + +28458 if(negative || (!stack_empty && num.neg))
+ 2702 + + {
+ 2703 + +2532 if(BOOST_JSON_UNLIKELY(
+ 2704 + + ! h_.on_int64(static_cast<
+ 2705 + + int64_t>(~num.mant + 1), {begin, cs.used(begin)}, ec_)))
+ 2706 + +310 return fail(cs.begin());
+ 2707 + +1914 return cs.begin();
+ 2708 + + }
+ 2709 + +27856 if(num.mant <= INT64_MAX)
+ 2710 + + {
+ 2711 + +27554 finish_signed:
+ 2712 + +30829 if(BOOST_JSON_UNLIKELY(
+ 2713 + + ! h_.on_int64(static_cast<
+ 2714 + + int64_t>(num.mant), {begin, cs.used(begin)}, ec_)))
+ 2715 + +2267 return fail(cs.begin());
+ 2716 + +26302 return cs.begin();
+ 2717 + + }
+ 2718 + +321 if(BOOST_JSON_UNLIKELY(
+ 2719 + + ! h_.on_uint64(num.mant, {begin, cs.used(begin)}, ec_)))
+ 2720 + +35 return fail(cs.begin());
+ 2721 + +254 return cs.begin();
+ 2722 + +2052261 finish_dub:
+ 2723 + + double d;
+ 2724 + +2052261 std::size_t const size = cs.used(begin);
+ 2725 + +2052261 BOOST_ASSERT( !num_buf_.size() || precise_parsing );
+ 2726 + + BOOST_IF_CONSTEXPR( precise_parsing )
+ 2727 + + {
+ 2728 + +1009310 char const* data = begin;
+ 2729 + +1009310 std::size_t full_size = size;
+ 2730 + + // if we previously suspended or if the current input ends with the
+ 2731 + + // number, we need to copy the current part of the number to the
+ 2732 + + // temporary buffer
+ 2733 + +1009310 if(BOOST_JSON_UNLIKELY( num_buf_.size() ))
+ 2734 + + {
+ 2735 + +4771 data = num_buf_.append( begin, size );
+ 2736 + +4771 full_size = num_buf_.size();
+ 2737 + + }
+ 2738 + +1009310 auto const err = detail::charconv::from_chars(
+ 2739 + + data, data + full_size, d );
+ 2740 + +1009310 BOOST_ASSERT( err.ec != std::errc::invalid_argument );
+ 2741 + +1009310 BOOST_ASSERT( err.ptr == data + full_size );
+ 2742 + + (void)err;
+ 2743 + + }
+ 2744 + + else BOOST_IF_CONSTEXPR( no_parsing )
+ 2745 + +9258 d = 0;
+ 2746 + + else
+ 2747 + +1033693 d = detail::dec_to_float(
+ 2748 + + num.mant,
+ 2749 + +531741 num.bias + (num.frac ?
+ 2750 + +501952 -num.exp : num.exp),
+ 2751 + +1033693 num.neg);
+ 2752 + +2052261 if(BOOST_JSON_UNLIKELY(
+ 2753 + + ! h_.on_double(d, {begin, size}, ec_)))
+ 2754 + +1903 return fail(cs.begin());
+ 2755 + +2048455 return cs.begin();
+ 2756 + + }
+ 2757 + +
+ 2758 + + //----------------------------------------------------------
+ 2759 + +
+ 2760 + + template<class Handler>
+ 2761 + + template<class... Args>
+ 2762 + +2164604 basic_parser<Handler>::
+ 2763 + + basic_parser(
+ 2764 + + parse_options const& opt,
+ 2765 + + Args&&... args)
+ 2766 + +2164596 : h_(std::forward<Args>(args)...)
+ 2767 + +2164604 , opt_(opt)
+ 2768 + + {
+ 2769 + +2164604 }
+ 2770 + +
+ 2771 + + //----------------------------------------------------------
+ 2772 + +
+ 2773 + + template<class Handler>
+ 2774 + + void
+ 2775 + +4153127 basic_parser<Handler>::
+ 2776 + + reset() noexcept
+ 2777 + + {
+ 2778 + +4153127 ec_ = {};
+ 2779 + +4153127 st_.clear();
+ 2780 + +4153127 more_ = true;
+ 2781 + +4153127 done_ = false;
+ 2782 + +4153127 clean_ = true;
+ 2783 + +4153127 num_buf_.clear();
+ 2784 + +4153127 }
+ 2785 + +
+ 2786 + + template<class Handler>
+ 2787 + + void
+ 2788 + +16 basic_parser<Handler>::
+ 2789 + + fail(system::error_code ec) noexcept
+ 2790 + + {
+ 2791 + +16 if(! ec)
+ 2792 + + {
+ 2793 + + // assign an arbitrary
+ 2794 + + // error code to prevent UB
+ 2795 + + BOOST_JSON_FAIL(ec_, error::incomplete);
+ 2796 + + }
+ 2797 + + else
+ 2798 + + {
+ 2799 + +16 ec_ = ec;
+ 2800 + + }
+ 2801 + +16 done_ = false;
+ 2802 + +16 }
+ 2803 + +
+ 2804 + + //----------------------------------------------------------
+ 2805 + +
+ 2806 + + template<class Handler>
+ 2807 + + std::size_t
+ 2808 + +2334191 basic_parser<Handler>::
+ 2809 + + write_some(
+ 2810 + + bool more,
+ 2811 + + char const* data,
+ 2812 + + std::size_t size,
+ 2813 + + system::error_code& ec)
+ 2814 + + {
+ 2815 + + // see if we exited via exception
+ 2816 + + // on the last call to write_some
+ 2817 + +2334191 if(! clean_)
+ 2818 + + {
+ 2819 + + // prevent UB
+ 2820 + +1 if(! ec_)
+ 2821 + + {
+ 2822 + +1 BOOST_JSON_FAIL(ec_, error::exception);
+ 2823 + + }
+ 2824 + + }
+ 2825 + +2334191 if(ec_)
+ 2826 + + {
+ 2827 + + // error is sticky
+ 2828 + +5 ec = ec_;
+ 2829 + +5 return 0;
+ 2830 + + }
+ 2831 + +2334186 clean_ = false;
+ 2832 + +2334186 more_ = more;
+ 2833 + +2334186 end_ = data + size;
+ 2834 + + const char* p;
+ 2835 + +2334186 if(BOOST_JSON_LIKELY(st_.empty()))
+ 2836 + + {
+ 2837 + + // first time
+ 2838 + +2164590 depth_ = opt_.max_depth;
+ 2839 + +2164590 if(BOOST_JSON_UNLIKELY(
+ 2840 + + ! h_.on_document_begin(ec_)))
+ 2841 + + {
+ 2842 + +7889 ec = ec_;
+ 2843 + +7889 return 0;
+ 2844 + + }
+ 2845 + +2148811 p = parse_document(data, std::true_type());
+ 2846 + + }
+ 2847 + + else
+ 2848 + + {
+ 2849 + +169596 p = parse_document(data, std::false_type());
+ 2850 + + }
+ 2851 + +
+ 2852 + +2299308 if(BOOST_JSON_LIKELY(p != sentinel()))
+ 2853 + + {
+ 2854 + +2099051 BOOST_ASSERT(! ec_);
+ 2855 + +2099051 if(! done_)
+ 2856 + + {
+ 2857 + +2031637 done_ = true;
+ 2858 + +2031637 h_.on_document_end(ec_);
+ 2859 + + }
+ 2860 + + }
+ 2861 + + else
+ 2862 + + {
+ 2863 + +200257 if(! ec_)
+ 2864 + + {
+ 2865 + +173480 if(! more_)
+ 2866 + + {
+ 2867 + +572 BOOST_JSON_FAIL(ec_, error::incomplete);
+ 2868 + + }
+ 2869 + +172908 else if(! st_.empty())
+ 2870 + + {
+ 2871 + + // consume as much trailing whitespace in
+ 2872 + + // the JSON document as possible, but still
+ 2873 + + // consider the parse complete
+ 2874 + + state st;
+ 2875 + +172908 st_.peek(st);
+ 2876 + +172908 if( st == state::doc3 &&
+ 2877 + +88550 ! done_)
+ 2878 + + {
+ 2879 + +70723 done_ = true;
+ 2880 + +70723 h_.on_document_end(ec_);
+ 2881 + + }
+ 2882 + + }
+ 2883 + + }
+ 2884 + +198613 p = end_;
+ 2885 + + }
+ 2886 + +2293704 ec = ec_;
+ 2887 + +2293704 clean_ = true;
+ 2888 + +2293704 return p - data;
+ 2889 + + }
+ 2890 + +
+ 2891 + + template<class Handler>
+ 2892 + + std::size_t
+ 2893 + +1 basic_parser<Handler>::
+ 2894 + + write_some(
+ 2895 + + bool more,
+ 2896 + + char const* data,
+ 2897 + + std::size_t size,
+ 2898 + + std::error_code& ec)
+ 2899 + + {
+ 2900 + +1 system::error_code jec;
+ 2901 + +1 std::size_t const result = write_some(more, data, size, jec);
+ 2902 + +1 ec = jec;
+ 2903 + +1 return result;
+ 2904 + + }
+ 2905 + +
+ 2906 + + #endif
+ 2907 + +
+ 2908 + + } // namespace json
+ 2909 + + } // namespace boost
+ 2910 + +
+ 2911 + + #ifdef _MSC_VER
+ 2912 + + #pragma warning(pop)
+ 2913 + + #endif
+ 2914 + +
+ 2915 + + #endif
+ 2916 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.bigint.hpp.7ed59f082bdc8865c839e37a907818ae.html b/json/gcovr/index.bigint.hpp.7ed59f082bdc8865c839e37a907818ae.html new file mode 100644 index 00000000..a325cd68 --- /dev/null +++ b/json/gcovr/index.bigint.hpp.7ed59f082bdc8865c839e37a907818ae.html @@ -0,0 +1,7094 @@ + + + + + + detail/charconv/detail/fast_float/bigint.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/fast_float/bigint.hpp

+
+ + 89.9% Lines (213/237) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/fast_float/bigint.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2020-2023 Daniel Lemire
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + + //
+ 6 + + // Derivative of: https://github.com/fastfloat/fast_float
+ 7 + +
+ 8 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_BIGINT_HPP
+ 9 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_BIGINT_HPP
+ 10 + +
+ 11 + + #include <boost/json/detail/charconv/detail/fast_float/float_common.hpp>
+ 12 + + #include <algorithm>
+ 13 + + #include <cstdint>
+ 14 + + #include <climits>
+ 15 + + #include <cstring>
+ 16 + +
+ 17 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float {
+ 18 + +
+ 19 + + // the limb width: we want efficient multiplication of double the bits in
+ 20 + + // limb, or for 64-bit limbs, at least 64-bit multiplication where we can
+ 21 + + // extract the high and low parts efficiently. this is every 64-bit
+ 22 + + // architecture except for sparc, which emulates 128-bit multiplication.
+ 23 + + // we might have platforms where `CHAR_BIT` is not 8, so let's avoid
+ 24 + + // doing `8 * sizeof(limb)`.
+ 25 + + #if defined(BOOST_JSON_FASTFLOAT_64BIT) && !defined(__sparc)
+ 26 + + #define BOOST_JSON_FASTFLOAT_64BIT_LIMB 1
+ 27 + + typedef uint64_t limb;
+ 28 + + constexpr size_t limb_bits = 64;
+ 29 + + #else
+ 30 + + #define BOOST_JSON_FASTFLOAT_32BIT_LIMB
+ 31 + + typedef uint32_t limb;
+ 32 + + constexpr size_t limb_bits = 32;
+ 33 + + #endif
+ 34 + +
+ 35 + + typedef span<limb> limb_span;
+ 36 + +
+ 37 + + // number of bits in a bigint. this needs to be at least the number
+ 38 + + // of bits required to store the largest bigint, which is
+ 39 + + // `log2(10**(digits + max_exp))`, or `log2(10**(767 + 342))`, or
+ 40 + + // ~3600 bits, so we round to 4000.
+ 41 + + constexpr size_t bigint_bits = 4000;
+ 42 + + constexpr size_t bigint_limbs = bigint_bits / limb_bits;
+ 43 + +
+ 44 + + // vector-like type that is allocated on the stack. the entire
+ 45 + + // buffer is pre-allocated, and only the length changes.
+ 46 + + template <uint16_t size>
+ 47 + + struct stackvec {
+ 48 + + limb data[size];
+ 49 + + // we never need more than 150 limbs
+ 50 + + uint16_t length{0};
+ 51 + +
+ 52 + +12693 stackvec() = default;
+ 53 + + stackvec(const stackvec &) = delete;
+ 54 + + stackvec &operator=(const stackvec &) = delete;
+ 55 + + stackvec(stackvec &&) = delete;
+ 56 + + stackvec &operator=(stackvec &&other) = delete;
+ 57 + +
+ 58 + + // create stack vector from existing limb span.
+ 59 + +2024 BOOST_JSON_FASTFLOAT_CONSTEXPR20 stackvec(limb_span s) {
+ 60 + +2024 try_extend(s);
+ 61 + +2024 }
+ 62 + +
+ 63 + +255428 BOOST_JSON_CXX14_CONSTEXPR limb& operator[](size_t index) noexcept {
+ 64 + +255428 BOOST_ASSERT(index < length);
+ 65 + +255428 return data[index];
+ 66 + + }
+ 67 + +6198 BOOST_JSON_CXX14_CONSTEXPR const limb& operator[](size_t index) const noexcept {
+ 68 + +6198 BOOST_ASSERT(index < length);
+ 69 + +6198 return data[index];
+ 70 + + }
+ 71 + + // index from the end of the container
+ 72 + +9129 BOOST_JSON_CXX14_CONSTEXPR const limb& rindex(size_t index) const noexcept {
+ 73 + +9129 BOOST_ASSERT(index < length);
+ 74 + +9129 size_t rindex = length - index - 1;
+ 75 + +9129 return data[rindex];
+ 76 + + }
+ 77 + +
+ 78 + + // set the length, without bounds checking.
+ 79 + +28303 BOOST_JSON_CXX14_CONSTEXPR void set_len(size_t len) noexcept {
+ 80 + +28303 length = uint16_t(len);
+ 81 + +28303 }
+ 82 + +259478 constexpr size_t len() const noexcept {
+ 83 + +259478 return length;
+ 84 + + }
+ 85 + +3789 constexpr bool is_empty() const noexcept {
+ 86 + +3789 return length == 0;
+ 87 + + }
+ 88 + +45829 constexpr size_t capacity() const noexcept {
+ 89 + +45829 return size;
+ 90 + + }
+ 91 + + // append item to vector, without bounds checking
+ 92 + +27233 BOOST_JSON_CXX14_CONSTEXPR void push_unchecked(limb value) noexcept {
+ 93 + +27233 data[length] = value;
+ 94 + +27233 length++;
+ 95 + +27233 }
+ 96 + + // append item to vector, returning if item was added
+ 97 + +25622 BOOST_JSON_CXX14_CONSTEXPR bool try_push(limb value) noexcept {
+ 98 + +25622 if (len() < capacity()) {
+ 99 + +25622 push_unchecked(value);
+ 100 + +25622 return true;
+ 101 + + } else {
+ 102 + + return false;
+ 103 + + }
+ 104 + + }
+ 105 + + // add items to the vector, from a span, without bounds checking
+ 106 + +10120 BOOST_JSON_FASTFLOAT_CONSTEXPR20 void extend_unchecked(limb_span s) noexcept {
+ 107 + +10120 limb* ptr = data + length;
+ 108 + +10120 std::copy_n(s.ptr, s.len(), ptr);
+ 109 + +10120 set_len(len() + s.len());
+ 110 + +10120 }
+ 111 + + // try to add items to the vector, returning if items were added
+ 112 + +10120 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool try_extend(limb_span s) noexcept {
+ 113 + +10120 if (len() + s.len() <= capacity()) {
+ 114 + +10120 extend_unchecked(s);
+ 115 + +10120 return true;
+ 116 + + } else {
+ 117 + + return false;
+ 118 + + }
+ 119 + + }
+ 120 + + // resize the vector, without bounds checking
+ 121 + + // if the new size is longer than the vector, assign value to each
+ 122 + + // appended item.
+ 123 + + BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 124 + +7673 void resize_unchecked(size_t new_len, limb value) noexcept {
+ 125 + +7673 if (new_len > len()) {
+ 126 + +7673 size_t count = new_len - len();
+ 127 + +7673 limb* first = data + len();
+ 128 + +7673 limb* last = first + count;
+ 129 + +7673 ::std::fill(first, last, value);
+ 130 + +7673 set_len(new_len);
+ 131 + + } else {
+ 132 + + set_len(new_len);
+ 133 + + }
+ 134 + +7673 }
+ 135 + + // try to resize the vector, returning if the vector was resized.
+ 136 + +7673 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool try_resize(size_t new_len, limb value) noexcept {
+ 137 + +7673 if (new_len > capacity()) {
+ 138 + + return false;
+ 139 + + } else {
+ 140 + +7673 resize_unchecked(new_len, value);
+ 141 + +7673 return true;
+ 142 + + }
+ 143 + + }
+ 144 + + // check if any limbs are non-zero after the given index.
+ 145 + + // this needs to be done in reverse order, since the index
+ 146 + + // is relative to the most significant limbs.
+ 147 + +1375 BOOST_JSON_CXX14_CONSTEXPR bool nonzero(size_t index) const noexcept {
+ 148 + +1375 while (index < len()) {
+ 149 + +1369 if (rindex(index) != 0) {
+ 150 + +1369 return true;
+ 151 + + }
+ 152 + + index++;
+ 153 + + }
+ 154 + +6 return false;
+ 155 + + }
+ 156 + + // normalize the big integer, so most-significant zero limbs are removed.
+ 157 + +3635 BOOST_JSON_CXX14_CONSTEXPR void normalize() noexcept {
+ 158 + +3635 while (len() > 0 && rindex(0) == 0) {
+ 159 + + length--;
+ 160 + + }
+ 161 + +3635 }
+ 162 + + };
+ 163 + +
+ 164 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 165 + + uint64_t empty_hi64(bool& truncated) noexcept {
+ 166 + + truncated = false;
+ 167 + + return 0;
+ 168 + + }
+ 169 + +
+ 170 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 171 + + uint64_t uint64_hi64(uint64_t r0, bool& truncated) noexcept {
+ 172 + + truncated = false;
+ 173 + + int shl = leading_zeroes(r0);
+ 174 + + return r0 << shl;
+ 175 + + }
+ 176 + +
+ 177 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 178 + + uint64_t uint64_hi64(uint64_t r0, uint64_t r1, bool& truncated) noexcept {
+ 179 + +1375 int shl = leading_zeroes(r0);
+ 180 + +1375 if (shl == 0) {
+ 181 + +27 truncated = r1 != 0;
+ 182 + +27 return r0;
+ 183 + + } else {
+ 184 + +1348 int shr = 64 - shl;
+ 185 + +1348 truncated = (r1 << shl) != 0;
+ 186 + +1348 return (r0 << shl) | (r1 >> shr);
+ 187 + + }
+ 188 + + }
+ 189 + +
+ 190 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 191 + + uint64_t uint32_hi64(uint32_t r0, bool& truncated) noexcept {
+ 192 + + return uint64_hi64(r0, truncated);
+ 193 + + }
+ 194 + +
+ 195 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 196 + + uint64_t uint32_hi64(uint32_t r0, uint32_t r1, bool& truncated) noexcept {
+ 197 + + uint64_t x0 = r0;
+ 198 + + uint64_t x1 = r1;
+ 199 + + return uint64_hi64((x0 << 32) | x1, truncated);
+ 200 + + }
+ 201 + +
+ 202 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 203 + + uint64_t uint32_hi64(uint32_t r0, uint32_t r1, uint32_t r2, bool& truncated) noexcept {
+ 204 + + uint64_t x0 = r0;
+ 205 + + uint64_t x1 = r1;
+ 206 + + uint64_t x2 = r2;
+ 207 + + return uint64_hi64(x0, (x1 << 32) | x2, truncated);
+ 208 + + }
+ 209 + +
+ 210 + + // add two small integers, checking for overflow.
+ 211 + + // we want an efficient operation. for msvc, where
+ 212 + + // we don't have built-in intrinsics, this is still
+ 213 + + // pretty fast.
+ 214 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 215 + + limb scalar_add(limb x, limb y, bool& overflow) noexcept {
+ 216 + + limb z;
+ 217 + + // gcc and clang
+ 218 + + #if defined(__has_builtin)
+ 219 + + #if __has_builtin(__builtin_add_overflow)
+ 220 + +38490 if (!cpp20_and_in_constexpr()) {
+ 221 + +38490 overflow = __builtin_add_overflow(x, y, &z);
+ 222 + +38490 return z;
+ 223 + + }
+ 224 + + #endif
+ 225 + + #endif
+ 226 + +
+ 227 + + // generic, this still optimizes correctly on MSVC.
+ 228 + + z = x + y;
+ 229 + + overflow = z < x;
+ 230 + + return z;
+ 231 + + }
+ 232 + +
+ 233 + + // multiply two small integers, getting both the high and low bits.
+ 234 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 235 + + limb scalar_mul(limb x, limb y, limb& carry) noexcept {
+ 236 + + #ifdef BOOST_JSON_FASTFLOAT_64BIT_LIMB
+ 237 + + #if defined(__SIZEOF_INT128__)
+ 238 + + // GCC and clang both define it as an extension.
+ 239 + +80707 __uint128_t z = __uint128_t(x) * __uint128_t(y) + __uint128_t(carry);
+ 240 + +80707 carry = limb(z >> limb_bits);
+ 241 + +80707 return limb(z);
+ 242 + + #else
+ 243 + + // fallback, no native 128-bit integer multiplication with carry.
+ 244 + + // on msvc, this optimizes identically, somehow.
+ 245 + + value128 z = full_multiplication(x, y);
+ 246 + + bool overflow;
+ 247 + + z.low = scalar_add(z.low, carry, overflow);
+ 248 + + z.high += uint64_t(overflow); // cannot overflow
+ 249 + + carry = z.high;
+ 250 + + return z.low;
+ 251 + + #endif
+ 252 + + #else
+ 253 + + uint64_t z = uint64_t(x) * uint64_t(y) + uint64_t(carry);
+ 254 + + carry = limb(z >> limb_bits);
+ 255 + + return limb(z);
+ 256 + + #endif
+ 257 + + }
+ 258 + +
+ 259 + + // add scalar value to bigint starting from offset.
+ 260 + + // used in grade school multiplication
+ 261 + + template <uint16_t size>
+ 262 + + inline BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 263 + +9437 bool small_add_from(stackvec<size>& vec, limb y, size_t start) noexcept {
+ 264 + +9437 size_t index = start;
+ 265 + +9437 limb carry = y;
+ 266 + + bool overflow;
+ 267 + +16116 while (carry != 0 && index < vec.len()) {
+ 268 + +6679 vec[index] = scalar_add(vec[index], carry, overflow);
+ 269 + +6679 carry = limb(overflow);
+ 270 + +6679 index += 1;
+ 271 + + }
+ 272 + +9437 if (carry != 0) {
+ 273 + +2986 BOOST_JSON_FASTFLOAT_TRY(vec.try_push(carry));
+ 274 + + }
+ 275 + +9437 return true;
+ 276 + + }
+ 277 + +
+ 278 + + // add scalar value to bigint.
+ 279 + + template <uint16_t size>
+ 280 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 281 + + bool small_add(stackvec<size>& vec, limb y) noexcept {
+ 282 + +9437 return small_add_from(vec, y, 0);
+ 283 + + }
+ 284 + +
+ 285 + + // multiply bigint by scalar value.
+ 286 + + template <uint16_t size>
+ 287 + + inline BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 288 + +28029 bool small_mul(stackvec<size>& vec, limb y) noexcept {
+ 289 + +28029 limb carry = 0;
+ 290 + +108736 for (size_t index = 0; index < vec.len(); index++) {
+ 291 + +161414 vec[index] = scalar_mul(vec[index], y, carry);
+ 292 + + }
+ 293 + +28029 if (carry != 0) {
+ 294 + +21102 BOOST_JSON_FASTFLOAT_TRY(vec.try_push(carry));
+ 295 + + }
+ 296 + +28029 return true;
+ 297 + + }
+ 298 + +
+ 299 + + // add bigint to bigint starting from index.
+ 300 + + // used in grade school multiplication
+ 301 + + template <uint16_t size>
+ 302 + + BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 303 + +8096 bool large_add_from(stackvec<size>& x, limb_span y, size_t start) noexcept {
+ 304 + + // the effective x buffer is from `xstart..x.len()`, so exit early
+ 305 + + // if we can't get that current range.
+ 306 + +8096 if (x.len() < start || y.len() > x.len() - start) {
+ 307 + +7673 BOOST_JSON_FASTFLOAT_TRY(x.try_resize(y.len() + start, 0));
+ 308 + + }
+ 309 + +
+ 310 + +8096 bool carry = false;
+ 311 + +34341 for (size_t index = 0; index < y.len(); index++) {
+ 312 + +26245 limb xi = x[index + start];
+ 313 + +26245 limb yi = y[index];
+ 314 + +26245 bool c1 = false;
+ 315 + +26245 bool c2 = false;
+ 316 + +26245 xi = scalar_add(xi, yi, c1);
+ 317 + +26245 if (carry) {
+ 318 + +5566 xi = scalar_add(xi, 1, c2);
+ 319 + + }
+ 320 + +26245 x[index + start] = xi;
+ 321 + +26245 carry = c1 | c2;
+ 322 + + }
+ 323 + +
+ 324 + + // handle overflow
+ 325 + +8096 if (carry) {
+ 326 + + BOOST_JSON_FASTFLOAT_TRY(small_add_from(x, 1, y.len() + start));
+ 327 + + }
+ 328 + +8096 return true;
+ 329 + + }
+ 330 + +
+ 331 + + // add bigint to bigint.
+ 332 + + template <uint16_t size>
+ 333 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 334 + + bool large_add_from(stackvec<size>& x, limb_span y) noexcept {
+ 335 + + return large_add_from(x, y, 0);
+ 336 + + }
+ 337 + +
+ 338 + + // grade-school multiplication algorithm
+ 339 + + template <uint16_t size>
+ 340 + + BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 341 + +2024 bool long_mul(stackvec<size>& x, limb_span y) noexcept {
+ 342 + +2024 limb_span xs = limb_span(x.data, x.len());
+ 343 + +2024 stackvec<size> z(xs);
+ 344 + +2024 limb_span zs = limb_span(z.data, z.len());
+ 345 + +
+ 346 + +2024 if (y.len() != 0) {
+ 347 + +2024 limb y0 = y[0];
+ 348 + +2024 BOOST_JSON_FASTFLOAT_TRY(small_mul(x, y0));
+ 349 + +10120 for (size_t index = 1; index < y.len(); index++) {
+ 350 + +8096 limb yi = y[index];
+ 351 + +8096 stackvec<size> zi;
+ 352 + +8096 if (yi != 0) {
+ 353 + + // re-use the same buffer throughout
+ 354 + +8096 zi.set_len(0);
+ 355 + +8096 BOOST_JSON_FASTFLOAT_TRY(zi.try_extend(zs));
+ 356 + +8096 BOOST_JSON_FASTFLOAT_TRY(small_mul(zi, yi));
+ 357 + +8096 limb_span zis = limb_span(zi.data, zi.len());
+ 358 + +8096 BOOST_JSON_FASTFLOAT_TRY(large_add_from(x, zis, index));
+ 359 + + }
+ 360 + + }
+ 361 + + }
+ 362 + +
+ 363 + +2024 x.normalize();
+ 364 + +2024 return true;
+ 365 + + }
+ 366 + +
+ 367 + + // grade-school multiplication algorithm
+ 368 + + template <uint16_t size>
+ 369 + + BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 370 + +2024 bool large_mul(stackvec<size>& x, limb_span y) noexcept {
+ 371 + +2024 if (y.len() == 1) {
+ 372 + + BOOST_JSON_FASTFLOAT_TRY(small_mul(x, y[0]));
+ 373 + + } else {
+ 374 + +2024 BOOST_JSON_FASTFLOAT_TRY(long_mul(x, y));
+ 375 + + }
+ 376 + +2024 return true;
+ 377 + + }
+ 378 + +
+ 379 + + template <typename = void>
+ 380 + + struct pow5_tables {
+ 381 + + static constexpr uint32_t large_step = 135;
+ 382 + + static constexpr uint64_t small_power_of_5[] = {
+ 383 + + 1UL, 5UL, 25UL, 125UL, 625UL, 3125UL, 15625UL, 78125UL, 390625UL,
+ 384 + + 1953125UL, 9765625UL, 48828125UL, 244140625UL, 1220703125UL,
+ 385 + + 6103515625UL, 30517578125UL, 152587890625UL, 762939453125UL,
+ 386 + + 3814697265625UL, 19073486328125UL, 95367431640625UL, 476837158203125UL,
+ 387 + + 2384185791015625UL, 11920928955078125UL, 59604644775390625UL,
+ 388 + + 298023223876953125UL, 1490116119384765625UL, 7450580596923828125UL,
+ 389 + + };
+ 390 + + #ifdef BOOST_JSON_FASTFLOAT_64BIT_LIMB
+ 391 + + constexpr static limb large_power_of_5[] = {
+ 392 + + 1414648277510068013UL, 9180637584431281687UL, 4539964771860779200UL,
+ 393 + + 10482974169319127550UL, 198276706040285095UL};
+ 394 + + #else
+ 395 + + constexpr static limb large_power_of_5[] = {
+ 396 + + 4279965485U, 329373468U, 4020270615U, 2137533757U, 4287402176U,
+ 397 + + 1057042919U, 1071430142U, 2440757623U, 381945767U, 46164893U};
+ 398 + + #endif
+ 399 + + };
+ 400 + +
+ 401 + + template <typename T>
+ 402 + + constexpr uint32_t pow5_tables<T>::large_step;
+ 403 + +
+ 404 + + template <typename T>
+ 405 + + constexpr uint64_t pow5_tables<T>::small_power_of_5[];
+ 406 + +
+ 407 + + template <typename T>
+ 408 + + constexpr limb pow5_tables<T>::large_power_of_5[];
+ 409 + +
+ 410 + + // big integer type. implements a small subset of big integer
+ 411 + + // arithmetic, using simple algorithms since asymptotically
+ 412 + + // faster algorithms are slower for a small number of limbs.
+ 413 + + // all operations assume the big-integer is normalized.
+ 414 + + struct bigint : pow5_tables<> {
+ 415 + + // storage of the limbs, in little-endian order.
+ 416 + + stackvec<bigint_limbs> vec;
+ 417 + +
+ 418 + +2986 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bigint(): vec() {}
+ 419 + + bigint(const bigint &) = delete;
+ 420 + + bigint &operator=(const bigint &) = delete;
+ 421 + + bigint(bigint &&) = delete;
+ 422 + + bigint &operator=(bigint &&other) = delete;
+ 423 + +
+ 424 + +1611 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bigint(uint64_t value): vec() {
+ 425 + + #ifdef BOOST_JSON_FASTFLOAT_64BIT_LIMB
+ 426 + +1611 vec.push_unchecked(value);
+ 427 + + #else
+ 428 + + vec.push_unchecked(uint32_t(value));
+ 429 + + vec.push_unchecked(uint32_t(value >> 32));
+ 430 + + #endif
+ 431 + +1611 vec.normalize();
+ 432 + +1611 }
+ 433 + +
+ 434 + + // get the high 64 bits from the vector, and if bits were truncated.
+ 435 + + // this is to get the significant digits for the float.
+ 436 + +1375 BOOST_JSON_FASTFLOAT_CONSTEXPR20 uint64_t hi64(bool& truncated) const noexcept {
+ 437 + + #ifdef BOOST_JSON_FASTFLOAT_64BIT_LIMB
+ 438 + +1375 if (vec.len() == 0) {
+ 439 + + return empty_hi64(truncated);
+ 440 + +1375 } else if (vec.len() == 1) {
+ 441 + + return uint64_hi64(vec.rindex(0), truncated);
+ 442 + + } else {
+ 443 + +1375 uint64_t result = uint64_hi64(vec.rindex(0), vec.rindex(1), truncated);
+ 444 + +1375 truncated |= vec.nonzero(2);
+ 445 + +1375 return result;
+ 446 + + }
+ 447 + + #else
+ 448 + + if (vec.len() == 0) {
+ 449 + + return empty_hi64(truncated);
+ 450 + + } else if (vec.len() == 1) {
+ 451 + + return uint32_hi64(vec.rindex(0), truncated);
+ 452 + + } else if (vec.len() == 2) {
+ 453 + + return uint32_hi64(vec.rindex(0), vec.rindex(1), truncated);
+ 454 + + } else {
+ 455 + + uint64_t result = uint32_hi64(vec.rindex(0), vec.rindex(1), vec.rindex(2), truncated);
+ 456 + + truncated |= vec.nonzero(3);
+ 457 + + return result;
+ 458 + + }
+ 459 + + #endif
+ 460 + + }
+ 461 + +
+ 462 + + // compare two big integers, returning the large value.
+ 463 + + // assumes both are normalized. if the return value is
+ 464 + + // negative, other is larger, if the return value is
+ 465 + + // positive, this is larger, otherwise they are equal.
+ 466 + + // the limbs are stored in little-endian order, so we
+ 467 + + // must compare the limbs in ever order.
+ 468 + +1611 BOOST_JSON_FASTFLOAT_CONSTEXPR20 int compare(const bigint& other) const noexcept {
+ 469 + +1611 if (vec.len() > other.vec.len()) {
+ 470 + + return 1;
+ 471 + +1611 } else if (vec.len() < other.vec.len()) {
+ 472 + + return -1;
+ 473 + + } else {
+ 474 + +3099 for (size_t index = vec.len(); index > 0; index--) {
+ 475 + +3099 limb xi = vec[index - 1];
+ 476 + +3099 limb yi = other.vec[index - 1];
+ 477 + +3099 if (xi > yi) {
+ 478 + +767 return 1;
+ 479 + +2332 } else if (xi < yi) {
+ 480 + +844 return -1;
+ 481 + + }
+ 482 + + }
+ 483 + + return 0;
+ 484 + + }
+ 485 + + }
+ 486 + +
+ 487 + + // shift left each limb n bits, carrying over to the new limb
+ 488 + + // returns true if we were able to shift all the digits.
+ 489 + +2931 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool shl_bits(size_t n) noexcept {
+ 490 + + // Internally, for each item, we shift left by n, and add the previous
+ 491 + + // right shifted limb-bits.
+ 492 + + // For example, we transform (for u8) shifted left 2, to:
+ 493 + + // b10100100 b01000010
+ 494 + + // b10 b10010001 b00001000
+ 495 + +2931 BOOST_ASSERT(n != 0);
+ 496 + +2931 BOOST_ASSERT(n < sizeof(limb) * 8);
+ 497 + +
+ 498 + +2931 size_t shl = n;
+ 499 + +2931 size_t shr = limb_bits - shl;
+ 500 + +2931 limb prev = 0;
+ 501 + +17014 for (size_t index = 0; index < vec.len(); index++) {
+ 502 + +14083 limb xi = vec[index];
+ 503 + +14083 vec[index] = (xi << shl) | (prev >> shr);
+ 504 + +14083 prev = xi;
+ 505 + + }
+ 506 + +
+ 507 + +2931 limb carry = prev >> shr;
+ 508 + +2931 if (carry != 0) {
+ 509 + +1534 return vec.try_push(carry);
+ 510 + + }
+ 511 + +1397 return true;
+ 512 + + }
+ 513 + +
+ 514 + + // move the limbs left by `n` limbs.
+ 515 + +2414 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool shl_limbs(size_t n) noexcept {
+ 516 + +2414 BOOST_ASSERT(n != 0);
+ 517 + +2414 if (n + vec.len() > vec.capacity()) {
+ 518 + + return false;
+ 519 + +2414 } else if (!vec.is_empty()) {
+ 520 + + // move limbs
+ 521 + +2414 limb* dst = vec.data + n;
+ 522 + +2414 const limb* src = vec.data;
+ 523 + +2414 std::copy_backward(src, src + vec.len(), dst + vec.len());
+ 524 + + // fill in empty limbs
+ 525 + +2414 limb* first = vec.data;
+ 526 + +2414 limb* last = first + n;
+ 527 + +2414 ::std::fill(first, last, 0);
+ 528 + +2414 vec.set_len(n + vec.len());
+ 529 + +2414 return true;
+ 530 + + } else {
+ 531 + + return true;
+ 532 + + }
+ 533 + + }
+ 534 + +
+ 535 + + // move the limbs left by `n` bits.
+ 536 + +2984 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool shl(size_t n) noexcept {
+ 537 + +2984 size_t rem = n % limb_bits;
+ 538 + +2984 size_t div = n / limb_bits;
+ 539 + +2984 if (rem != 0) {
+ 540 + +2931 BOOST_JSON_FASTFLOAT_TRY(shl_bits(rem));
+ 541 + + }
+ 542 + +2984 if (div != 0) {
+ 543 + +2414 BOOST_JSON_FASTFLOAT_TRY(shl_limbs(div));
+ 544 + + }
+ 545 + +2984 return true;
+ 546 + + }
+ 547 + +
+ 548 + + // get the number of leading zeros in the bigint.
+ 549 + +1375 BOOST_JSON_FASTFLOAT_CONSTEXPR20 int ctlz() const noexcept {
+ 550 + +1375 if (vec.is_empty()) {
+ 551 + + return 0;
+ 552 + + } else {
+ 553 + + #ifdef BOOST_JSON_FASTFLOAT_64BIT_LIMB
+ 554 + +2750 return leading_zeroes(vec.rindex(0));
+ 555 + + #else
+ 556 + + // no use defining a specialized leading_zeroes for a 32-bit type.
+ 557 + + uint64_t r0 = vec.rindex(0);
+ 558 + + return leading_zeroes(r0 << 32);
+ 559 + + #endif
+ 560 + + }
+ 561 + + }
+ 562 + +
+ 563 + + // get the number of bits in the bigint.
+ 564 + +1375 BOOST_JSON_FASTFLOAT_CONSTEXPR20 int bit_length() const noexcept {
+ 565 + +1375 int lz = ctlz();
+ 566 + +1375 return int(limb_bits * vec.len()) - lz;
+ 567 + + }
+ 568 + +
+ 569 + +9437 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool mul(limb y) noexcept {
+ 570 + +9437 return small_mul(vec, y);
+ 571 + + }
+ 572 + +
+ 573 + +9437 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool add(limb y) noexcept {
+ 574 + +18874 return small_add(vec, y);
+ 575 + + }
+ 576 + +
+ 577 + + // multiply as if by 2 raised to a power.
+ 578 + +2984 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool pow2(uint32_t exp) noexcept {
+ 579 + +2984 return shl(exp);
+ 580 + + }
+ 581 + +
+ 582 + + // multiply as if by 5 raised to a power.
+ 583 + +2986 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool pow5(uint32_t exp) noexcept {
+ 584 + + // multiply by a power of 5
+ 585 + +2986 constexpr size_t large_length = sizeof(large_power_of_5) / sizeof(limb);
+ 586 + +2986 limb_span large = limb_span(large_power_of_5, large_length);
+ 587 + +5010 while (exp >= large_step) {
+ 588 + +2024 BOOST_JSON_FASTFLOAT_TRY(large_mul(vec, large));
+ 589 + +2024 exp -= large_step;
+ 590 + + }
+ 591 + + #ifdef BOOST_JSON_FASTFLOAT_64BIT_LIMB
+ 592 + +2986 constexpr uint32_t small_step = 27;
+ 593 + +2986 constexpr limb max_native = 7450580596923828125UL;
+ 594 + + #else
+ 595 + + constexpr uint32_t small_step = 13;
+ 596 + + constexpr limb max_native = 1220703125U;
+ 597 + + #endif
+ 598 + +8590 while (exp >= small_step) {
+ 599 + +5604 BOOST_JSON_FASTFLOAT_TRY(small_mul(vec, max_native));
+ 600 + +5604 exp -= small_step;
+ 601 + + }
+ 602 + +2986 if (exp != 0) {
+ 603 + + // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ 604 + + // This is similar to https://github.com/llvm/llvm-project/issues/47746,
+ 605 + + // except the workaround described there don't work here
+ 606 + +2868 BOOST_JSON_FASTFLOAT_TRY(
+ 607 + + small_mul(vec, limb(((void)small_power_of_5[0], small_power_of_5[exp])))
+ 608 + + );
+ 609 + + }
+ 610 + +
+ 611 + +2986 return true;
+ 612 + + }
+ 613 + +
+ 614 + + // multiply as if by 10 raised to a power.
+ 615 + +1375 BOOST_JSON_FASTFLOAT_CONSTEXPR20 bool pow10(uint32_t exp) noexcept {
+ 616 + +1375 BOOST_JSON_FASTFLOAT_TRY(pow5(exp));
+ 617 + +1375 return pow2(exp);
+ 618 + + }
+ 619 + + };
+ 620 + +
+ 621 + + }}}}}} // namespace fast_float
+ 622 + +
+ 623 + + #endif
+ 624 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.buffer.hpp.55b2280adf5814131719bffc56d99e63.html b/json/gcovr/index.buffer.hpp.55b2280adf5814131719bffc56d99e63.html new file mode 100644 index 00000000..1de89325 --- /dev/null +++ b/json/gcovr/index.buffer.hpp.55b2280adf5814131719bffc56d99e63.html @@ -0,0 +1,3278 @@ + + + + + + detail/buffer.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/buffer.hpp

+
+ + 100.0% Lines (44/44) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/buffer.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_BUFFER_HPP
+ 11 + + #define BOOST_JSON_DETAIL_BUFFER_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/json/string_view.hpp>
+ 15 + + #include <cstring>
+ 16 + +
+ 17 + + namespace boost {
+ 18 + + namespace json {
+ 19 + + namespace detail {
+ 20 + +
+ 21 + + // A simple string-like temporary static buffer
+ 22 + + template<std::size_t N>
+ 23 + + class buffer
+ 24 + + {
+ 25 + + public:
+ 26 + + using size_type = std::size_t;
+ 27 + +
+ 28 + +13678 buffer() = default;
+ 29 + +
+ 30 + + bool
+ 31 + +9362 empty() const noexcept
+ 32 + + {
+ 33 + +9362 return size_ == 0;
+ 34 + + }
+ 35 + +
+ 36 + + string_view
+ 37 + +10691 get() const noexcept
+ 38 + + {
+ 39 + +10691 return {buf_, size_};
+ 40 + + }
+ 41 + +
+ 42 + + operator string_view() const noexcept
+ 43 + + {
+ 44 + + return get();
+ 45 + + }
+ 46 + +
+ 47 + + char const*
+ 48 + + data() const noexcept
+ 49 + + {
+ 50 + + return buf_;
+ 51 + + }
+ 52 + +
+ 53 + + size_type
+ 54 + +30251 size() const noexcept
+ 55 + + {
+ 56 + +30251 return size_;
+ 57 + + }
+ 58 + +
+ 59 + + size_type
+ 60 + +17244 capacity() const noexcept
+ 61 + + {
+ 62 + +17244 return N - size_;
+ 63 + + }
+ 64 + +
+ 65 + + size_type
+ 66 + +15663 max_size() const noexcept
+ 67 + + {
+ 68 + +15663 return N;
+ 69 + + }
+ 70 + +
+ 71 + + void
+ 72 + +1524 clear() noexcept
+ 73 + + {
+ 74 + +1524 size_ = 0;
+ 75 + +1524 }
+ 76 + +
+ 77 + + void
+ 78 + +2934 push_back(char ch) noexcept
+ 79 + + {
+ 80 + +2934 BOOST_ASSERT(capacity() > 0);
+ 81 + +2934 buf_[size_++] = ch;
+ 82 + +2934 }
+ 83 + +
+ 84 + + // append an unescaped string
+ 85 + + void
+ 86 + + append(
+ 87 + + char const* s,
+ 88 + + size_type n)
+ 89 + + {
+ 90 + + BOOST_ASSERT(n <= N - size_);
+ 91 + + std::memcpy(buf_ + size_, s, n);
+ 92 + + size_ += n;
+ 93 + + }
+ 94 + +
+ 95 + + // append valid 32-bit code point as utf8
+ 96 + + void
+ 97 + +11989 append_utf8(
+ 98 + + unsigned long cp) noexcept
+ 99 + + {
+ 100 + +11989 auto dest = buf_ + size_;
+ 101 + +11989 if(cp < 0x80)
+ 102 + + {
+ 103 + +1137 BOOST_ASSERT(size_ <= N - 1);
+ 104 + +1137 dest[0] = static_cast<char>(cp);
+ 105 + +1137 size_ += 1;
+ 106 + +1137 return;
+ 107 + + }
+ 108 + +
+ 109 + +10852 if(cp < 0x800)
+ 110 + + {
+ 111 + +319 BOOST_ASSERT(size_ <= N - 2);
+ 112 + +319 dest[0] = static_cast<char>( (cp >> 6) | 0xc0);
+ 113 + +319 dest[1] = static_cast<char>( (cp & 0x3f) | 0x80);
+ 114 + +319 size_ += 2;
+ 115 + +319 return;
+ 116 + + }
+ 117 + +
+ 118 + +10533 if(cp < 0x10000)
+ 119 + + {
+ 120 + +7240 BOOST_ASSERT(size_ <= N - 3);
+ 121 + +7240 dest[0] = static_cast<char>( (cp >> 12) | 0xe0);
+ 122 + +7240 dest[1] = static_cast<char>(((cp >> 6) & 0x3f) | 0x80);
+ 123 + +7240 dest[2] = static_cast<char>( (cp & 0x3f) | 0x80);
+ 124 + +7240 size_ += 3;
+ 125 + +7240 return;
+ 126 + + }
+ 127 + +
+ 128 + + {
+ 129 + +3293 BOOST_ASSERT(size_ <= N - 4);
+ 130 + +3293 dest[0] = static_cast<char>( (cp >> 18) | 0xf0);
+ 131 + +3293 dest[1] = static_cast<char>(((cp >> 12) & 0x3f) | 0x80);
+ 132 + +3293 dest[2] = static_cast<char>(((cp >> 6) & 0x3f) | 0x80);
+ 133 + +3293 dest[3] = static_cast<char>( (cp & 0x3f) | 0x80);
+ 134 + +3293 size_ += 4;
+ 135 + + }
+ 136 + + }
+ 137 + + private:
+ 138 + + char buf_[N];
+ 139 + + size_type size_ = 0;
+ 140 + + };
+ 141 + +
+ 142 + + } // detail
+ 143 + + } // namespace json
+ 144 + + } // namespace boost
+ 145 + +
+ 146 + + #endif
+ 147 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.charconv.510f5dd29cc43eca58c0d2b93adff045.html b/json/gcovr/index.charconv.510f5dd29cc43eca58c0d2b93adff045.html new file mode 100644 index 00000000..5da6fae8 --- /dev/null +++ b/json/gcovr/index.charconv.510f5dd29cc43eca58c0d2b93adff045.html @@ -0,0 +1,2188 @@ + + + + + + detail/charconv/ - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+
+

Lines

+
+
+
+ + + + + 93.3% +
+
+
+ Hit + 8225 +
+
+ Total + 8811 +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+
+ +
+ High: ≥ 90.0% + Medium: ≥ 75.0% + Low: < 75.0% +
+ +
+
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+
+ +
+
+ +
+ + + + detail +
+ +
+
+
+
+ 53.2% +
+ +
+ 584 + / + 1097 +
+ + +
+
+ + + +
+
+
+
+ 25.0% +
+ +
+ 3 + / + 12 +
+ + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.common.hpp.98695bbba488db8061085c97a91bfff6.html b/json/gcovr/index.common.hpp.98695bbba488db8061085c97a91bfff6.html new file mode 100644 index 00000000..69c4be79 --- /dev/null +++ b/json/gcovr/index.common.hpp.98695bbba488db8061085c97a91bfff6.html @@ -0,0 +1,3262 @@ + + + + + + detail/ryu/detail/common.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/ryu/detail/common.hpp

+
+ + 100.0% Lines (38/38) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/ryu/detail/common.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2018 Ulf Adams
+ 2 + + //
+ 3 + + // The contents of this file may be used under the terms of the Apache License,
+ 4 + + // Version 2.0.
+ 5 + + //
+ 6 + + // (See accompanying file LICENSE-Apache or copy at
+ 7 + + // http://www.apache.org/licenses/LICENSE-2.0)
+ 8 + + //
+ 9 + + // Alternatively, the contents of this file may be used under the terms of
+ 10 + + // the Boost Software License, Version 1.0.
+ 11 + + // (See accompanying file LICENSE-Boost or copy at
+ 12 + + // https://www.boost.org/LICENSE_1_0.txt)
+ 13 + + //
+ 14 + + // Unless required by applicable law or agreed to in writing, this software
+ 15 + + // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ 16 + + // KIND, either express or implied.
+ 17 + +
+ 18 + + /*
+ 19 + + This is a derivative work
+ 20 + + */
+ 21 + +
+ 22 + + #ifndef BOOST_JSON_DETAIL_RYU_DETAIL_COMMON_HPP
+ 23 + + #define BOOST_JSON_DETAIL_RYU_DETAIL_COMMON_HPP
+ 24 + +
+ 25 + + #include <boost/json/detail/config.hpp>
+ 26 + + #include <string.h>
+ 27 + +
+ 28 + + namespace boost {
+ 29 + + namespace json {
+ 30 + + namespace detail {
+ 31 + +
+ 32 + + namespace ryu {
+ 33 + + namespace detail {
+ 34 + +
+ 35 + + constexpr int DOUBLE_MANTISSA_BITS = 52;
+ 36 + + constexpr int DOUBLE_EXPONENT_BITS = 11;
+ 37 + + constexpr int DOUBLE_BIAS = 1023;
+ 38 + +
+ 39 + + #if defined(_M_IX86) || defined(_M_ARM)
+ 40 + + #define BOOST_JSON_RYU_32_BIT_PLATFORM
+ 41 + + #endif
+ 42 + +
+ 43 + + inline uint32_t decimalLength9(const uint32_t v) {
+ 44 + + // Function precondition: v is not a 10-digit number.
+ 45 + + // (f2s: 9 digits are sufficient for round-tripping.)
+ 46 + + // (d2fixed: We print 9-digit blocks.)
+ 47 + + BOOST_ASSERT(v < 1000000000);
+ 48 + + if (v >= 100000000) { return 9; }
+ 49 + + if (v >= 10000000) { return 8; }
+ 50 + + if (v >= 1000000) { return 7; }
+ 51 + + if (v >= 100000) { return 6; }
+ 52 + + if (v >= 10000) { return 5; }
+ 53 + + if (v >= 1000) { return 4; }
+ 54 + + if (v >= 100) { return 3; }
+ 55 + + if (v >= 10) { return 2; }
+ 56 + + return 1;
+ 57 + + }
+ 58 + +
+ 59 + + // Returns e == 0 ? 1 : ceil(log_2(5^e)).
+ 60 + +2634 inline int32_t pow5bits(const int32_t e) {
+ 61 + + // This approximation works up to the point that the multiplication overflows at e = 3529.
+ 62 + + // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater
+ 63 + + // than 2^9297.
+ 64 + +2634 BOOST_ASSERT(e >= 0);
+ 65 + +2634 BOOST_ASSERT(e <= 3528);
+ 66 + +2634 return (int32_t) (((((uint32_t) e) * 1217359) >> 19) + 1);
+ 67 + + }
+ 68 + +
+ 69 + + // Returns floor(log_10(2^e)).
+ 70 + +128 inline uint32_t log10Pow2(const int32_t e) {
+ 71 + + // The first value this approximation fails for is 2^1651 which is just greater than 10^297.
+ 72 + +128 BOOST_ASSERT(e >= 0);
+ 73 + +128 BOOST_ASSERT(e <= 1650);
+ 74 + +128 return (((uint32_t) e) * 78913) >> 18;
+ 75 + + }
+ 76 + +
+ 77 + + // Returns floor(log_10(5^e)).
+ 78 + +134 inline uint32_t log10Pow5(const int32_t e) {
+ 79 + + // The first value this approximation fails for is 5^2621 which is just greater than 10^1832.
+ 80 + +134 BOOST_ASSERT(e >= 0);
+ 81 + +134 BOOST_ASSERT(e <= 2620);
+ 82 + +134 return (((uint32_t) e) * 732923) >> 20;
+ 83 + + }
+ 84 + +
+ 85 + +11 inline int copy_special_str(char * const result, const bool sign, const bool exponent, const bool mantissa) {
+ 86 + +11 if (mantissa) {
+ 87 + +3 memcpy(result, "NaN", 3);
+ 88 + +3 return 3;
+ 89 + + }
+ 90 + +8 if (sign) {
+ 91 + +4 result[0] = '-';
+ 92 + + }
+ 93 + +8 if (exponent) {
+ 94 + +6 memcpy(result + sign, "Infinity", 8);
+ 95 + +6 return sign + 8;
+ 96 + + }
+ 97 + +2 memcpy(result + sign, "0E0", 3);
+ 98 + +2 return sign + 3;
+ 99 + + }
+ 100 + +
+ 101 + + inline
+ 102 + + int
+ 103 + +60 copy_special_str_conforming(
+ 104 + + char* const result, bool sign, bool exponent, bool mantissa)
+ 105 + + {
+ 106 + +60 if (mantissa)
+ 107 + + {
+ 108 + +3 memcpy(result, "null", 4);
+ 109 + +3 return 4;
+ 110 + + }
+ 111 + +
+ 112 + +57 if (sign)
+ 113 + +20 result[0] = '-';
+ 114 + +
+ 115 + +57 if (exponent)
+ 116 + + {
+ 117 + +6 memcpy(result + sign, "1e99999", 7);
+ 118 + +6 return sign + 7;
+ 119 + + }
+ 120 + +
+ 121 + +51 memcpy(result + sign, "0E0", 3);
+ 122 + +51 return sign + 3;
+ 123 + + }
+ 124 + +
+ 125 + + inline uint32_t float_to_bits(const float f) {
+ 126 + + uint32_t bits = 0;
+ 127 + + memcpy(&bits, &f, sizeof(float));
+ 128 + + return bits;
+ 129 + + }
+ 130 + +
+ 131 + +609 inline uint64_t double_to_bits(const double d) {
+ 132 + +609 uint64_t bits = 0;
+ 133 + +609 memcpy(&bits, &d, sizeof(double));
+ 134 + +609 return bits;
+ 135 + + }
+ 136 + +
+ 137 + + } // detail
+ 138 + + } // ryu
+ 139 + +
+ 140 + + } // detail
+ 141 + + } // namespace json
+ 142 + + } // namespace boost
+ 143 + +
+ 144 + + #endif
+ 145 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.compute_float64.hpp.14da4b5c079d398c9d8067d0d7a811dc.html b/json/gcovr/index.compute_float64.hpp.14da4b5c079d398c9d8067d0d7a811dc.html new file mode 100644 index 00000000..0ab3cf8b --- /dev/null +++ b/json/gcovr/index.compute_float64.hpp.14da4b5c079d398c9d8067d0d7a811dc.html @@ -0,0 +1,3718 @@ + + + + + + detail/charconv/detail/compute_float64.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/compute_float64.hpp

+
+ + 0.0% Lines (0/53) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/compute_float64.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2020-2023 Daniel Lemire
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + +
+ 6 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_COMPUTE_FLOAT64_HPP
+ 7 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_COMPUTE_FLOAT64_HPP
+ 8 + +
+ 9 + + #include <boost/json/detail/charconv/detail/config.hpp>
+ 10 + + #include <boost/json/detail/charconv/detail/significand_tables.hpp>
+ 11 + + #include <boost/json/detail/charconv/detail/emulated128.hpp>
+ 12 + + #include <boost/core/bit.hpp>
+ 13 + + #include <cstdint>
+ 14 + + #include <cfloat>
+ 15 + + #include <cstring>
+ 16 + + #include <cmath>
+ 17 + +
+ 18 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail {
+ 19 + +
+ 20 + + static constexpr double powers_of_ten[] = {
+ 21 + + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
+ 22 + + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22
+ 23 + + };
+ 24 + +
+ 25 + + // Attempts to compute i * 10^(power) exactly; and if "negative" is true, negate the result.
+ 26 + + //
+ 27 + + // This function will only work in some cases, when it does not work, success is
+ 28 + + // set to false. This should work *most of the time* (like 99% of the time).
+ 29 + + // We assume that power is in the [-325, 308] interval.
+ 30 + + inline double compute_float64(std::int64_t power, std::uint64_t i, bool negative, bool& success) noexcept
+ 31 + + {
+ 32 + + static constexpr auto smallest_power = -325;
+ 33 + + static constexpr auto largest_power = 308;
+ 34 + +
+ 35 + + // We start with a fast path
+ 36 + + // It was described in Clinger WD.
+ 37 + + // How to read floating point numbers accurately.
+ 38 + + // ACM SIGPLAN Notices. 1990
+ 39 + + #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
+ 40 + + if (0 <= power && power <= 22 && i <= UINT64_C(9007199254740991))
+ 41 + + #else
+ 42 + + if (-22 <= power && power <= 22 && i <= UINT64_C(9007199254740991))
+ 43 + + #endif
+ 44 + + {
+ 45 + + // The general idea is as follows.
+ 46 + + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then
+ 47 + + // 1) Both s and p can be represented exactly as 64-bit floating-point
+ 48 + + // values
+ 49 + + // (binary64).
+ 50 + + // 2) Because s and p can be represented exactly as floating-point values,
+ 51 + + // then s * p
+ 52 + + // and s / p will produce correctly rounded values.
+ 53 + +
+ 54 + + auto d = static_cast<double>(i);
+ 55 + +
+ 56 + + if (power < 0)
+ 57 + + {
+ 58 + + d = d / powers_of_ten[-power];
+ 59 + + }
+ 60 + + else
+ 61 + + {
+ 62 + + d = d * powers_of_ten[power];
+ 63 + + }
+ 64 + +
+ 65 + + if (negative)
+ 66 + + {
+ 67 + + d = -d;
+ 68 + + }
+ 69 + +
+ 70 + + success = true;
+ 71 + + return d;
+ 72 + + }
+ 73 + +
+ 74 + + // When 22 < power && power < 22 + 16, we could
+ 75 + + // hope for another, secondary fast path. It was
+ 76 + + // described by David M. Gay in "Correctly rounded
+ 77 + + // binary-decimal and decimal-binary conversions." (1990)
+ 78 + + // If you need to compute i * 10^(22 + x) for x < 16,
+ 79 + + // first compute i * 10^x, if you know that result is exact
+ 80 + + // (e.g., when i * 10^x < 2^53),
+ 81 + + // then you can still proceed and do (i * 10^x) * 10^22.
+ 82 + + // Is this worth your time?
+ 83 + + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53)
+ 84 + + // for this second fast path to work.
+ 85 + + // If you have 22 < power *and* power < 22 + 16, and then you
+ 86 + + // optimistically compute "i * 10^(x-22)", there is still a chance that you
+ 87 + + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of
+ 88 + + // this optimization maybe less common than we would like. Source:
+ 89 + + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
+ 90 + + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html
+ 91 + +
+ 92 + + if (i == 0 || power < smallest_power)
+ 93 + + {
+ 94 + + return negative ? -0.0 : 0.0;
+ 95 + + }
+ 96 + + else if (power > largest_power)
+ 97 + + {
+ 98 + + return negative ? -HUGE_VAL : HUGE_VAL;
+ 99 + + }
+ 100 + +
+ 101 + + const std::uint64_t factor_significand = significand_64[power - smallest_power];
+ 102 + + const std::int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63;
+ 103 + + int leading_zeros = boost::core::countl_zero(i);
+ 104 + + i <<= static_cast<std::uint64_t>(leading_zeros);
+ 105 + +
+ 106 + + uint128 product = umul128(i, factor_significand);
+ 107 + + std::uint64_t low = product.low;
+ 108 + + std::uint64_t high = product.high;
+ 109 + +
+ 110 + + // We know that upper has at most one leading zero because
+ 111 + + // both i and factor_mantissa have a leading one. This means
+ 112 + + // that the result is at least as large as ((1<<63)*(1<<63))/(1<<64).
+ 113 + + //
+ 114 + + // As long as the first 9 bits of "upper" are not "1", then we
+ 115 + + // know that we have an exact computed value for the leading
+ 116 + + // 55 bits because any imprecision would play out as a +1, in the worst case.
+ 117 + + // Having 55 bits is necessary because we need 53 bits for the mantissa,
+ 118 + + // but we have to have one rounding bit and, we can waste a bit if the most
+ 119 + + // significant bit of the product is zero.
+ 120 + + //
+ 121 + + // We expect this next branch to be rarely taken (say 1% of the time).
+ 122 + + // When (upper & 0x1FF) == 0x1FF, it can be common for
+ 123 + + // lower + i < lower to be true (proba. much higher than 1%).
+ 124 + + if (BOOST_UNLIKELY((high & 0x1FF) == 0x1FF) && (low + i < low))
+ 125 + + {
+ 126 + + const std::uint64_t factor_significand_low = significand_128[power - smallest_power];
+ 127 + + product = umul128(i, factor_significand_low);
+ 128 + + //const std::uint64_t product_low = product.low;
+ 129 + + const std::uint64_t product_middle2 = product.high;
+ 130 + + const std::uint64_t product_middle1 = low;
+ 131 + + std::uint64_t product_high = high;
+ 132 + + const std::uint64_t product_middle = product_middle1 + product_middle2;
+ 133 + +
+ 134 + + if (product_middle < product_middle1)
+ 135 + + {
+ 136 + + product_high++;
+ 137 + + }
+ 138 + +
+ 139 + + // Commented out because possibly unneeded
+ 140 + + // See: https://arxiv.org/pdf/2212.06644.pdf
+ 141 + + /*
+ 142 + + // we want to check whether mantissa *i + i would affect our result
+ 143 + + // This does happen, e.g. with 7.3177701707893310e+15
+ 144 + + if (((product_middle + 1 == 0) && ((product_high & 0x1FF) == 0x1FF) && (product_low + i < product_low)))
+ 145 + + {
+ 146 + + success = false;
+ 147 + + return 0;
+ 148 + + }
+ 149 + + */
+ 150 + +
+ 151 + + low = product_middle;
+ 152 + + high = product_high;
+ 153 + + }
+ 154 + +
+ 155 + + // The final significand should be 53 bits with a leading 1
+ 156 + + // We shift it so that it occupies 54 bits with a leading 1
+ 157 + + const std::uint64_t upper_bit = high >> 63;
+ 158 + + std::uint64_t significand = high >> (upper_bit + 9);
+ 159 + + leading_zeros += static_cast<int>(1 ^ upper_bit);
+ 160 + +
+ 161 + + // If we have lots of trailing zeros we may fall between two values
+ 162 + + if (BOOST_UNLIKELY((low == 0) && ((high & 0x1FF) == 0) && ((significand & 3) == 1)))
+ 163 + + {
+ 164 + + // if significand & 1 == 1 we might need to round up
+ 165 + + success = false;
+ 166 + + return 0;
+ 167 + + }
+ 168 + +
+ 169 + + significand += significand & 1;
+ 170 + + significand >>= 1;
+ 171 + +
+ 172 + + // Here the significand < (1<<53), unless there is an overflow
+ 173 + + if (significand >= (UINT64_C(1) << 53))
+ 174 + + {
+ 175 + + significand = (UINT64_C(1) << 52);
+ 176 + + leading_zeros--;
+ 177 + + }
+ 178 + +
+ 179 + + significand &= ~(UINT64_C(1) << 52);
+ 180 + + const std::uint64_t real_exponent = exponent - leading_zeros;
+ 181 + +
+ 182 + + // We have to check that real_exponent is in range, otherwise fail
+ 183 + + if (BOOST_UNLIKELY((real_exponent < 1) || (real_exponent > 2046)))
+ 184 + + {
+ 185 + + success = false;
+ 186 + + return 0;
+ 187 + + }
+ 188 + +
+ 189 + + significand |= real_exponent << 52;
+ 190 + + significand |= ((static_cast<std::uint64_t>(negative) << 63));
+ 191 + +
+ 192 + + double d;
+ 193 + + std::memcpy(&d, &significand, sizeof(d));
+ 194 + +
+ 195 + + success = true;
+ 196 + + return d;
+ 197 + + }
+ 198 + +
+ 199 + + }}}}} // Namespaces
+ 200 + +
+ 201 + + #endif // BOOST_JSON_DETAIL_CHARCONV_DETAIL_COMPUTE_FLOAT64_HPP
+ 202 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.config.hpp.0a32ee1b4391ae1eeb404af25739161a.html b/json/gcovr/index.config.hpp.0a32ee1b4391ae1eeb404af25739161a.html new file mode 100644 index 00000000..7a6d66a5 --- /dev/null +++ b/json/gcovr/index.config.hpp.0a32ee1b4391ae1eeb404af25739161a.html @@ -0,0 +1,4022 @@ + + + + + + detail/config.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/config.hpp

+
+ + 100.0% Lines (4/4) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/config.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_CONFIG_HPP
+ 11 + + #define BOOST_JSON_DETAIL_CONFIG_HPP
+ 12 + +
+ 13 + + #include <boost/config.hpp>
+ 14 + + #include <boost/config/pragma_message.hpp>
+ 15 + + #include <boost/assert.hpp>
+ 16 + + #include <boost/throw_exception.hpp>
+ 17 + + #include <cstdint>
+ 18 + + #include <type_traits>
+ 19 + + #include <utility>
+ 20 + +
+ 21 + + // detect 32/64 bit
+ 22 + + #if UINTPTR_MAX == UINT64_MAX
+ 23 + + # define BOOST_JSON_ARCH 64
+ 24 + + #elif UINTPTR_MAX == UINT32_MAX
+ 25 + + # define BOOST_JSON_ARCH 32
+ 26 + + #else
+ 27 + + # error Unknown or unsupported architecture, please open an issue
+ 28 + + #endif
+ 29 + +
+ 30 + + #ifndef BOOST_JSON_REQUIRE_CONST_INIT
+ 31 + + # define BOOST_JSON_REQUIRE_CONST_INIT
+ 32 + + # if __cpp_constinit >= 201907L
+ 33 + + # undef BOOST_JSON_REQUIRE_CONST_INIT
+ 34 + + # define BOOST_JSON_REQUIRE_CONST_INIT constinit
+ 35 + + # elif defined(__clang__) && defined(__has_cpp_attribute)
+ 36 + + # if __has_cpp_attribute(clang::require_constant_initialization)
+ 37 + + # undef BOOST_JSON_REQUIRE_CONST_INIT
+ 38 + + # define BOOST_JSON_REQUIRE_CONST_INIT [[clang::require_constant_initialization]]
+ 39 + + # endif
+ 40 + + # endif
+ 41 + + #endif
+ 42 + +
+ 43 + + #ifndef BOOST_JSON_NO_DESTROY
+ 44 + + # if defined(__clang__) && defined(__has_cpp_attribute)
+ 45 + + # if __has_cpp_attribute(clang::no_destroy)
+ 46 + + # define BOOST_JSON_NO_DESTROY [[clang::no_destroy]]
+ 47 + + # endif
+ 48 + + # endif
+ 49 + + #endif
+ 50 + +
+ 51 + + #if ! defined(BOOST_JSON_NO_SSE2) && \
+ 52 + + ! defined(BOOST_JSON_USE_SSE2)
+ 53 + + # if (defined(_M_IX86) && _M_IX86_FP == 2) || \
+ 54 + + defined(_M_X64) || defined(__SSE2__)
+ 55 + + # define BOOST_JSON_USE_SSE2
+ 56 + + # endif
+ 57 + + #endif
+ 58 + +
+ 59 + + #if defined(BOOST_JSON_DOCS)
+ 60 + + # define BOOST_JSON_DECL
+ 61 + + #else
+ 62 + + # if (defined(BOOST_JSON_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_JSON_STATIC_LINK)
+ 63 + + # if defined(BOOST_JSON_SOURCE)
+ 64 + + # define BOOST_JSON_DECL BOOST_SYMBOL_EXPORT
+ 65 + + # else
+ 66 + + # define BOOST_JSON_DECL BOOST_SYMBOL_IMPORT
+ 67 + + # endif
+ 68 + + # endif // shared lib
+ 69 + + # ifndef BOOST_JSON_DECL
+ 70 + + # define BOOST_JSON_DECL
+ 71 + + # endif
+ 72 + + # if !defined(BOOST_JSON_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_JSON_NO_LIB)
+ 73 + + # define BOOST_LIB_NAME boost_json
+ 74 + + # if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_JSON_DYN_LINK)
+ 75 + + # define BOOST_DYN_LINK
+ 76 + + # endif
+ 77 + + # include <boost/config/auto_link.hpp>
+ 78 + + # endif
+ 79 + + #endif
+ 80 + +
+ 81 + + #ifndef BOOST_JSON_LIKELY
+ 82 + + # define BOOST_JSON_LIKELY(x) BOOST_LIKELY( !!(x) )
+ 83 + + #endif
+ 84 + +
+ 85 + + #ifndef BOOST_JSON_UNLIKELY
+ 86 + + # define BOOST_JSON_UNLIKELY(x) BOOST_UNLIKELY( !!(x) )
+ 87 + + #endif
+ 88 + +
+ 89 + + #ifndef BOOST_JSON_UNREACHABLE
+ 90 + + # ifdef _MSC_VER
+ 91 + + # define BOOST_JSON_UNREACHABLE() __assume(0)
+ 92 + + # elif defined(__GNUC__) || defined(__clang__)
+ 93 + + # define BOOST_JSON_UNREACHABLE() __builtin_unreachable()
+ 94 + + # elif defined(__has_builtin)
+ 95 + + # if __has_builtin(__builtin_unreachable)
+ 96 + + # define BOOST_JSON_UNREACHABLE() __builtin_unreachable()
+ 97 + + # endif
+ 98 + + # else
+ 99 + + # define BOOST_JSON_UNREACHABLE() static_cast<void>(0)
+ 100 + + # endif
+ 101 + + #endif
+ 102 + +
+ 103 + + #ifndef BOOST_JSON_ASSUME
+ 104 + + # define BOOST_JSON_ASSUME(x) (!!(x) ? void() : BOOST_JSON_UNREACHABLE())
+ 105 + + # ifdef _MSC_VER
+ 106 + + # undef BOOST_JSON_ASSUME
+ 107 + + # define BOOST_JSON_ASSUME(x) __assume(!!(x))
+ 108 + + # elif defined(__has_builtin)
+ 109 + + # if __has_builtin(__builtin_assume)
+ 110 + + # undef BOOST_JSON_ASSUME
+ 111 + + # define BOOST_JSON_ASSUME(x) __builtin_assume(!!(x))
+ 112 + + # endif
+ 113 + + # endif
+ 114 + + #endif
+ 115 + +
+ 116 + + // older versions of msvc and clang don't always
+ 117 + + // constant initialize when they are supposed to
+ 118 + + #ifndef BOOST_JSON_WEAK_CONSTINIT
+ 119 + + # if defined(_MSC_VER) && ! defined(__clang__) && _MSC_VER < 1920
+ 120 + + # define BOOST_JSON_WEAK_CONSTINIT
+ 121 + + # elif defined(__clang__) && __clang_major__ < 4
+ 122 + + # define BOOST_JSON_WEAK_CONSTINIT
+ 123 + + # endif
+ 124 + + #endif
+ 125 + +
+ 126 + + // These macros are private, for tests, do not change
+ 127 + + // them or else previously built libraries won't match.
+ 128 + + #ifndef BOOST_JSON_MAX_STRING_SIZE
+ 129 + + # define BOOST_JSON_NO_MAX_STRING_SIZE
+ 130 + + # define BOOST_JSON_MAX_STRING_SIZE 0x7ffffffe
+ 131 + + #endif
+ 132 + + #ifndef BOOST_JSON_MAX_STRUCTURED_SIZE
+ 133 + + # define BOOST_JSON_NO_MAX_STRUCTURED_SIZE
+ 134 + + # define BOOST_JSON_MAX_STRUCTURED_SIZE 0x7ffffffe
+ 135 + + #endif
+ 136 + + #ifndef BOOST_JSON_STACK_BUFFER_SIZE
+ 137 + + # define BOOST_JSON_NO_STACK_BUFFER_SIZE
+ 138 + + # if defined(__i386__) || defined(__x86_64__) || \
+ 139 + + defined(_M_IX86) || defined(_M_X64)
+ 140 + + # define BOOST_JSON_STACK_BUFFER_SIZE 4096
+ 141 + + # else
+ 142 + + // If we are not on Intel, then assume we are on
+ 143 + + // embedded and use a smaller stack size. If this
+ 144 + + // is not suitable, the user can define the macro
+ 145 + + // themselves when building the library or including
+ 146 + + // src.hpp.
+ 147 + + # define BOOST_JSON_STACK_BUFFER_SIZE 256
+ 148 + + # endif
+ 149 + + #endif
+ 150 + +
+ 151 + + #if defined(__cpp_constinit) && __cpp_constinit >= 201907L
+ 152 + + # define BOOST_JSON_CONSTINIT constinit
+ 153 + + #elif defined(__has_cpp_attribute) && defined(__clang__)
+ 154 + + # if __has_cpp_attribute(clang::require_constant_initialization)
+ 155 + + # define BOOST_JSON_CONSTINIT [[clang::require_constant_initialization]]
+ 156 + + # endif
+ 157 + + #elif defined(__GNUC__) && (__GNUC__ >= 10)
+ 158 + + # define BOOST_JSON_CONSTINIT __constinit
+ 159 + + #endif
+ 160 + + #ifndef BOOST_JSON_CONSTINIT
+ 161 + + # define BOOST_JSON_CONSTINIT
+ 162 + + #endif
+ 163 + +
+ 164 + + namespace boost {
+ 165 + + namespace json {
+ 166 + + namespace detail {
+ 167 + +
+ 168 + + template<class...>
+ 169 + + struct make_void
+ 170 + + {
+ 171 + + using type =void;
+ 172 + + };
+ 173 + +
+ 174 + + template<class... Ts>
+ 175 + + using void_t = typename
+ 176 + + make_void<Ts...>::type;
+ 177 + +
+ 178 + + template<class T>
+ 179 + + using remove_cvref = typename
+ 180 + + std::remove_cv<typename
+ 181 + + std::remove_reference<T>::type>::type;
+ 182 + +
+ 183 + + template<class T, class U>
+ 184 + +25056816 T exchange(T& t, U u) noexcept
+ 185 + + {
+ 186 + +25056816 T v = std::move(t);
+ 187 + +25056816 t = std::move(u);
+ 188 + +25056816 return v;
+ 189 + + }
+ 190 + +
+ 191 + + /* This is a derivative work, original copyright:
+ 192 + +
+ 193 + + Copyright Eric Niebler 2013-present
+ 194 + +
+ 195 + + Use, modification and distribution is subject to the
+ 196 + + Boost Software License, Version 1.0. (See accompanying
+ 197 + + file LICENSE_1_0.txt or copy at
+ 198 + + http://www.boost.org/LICENSE_1_0.txt)
+ 199 + +
+ 200 + + Project home: https://github.com/ericniebler/range-v3
+ 201 + + */
+ 202 + + template<typename T>
+ 203 + + struct static_const
+ 204 + + {
+ 205 + + static constexpr T value {};
+ 206 + + };
+ 207 + + template<typename T>
+ 208 + + constexpr T static_const<T>::value;
+ 209 + +
+ 210 + + #define BOOST_JSON_INLINE_VARIABLE(name, type) \
+ 211 + + namespace { constexpr auto& name = \
+ 212 + + ::boost::json::detail::static_const<type>::value; \
+ 213 + + } struct _unused_ ## name ## _semicolon_bait_
+ 214 + +
+ 215 + + } // detail
+ 216 + + } // namespace json
+ 217 + + } // namespace boost
+ 218 + +
+ 219 + + #ifndef BOOST_JSON_ALLOW_DEPRECATED
+ 220 + + # ifdef BOOST_ALLOW_DEPRECATED
+ 221 + + # define BOOST_JSON_ALLOW_DEPRECATED
+ 222 + + # endif
+ 223 + + #endif
+ 224 + +
+ 225 + + #if defined(BOOST_GCC) && BOOST_GCC < 50000 && !defined(BOOST_JSON_ALLOW_DEPRECATED)
+ 226 + + # pragma GCC warning "Support for GCC versions below 5.0 is deprecated and will stop in Boost 1.88.0. To suppress this message define macro BOOST_JSON_ALLOW_DEPRECATED."
+ 227 + + #endif
+ 228 + +
+ 229 + + #ifndef BOOST_JSON_ALLOW_DEPRECATED
+ 230 + + # define BOOST_JSON_DEPRECATED(x) BOOST_DEPRECATED(x)
+ 231 + + #else
+ 232 + + # define BOOST_JSON_DEPRECATED(x)
+ 233 + + #endif
+ 234 + +
+ 235 + + #ifndef BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS
+ 236 + + #include <boost/json/detail/gdb_printers.hpp>
+ 237 + + #endif
+ 238 + +
+ 239 + + #endif
+ 240 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.conversion.hpp.c385894883668d872f8d1b74220b0f7e.html b/json/gcovr/index.conversion.hpp.c385894883668d872f8d1b74220b0f7e.html new file mode 100644 index 00000000..e2847e89 --- /dev/null +++ b/json/gcovr/index.conversion.hpp.c385894883668d872f8d1b74220b0f7e.html @@ -0,0 +1,6958 @@ + + + + + + impl/conversion.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/conversion.hpp

+
+ + 100.0% Lines (18/18) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/conversion.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 3 + + // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@yandex.ru)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_IMPL_CONVERSION_HPP
+ 12 + + #define BOOST_JSON_IMPL_CONVERSION_HPP
+ 13 + +
+ 14 + + #include <boost/json/fwd.hpp>
+ 15 + + #include <boost/json/value.hpp>
+ 16 + + #include <boost/json/string_view.hpp>
+ 17 + + #include <boost/describe/enumerators.hpp>
+ 18 + + #include <boost/describe/members.hpp>
+ 19 + + #include <boost/describe/bases.hpp>
+ 20 + + #include <boost/mp11/algorithm.hpp>
+ 21 + + #include <boost/mp11/utility.hpp>
+ 22 + + #include <boost/system/result.hpp>
+ 23 + +
+ 24 + + #include <iterator>
+ 25 + + #include <tuple>
+ 26 + + #include <utility>
+ 27 + + #ifndef BOOST_NO_CXX17_HDR_VARIANT
+ 28 + + # include <variant>
+ 29 + + #endif // BOOST_NO_CXX17_HDR_VARIANT
+ 30 + +
+ 31 + + namespace boost {
+ 32 + + namespace json {
+ 33 + + namespace detail {
+ 34 + +
+ 35 + + #ifdef __cpp_lib_nonmember_container_access
+ 36 + + using std::size;
+ 37 + + #endif
+ 38 + +
+ 39 + + template<std::size_t I, class T>
+ 40 + + using tuple_element_t = typename std::tuple_element<I, T>::type;
+ 41 + +
+ 42 + + template<class T>
+ 43 + + using iterator_type = decltype(std::begin(std::declval<T&>()));
+ 44 + + template<class T>
+ 45 + + using iterator_traits = std::iterator_traits< iterator_type<T> >;
+ 46 + +
+ 47 + + template<class T>
+ 48 + + using value_type = typename iterator_traits<T>::value_type;
+ 49 + + template<class T>
+ 50 + + using mapped_type = tuple_element_t< 1, value_type<T> >;
+ 51 + +
+ 52 + + // had to make the metafunction always succeeding in order to make it work
+ 53 + + // with msvc 14.0
+ 54 + + template<class T>
+ 55 + + using key_type_helper = tuple_element_t< 0, value_type<T> >;
+ 56 + + template<class T>
+ 57 + + using key_type = mp11::mp_eval_or<
+ 58 + + void,
+ 59 + + key_type_helper,
+ 60 + + T>;
+ 61 + +
+ 62 + + template<class T>
+ 63 + + using are_begin_and_end_same = std::is_same<
+ 64 + + iterator_type<T>,
+ 65 + + decltype(std::end(std::declval<T&>()))>;
+ 66 + +
+ 67 + + // msvc 14.0 gets confused when std::is_same is used directly
+ 68 + + template<class A, class B>
+ 69 + + using is_same_msvc_140 = std::is_same<A, B>;
+ 70 + + template<class T>
+ 71 + + using is_its_own_value = is_same_msvc_140<value_type<T>, T>;
+ 72 + +
+ 73 + + template<class T>
+ 74 + + using not_its_own_value = mp11::mp_not< is_its_own_value<T> >;
+ 75 + +
+ 76 + + template<class T>
+ 77 + + using begin_iterator_category = typename std::iterator_traits<
+ 78 + + iterator_type<T>>::iterator_category;
+ 79 + +
+ 80 + + template<class T>
+ 81 + + using has_positive_tuple_size = mp11::mp_bool<
+ 82 + + (std::tuple_size<T>::value > 0) >;
+ 83 + +
+ 84 + + template<class T>
+ 85 + + using has_unique_keys = has_positive_tuple_size<decltype(
+ 86 + + std::declval<T&>().emplace(
+ 87 + + std::declval<value_type<T>>()))>;
+ 88 + +
+ 89 + + template<class T>
+ 90 + + using has_string_type = std::is_same<
+ 91 + + typename T::string_type, std::basic_string<typename T::value_type> >;
+ 92 + +
+ 93 + + template<class T>
+ 94 + + struct is_value_type_pair_helper : std::false_type
+ 95 + + { };
+ 96 + + template<class T1, class T2>
+ 97 + + struct is_value_type_pair_helper<std::pair<T1, T2>> : std::true_type
+ 98 + + { };
+ 99 + + template<class T>
+ 100 + + using is_value_type_pair = is_value_type_pair_helper<value_type<T>>;
+ 101 + +
+ 102 + + template<class T>
+ 103 + + using has_size_member_helper
+ 104 + + = std::is_convertible<decltype(std::declval<T&>().size()), std::size_t>;
+ 105 + + template<class T>
+ 106 + + using has_size_member = mp11::mp_valid_and_true<has_size_member_helper, T>;
+ 107 + + template<class T>
+ 108 + + using has_free_size_helper
+ 109 + + = std::is_convertible<
+ 110 + + decltype(size(std::declval<T const&>())),
+ 111 + + std::size_t>;
+ 112 + + template<class T>
+ 113 + + using has_free_size = mp11::mp_valid_and_true<has_free_size_helper, T>;
+ 114 + + template<class T>
+ 115 + + using size_implementation = mp11::mp_cond<
+ 116 + + has_size_member<T>, mp11::mp_int<3>,
+ 117 + + has_free_size<T>, mp11::mp_int<2>,
+ 118 + + std::is_array<T>, mp11::mp_int<1>,
+ 119 + + mp11::mp_true, mp11::mp_int<0>>;
+ 120 + +
+ 121 + + template<class T>
+ 122 + + std::size_t
+ 123 + +138 try_size(T&& cont, mp11::mp_int<3>)
+ 124 + + {
+ 125 + +138 return cont.size();
+ 126 + + }
+ 127 + +
+ 128 + + template<class T>
+ 129 + + std::size_t
+ 130 + +1 try_size(T& cont, mp11::mp_int<2>)
+ 131 + + {
+ 132 + +1 return size(cont);
+ 133 + + }
+ 134 + +
+ 135 + + template<class T, std::size_t N>
+ 136 + + std::size_t
+ 137 + +1 try_size(T(&)[N], mp11::mp_int<1>)
+ 138 + + {
+ 139 + +1 return N;
+ 140 + + }
+ 141 + +
+ 142 + + template<class T>
+ 143 + + std::size_t
+ 144 + +7 try_size(T&, mp11::mp_int<0>)
+ 145 + + {
+ 146 + +7 return 0;
+ 147 + + }
+ 148 + +
+ 149 + + template<class T>
+ 150 + + using has_push_back_helper
+ 151 + + = decltype(std::declval<T&>().push_back(std::declval<value_type<T>>()));
+ 152 + + template<class T>
+ 153 + + using has_push_back = mp11::mp_valid<has_push_back_helper, T>;
+ 154 + + template<class T>
+ 155 + + using inserter_implementation = mp11::mp_cond<
+ 156 + + is_tuple_like<T>, mp11::mp_int<2>,
+ 157 + + has_push_back<T>, mp11::mp_int<1>,
+ 158 + + mp11::mp_true, mp11::mp_int<0>>;
+ 159 + +
+ 160 + + template<class T>
+ 161 + + iterator_type<T>
+ 162 + +56 inserter(
+ 163 + + T& target,
+ 164 + + mp11::mp_int<2>)
+ 165 + + {
+ 166 + +56 return target.begin();
+ 167 + + }
+ 168 + +
+ 169 + + template<class T>
+ 170 + + std::back_insert_iterator<T>
+ 171 + +569 inserter(
+ 172 + + T& target,
+ 173 + + mp11::mp_int<1>)
+ 174 + + {
+ 175 + +569 return std::back_inserter(target);
+ 176 + + }
+ 177 + +
+ 178 + + template<class T>
+ 179 + + std::insert_iterator<T>
+ 180 + +62 inserter(
+ 181 + + T& target,
+ 182 + + mp11::mp_int<0>)
+ 183 + + {
+ 184 + +62 return std::inserter( target, target.end() );
+ 185 + + }
+ 186 + +
+ 187 + + using value_from_conversion = mp11::mp_true;
+ 188 + + using value_to_conversion = mp11::mp_false;
+ 189 + +
+ 190 + + struct user_conversion_tag { };
+ 191 + + struct context_conversion_tag : user_conversion_tag { };
+ 192 + + struct full_context_conversion_tag : context_conversion_tag { };
+ 193 + + struct native_conversion_tag { };
+ 194 + + struct value_conversion_tag : native_conversion_tag { };
+ 195 + + struct object_conversion_tag : native_conversion_tag { };
+ 196 + + struct array_conversion_tag : native_conversion_tag { };
+ 197 + + struct string_conversion_tag : native_conversion_tag { };
+ 198 + + struct bool_conversion_tag : native_conversion_tag { };
+ 199 + + struct number_conversion_tag : native_conversion_tag { };
+ 200 + + struct integral_conversion_tag : number_conversion_tag { };
+ 201 + + struct floating_point_conversion_tag : number_conversion_tag { };
+ 202 + + struct null_like_conversion_tag { };
+ 203 + + struct string_like_conversion_tag { };
+ 204 + + struct map_like_conversion_tag { };
+ 205 + + struct path_conversion_tag { };
+ 206 + + struct sequence_conversion_tag { };
+ 207 + + struct tuple_conversion_tag { };
+ 208 + + struct described_class_conversion_tag { };
+ 209 + + struct described_enum_conversion_tag { };
+ 210 + + struct variant_conversion_tag { };
+ 211 + + struct optional_conversion_tag { };
+ 212 + + struct no_conversion_tag { };
+ 213 + +
+ 214 + + template<class... Args>
+ 215 + + using supports_tag_invoke = decltype(tag_invoke( std::declval<Args>()... ));
+ 216 + +
+ 217 + + template<class T>
+ 218 + + using has_user_conversion_from_impl = supports_tag_invoke<
+ 219 + + value_from_tag, value&, T&& >;
+ 220 + + template<class T>
+ 221 + + using has_user_conversion_to_impl = supports_tag_invoke<
+ 222 + + value_to_tag<T>, value const& >;
+ 223 + + template<class T>
+ 224 + + using has_nonthrowing_user_conversion_to_impl = supports_tag_invoke<
+ 225 + + try_value_to_tag<T>, value const& >;
+ 226 + + template< class T, class Dir >
+ 227 + + using has_user_conversion1 = mp11::mp_if<
+ 228 + + std::is_same<Dir, value_from_conversion>,
+ 229 + + mp11::mp_valid<has_user_conversion_from_impl, T>,
+ 230 + + mp11::mp_or<
+ 231 + + mp11::mp_valid<has_user_conversion_to_impl, T>,
+ 232 + + mp11::mp_valid<has_nonthrowing_user_conversion_to_impl, T>>>;
+ 233 + +
+ 234 + + template< class Ctx, class T >
+ 235 + + using has_context_conversion_from_impl = supports_tag_invoke<
+ 236 + + value_from_tag, value&, T&&, Ctx const& >;
+ 237 + + template< class Ctx, class T >
+ 238 + + using has_context_conversion_to_impl = supports_tag_invoke<
+ 239 + + value_to_tag<T>, value const&, Ctx const& >;
+ 240 + + template< class Ctx, class T >
+ 241 + + using has_nonthrowing_context_conversion_to_impl = supports_tag_invoke<
+ 242 + + try_value_to_tag<T>, value const&, Ctx const& >;
+ 243 + + template< class Ctx, class T, class Dir >
+ 244 + + using has_user_conversion2 = mp11::mp_if<
+ 245 + + std::is_same<Dir, value_from_conversion>,
+ 246 + + mp11::mp_valid<has_context_conversion_from_impl, Ctx, T>,
+ 247 + + mp11::mp_or<
+ 248 + + mp11::mp_valid<has_context_conversion_to_impl, Ctx, T>,
+ 249 + + mp11::mp_valid<has_nonthrowing_context_conversion_to_impl, Ctx, T>>>;
+ 250 + +
+ 251 + + template< class Ctx, class T >
+ 252 + + using has_full_context_conversion_from_impl = supports_tag_invoke<
+ 253 + + value_from_tag, value&, T&&, Ctx const&, Ctx const& >;
+ 254 + + template< class Ctx, class T >
+ 255 + + using has_full_context_conversion_to_impl = supports_tag_invoke<
+ 256 + + value_to_tag<T>, value const&, Ctx const&, Ctx const& >;
+ 257 + + template< class Ctx, class T >
+ 258 + + using has_nonthrowing_full_context_conversion_to_impl = supports_tag_invoke<
+ 259 + + try_value_to_tag<T>, value const&, Ctx const&, Ctx const& >;
+ 260 + + template< class Ctx, class T, class Dir >
+ 261 + + using has_user_conversion3 = mp11::mp_if<
+ 262 + + std::is_same<Dir, value_from_conversion>,
+ 263 + + mp11::mp_valid<has_full_context_conversion_from_impl, Ctx, T>,
+ 264 + + mp11::mp_or<
+ 265 + + mp11::mp_valid<has_full_context_conversion_to_impl, Ctx, T>,
+ 266 + + mp11::mp_valid<
+ 267 + + has_nonthrowing_full_context_conversion_to_impl, Ctx, T>>>;
+ 268 + +
+ 269 + + template< class T >
+ 270 + + using described_non_public_members = describe::describe_members<
+ 271 + + T,
+ 272 + + describe::mod_private
+ 273 + + | describe::mod_protected
+ 274 + + | boost::describe::mod_inherited>;
+ 275 + +
+ 276 + + #if defined(BOOST_MSVC) && BOOST_MSVC < 1920
+ 277 + +
+ 278 + + template< class T >
+ 279 + + struct described_member_t_impl;
+ 280 + +
+ 281 + + template< class T, class C >
+ 282 + + struct described_member_t_impl<T C::*>
+ 283 + + {
+ 284 + + using type = T;
+ 285 + + };
+ 286 + +
+ 287 + + template< class T, class D >
+ 288 + + using described_member_t = remove_cvref<
+ 289 + + typename described_member_t_impl<
+ 290 + + remove_cvref<decltype(D::pointer)> >::type>;
+ 291 + +
+ 292 + + #else
+ 293 + +
+ 294 + + template< class T, class D >
+ 295 + + using described_member_t = remove_cvref<decltype(
+ 296 + + std::declval<T&>().* D::pointer )>;
+ 297 + +
+ 298 + + #endif
+ 299 + +
+ 300 + + template< class T >
+ 301 + + using described_members = describe::describe_members<
+ 302 + + T, describe::mod_any_access | describe::mod_inherited>;
+ 303 + +
+ 304 + + #ifdef BOOST_DESCRIBE_CXX14
+ 305 + +
+ 306 + + constexpr
+ 307 + + bool
+ 308 + + compare_strings(char const* l, char const* r)
+ 309 + + {
+ 310 + + #if defined(_MSC_VER) && (_MSC_VER <= 1900) && !defined(__clang__)
+ 311 + + return *l == *r && ( (*l == 0) | compare_strings(l + 1, r + 1) );
+ 312 + + #else
+ 313 + + do
+ 314 + + {
+ 315 + + if( *l != *r )
+ 316 + + return false;
+ 317 + + if( *l == 0 )
+ 318 + + return true;
+ 319 + + ++l;
+ 320 + + ++r;
+ 321 + + } while(true);
+ 322 + + #endif
+ 323 + + }
+ 324 + +
+ 325 + + template< class L, class R >
+ 326 + + struct equal_member_names
+ 327 + + : mp11::mp_bool< compare_strings(L::name, R::name) >
+ 328 + + {};
+ 329 + +
+ 330 + + template< class T >
+ 331 + + using uniquely_named_members = mp11::mp_same<
+ 332 + + mp11::mp_unique_if< described_members<T>, equal_member_names >,
+ 333 + + described_members<T> >;
+ 334 + +
+ 335 + + #else
+ 336 + +
+ 337 + + // we only check this in C++14, but the template should exist nevertheless
+ 338 + + template< class T >
+ 339 + + using uniquely_named_members = std::true_type;
+ 340 + +
+ 341 + + #endif // BOOST_DESCRIBE_CXX14
+ 342 + +
+ 343 + + // user conversion (via tag_invoke)
+ 344 + + template< class Ctx, class T, class Dir >
+ 345 + + using user_conversion_category = mp11::mp_cond<
+ 346 + + has_user_conversion3<Ctx, T, Dir>, full_context_conversion_tag,
+ 347 + + has_user_conversion2<Ctx, T, Dir>, context_conversion_tag,
+ 348 + + has_user_conversion1<T, Dir>, user_conversion_tag>;
+ 349 + +
+ 350 + + // native conversions (constructors and member functions of value)
+ 351 + + template< class T >
+ 352 + + using native_conversion_category = mp11::mp_cond<
+ 353 + + std::is_same<T, value>, value_conversion_tag,
+ 354 + + std::is_same<T, array>, array_conversion_tag,
+ 355 + + std::is_same<T, object>, object_conversion_tag,
+ 356 + + std::is_same<T, string>, string_conversion_tag>;
+ 357 + +
+ 358 + + // generic conversions
+ 359 + + template< class T >
+ 360 + + using generic_conversion_category = mp11::mp_cond<
+ 361 + + std::is_same<T, bool>, bool_conversion_tag,
+ 362 + + std::is_integral<T>, integral_conversion_tag,
+ 363 + + std::is_floating_point<T>, floating_point_conversion_tag,
+ 364 + + is_null_like<T>, null_like_conversion_tag,
+ 365 + + is_string_like<T>, string_like_conversion_tag,
+ 366 + + is_variant_like<T>, variant_conversion_tag,
+ 367 + + is_optional_like<T>, optional_conversion_tag,
+ 368 + + is_map_like<T>, map_like_conversion_tag,
+ 369 + + is_sequence_like<T>, sequence_conversion_tag,
+ 370 + + is_tuple_like<T>, tuple_conversion_tag,
+ 371 + + is_described_class<T>, described_class_conversion_tag,
+ 372 + + is_described_enum<T>, described_enum_conversion_tag,
+ 373 + + is_path_like<T>, path_conversion_tag,
+ 374 + + // failed to find a suitable implementation
+ 375 + + mp11::mp_true, no_conversion_tag>;
+ 376 + +
+ 377 + + template< class T >
+ 378 + + using nested_type = typename T::type;
+ 379 + + template< class T1, class T2 >
+ 380 + + using conversion_category_impl_helper = mp11::mp_eval_if_not<
+ 381 + + std::is_same<detail::no_conversion_tag, T1>,
+ 382 + + T1,
+ 383 + + mp11::mp_eval_or_q, T1, mp11::mp_quote<nested_type>, T2>;
+ 384 + + template< class Ctx, class T, class Dir >
+ 385 + + struct conversion_category_impl
+ 386 + + {
+ 387 + + using type = mp11::mp_fold<
+ 388 + + mp11::mp_list<
+ 389 + + mp11::mp_defer<user_conversion_category, Ctx, T, Dir>,
+ 390 + + mp11::mp_defer<native_conversion_category, T>,
+ 391 + + mp11::mp_defer<generic_conversion_category, T>>,
+ 392 + + no_conversion_tag,
+ 393 + + conversion_category_impl_helper>;
+ 394 + + };
+ 395 + + template< class Ctx, class T, class Dir >
+ 396 + + using conversion_category =
+ 397 + + typename conversion_category_impl< Ctx, T, Dir >::type;
+ 398 + +
+ 399 + + template< class T >
+ 400 + + using any_conversion_tag = mp11::mp_not<
+ 401 + + std::is_same< T, no_conversion_tag > >;
+ 402 + +
+ 403 + + template< class T, class Dir, class... Ctxs >
+ 404 + + struct conversion_category_impl< std::tuple<Ctxs...>, T, Dir >
+ 405 + + {
+ 406 + + using ctxs = mp11::mp_list< remove_cvref<Ctxs>... >;
+ 407 + + using cats = mp11::mp_list<
+ 408 + + conversion_category<remove_cvref<Ctxs>, T, Dir>... >;
+ 409 + +
+ 410 + + template< class I >
+ 411 + + using exists = mp11::mp_less< I, mp11::mp_size<cats> >;
+ 412 + +
+ 413 + + using context2 = mp11::mp_find< cats, full_context_conversion_tag >;
+ 414 + + using context1 = mp11::mp_find< cats, context_conversion_tag >;
+ 415 + + using context0 = mp11::mp_find< cats, user_conversion_tag >;
+ 416 + + using index = mp11::mp_cond<
+ 417 + + exists<context2>, context2,
+ 418 + + exists<context1>, context1,
+ 419 + + exists<context0>, context0,
+ 420 + + mp11::mp_true, mp11::mp_find_if< cats, any_conversion_tag > >;
+ 421 + + using type = mp11::mp_eval_or<
+ 422 + + no_conversion_tag,
+ 423 + + mp11::mp_at, cats, index >;
+ 424 + + };
+ 425 + +
+ 426 + + struct no_context
+ 427 + + {};
+ 428 + +
+ 429 + + template <class T, class Dir>
+ 430 + + using can_convert = mp11::mp_not<
+ 431 + + std::is_same<
+ 432 + + detail::conversion_category<no_context, T, Dir>,
+ 433 + + detail::no_conversion_tag>>;
+ 434 + +
+ 435 + + template<class Impl1, class Impl2>
+ 436 + + using conversion_round_trips_helper = mp11::mp_or<
+ 437 + + std::is_same<Impl1, Impl2>,
+ 438 + + std::is_base_of<user_conversion_tag, Impl1>,
+ 439 + + std::is_base_of<user_conversion_tag, Impl2>>;
+ 440 + + template< class Ctx, class T, class Dir >
+ 441 + + using conversion_round_trips = conversion_round_trips_helper<
+ 442 + + conversion_category<Ctx, T, Dir>,
+ 443 + + conversion_category<Ctx, T, mp11::mp_not<Dir>>>;
+ 444 + +
+ 445 + + template< class T1, class T2 >
+ 446 + + struct copy_cref_helper
+ 447 + + {
+ 448 + + using type = remove_cvref<T2>;
+ 449 + + };
+ 450 + + template< class T1, class T2 >
+ 451 + + using copy_cref = typename copy_cref_helper< T1, T2 >::type;
+ 452 + +
+ 453 + + template< class T1, class T2 >
+ 454 + + struct copy_cref_helper<T1 const, T2>
+ 455 + + {
+ 456 + + using type = remove_cvref<T2> const;
+ 457 + + };
+ 458 + + template< class T1, class T2 >
+ 459 + + struct copy_cref_helper<T1&, T2>
+ 460 + + {
+ 461 + + using type = copy_cref<T1, T2>&;
+ 462 + + };
+ 463 + + template< class T1, class T2 >
+ 464 + + struct copy_cref_helper<T1&&, T2>
+ 465 + + {
+ 466 + + using type = copy_cref<T1, T2>&&;
+ 467 + + };
+ 468 + +
+ 469 + + template< class Rng, class Traits >
+ 470 + + using forwarded_value_helper = mp11::mp_if<
+ 471 + + std::is_convertible<
+ 472 + + typename Traits::reference,
+ 473 + + copy_cref<Rng, typename Traits::value_type> >,
+ 474 + + copy_cref<Rng, typename Traits::value_type>,
+ 475 + + typename Traits::value_type >;
+ 476 + +
+ 477 + + template< class Rng >
+ 478 + + using forwarded_value = forwarded_value_helper<
+ 479 + + Rng, iterator_traits< Rng > >;
+ 480 + +
+ 481 + + template< class Ctx, class T, class Dir >
+ 482 + + struct supported_context
+ 483 + + {
+ 484 + + using type = Ctx;
+ 485 + +
+ 486 + + static
+ 487 + + type const&
+ 488 + +32 get( Ctx const& ctx ) noexcept
+ 489 + + {
+ 490 + +32 return ctx;
+ 491 + + }
+ 492 + + };
+ 493 + +
+ 494 + + template< class T, class Dir, class... Ctxs >
+ 495 + + struct supported_context< std::tuple<Ctxs...>, T, Dir >
+ 496 + + {
+ 497 + + using Ctx = std::tuple<Ctxs...>;
+ 498 + + using impl = conversion_category_impl<Ctx, T, Dir>;
+ 499 + + using index = typename impl::index;
+ 500 + + using next_supported = supported_context<
+ 501 + + mp11::mp_at< typename impl::ctxs, index >, T, Dir >;
+ 502 + + using type = typename next_supported::type;
+ 503 + +
+ 504 + + static
+ 505 + + type const&
+ 506 + +19 get( Ctx const& ctx ) noexcept
+ 507 + + {
+ 508 + +19 return next_supported::get( std::get<index::value>( ctx ) );
+ 509 + + }
+ 510 + + };
+ 511 + +
+ 512 + + template< class T >
+ 513 + + using value_result_type = typename std::decay<
+ 514 + + decltype( std::declval<T&>().value() )>::type;
+ 515 + +
+ 516 + + template< class T >
+ 517 + + using can_reset = decltype( std::declval<T&>().reset() );
+ 518 + +
+ 519 + + template< class T >
+ 520 + + using has_valueless_by_exception =
+ 521 + + decltype( std::declval<T const&>().valueless_by_exception() );
+ 522 + +
+ 523 + + } // namespace detail
+ 524 + +
+ 525 + + template <class T>
+ 526 + + struct result_for<T, value>
+ 527 + + {
+ 528 + + using type = system::result< detail::remove_cvref<T> >;
+ 529 + + };
+ 530 + +
+ 531 + + template<class T>
+ 532 + + struct is_string_like
+ 533 + + : std::is_convertible<T, string_view>
+ 534 + + { };
+ 535 + +
+ 536 + + template<class T>
+ 537 + + struct is_path_like
+ 538 + + : mp11::mp_all<
+ 539 + + mp11::mp_valid_and_true<detail::is_its_own_value, T>,
+ 540 + + mp11::mp_valid_and_true<detail::has_string_type, T>>
+ 541 + + { };
+ 542 + + template<class T>
+ 543 + + struct is_sequence_like
+ 544 + + : mp11::mp_all<
+ 545 + + mp11::mp_valid_and_true<detail::are_begin_and_end_same, T>,
+ 546 + + mp11::mp_valid_and_true<detail::not_its_own_value, T>,
+ 547 + + mp11::mp_valid<detail::begin_iterator_category, T>>
+ 548 + + { };
+ 549 + +
+ 550 + + template<class T>
+ 551 + + struct is_map_like
+ 552 + + : mp11::mp_all<
+ 553 + + is_sequence_like<T>,
+ 554 + + mp11::mp_valid_and_true<detail::is_value_type_pair, T>,
+ 555 + + is_string_like<detail::key_type<T>>,
+ 556 + + mp11::mp_valid_and_true<detail::has_unique_keys, T>>
+ 557 + + { };
+ 558 + +
+ 559 + + template<class T>
+ 560 + + struct is_tuple_like
+ 561 + + : mp11::mp_valid_and_true<detail::has_positive_tuple_size, T>
+ 562 + + { };
+ 563 + +
+ 564 + + template<>
+ 565 + + struct is_null_like<std::nullptr_t>
+ 566 + + : std::true_type
+ 567 + + { };
+ 568 + +
+ 569 + + #ifndef BOOST_NO_CXX17_HDR_VARIANT
+ 570 + + template<>
+ 571 + + struct is_null_like<std::monostate>
+ 572 + + : std::true_type
+ 573 + + { };
+ 574 + + #endif // BOOST_NO_CXX17_HDR_VARIANT
+ 575 + +
+ 576 + + template<class T>
+ 577 + + struct is_described_class
+ 578 + + : mp11::mp_and<
+ 579 + + describe::has_describe_members<T>,
+ 580 + + mp11::mp_not< std::is_union<T> >,
+ 581 + + mp11::mp_empty<
+ 582 + + mp11::mp_eval_or<
+ 583 + + mp11::mp_list<>, detail::described_non_public_members, T>>>
+ 584 + + { };
+ 585 + +
+ 586 + + template<class T>
+ 587 + + struct is_described_enum
+ 588 + + : describe::has_describe_enumerators<T>
+ 589 + + { };
+ 590 + +
+ 591 + + template<class T>
+ 592 + + struct is_variant_like : mp11::mp_valid<detail::has_valueless_by_exception, T>
+ 593 + + { };
+ 594 + +
+ 595 + + template<class T>
+ 596 + + struct is_optional_like
+ 597 + + : mp11::mp_and<
+ 598 + + mp11::mp_not<std::is_void<
+ 599 + + mp11::mp_eval_or<void, detail::value_result_type, T>>>,
+ 600 + + mp11::mp_valid<detail::can_reset, T>>
+ 601 + + { };
+ 602 + +
+ 603 + + } // namespace json
+ 604 + + } // namespace boost
+ 605 + +
+ 606 + + #endif // BOOST_JSON_IMPL_CONVERSION_HPP
+ 607 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.css b/json/gcovr/index.css new file mode 100644 index 00000000..1eee6cb6 --- /dev/null +++ b/json/gcovr/index.css @@ -0,0 +1,1481 @@ +/* =========================================== + GCOVR Custom Dark Theme with Sidebar + =========================================== */ + +@charset "utf-8"; + +:root { + /* Dark theme colors */ + --bg-primary: #0d1117; + --bg-secondary: #161b22; + --bg-tertiary: #21262d; + --bg-hover: #30363d; + --bg-active: #388bfd26; + + --text-primary: #e6edf3; + --text-secondary: #8b949e; + --text-muted: #6e7681; + + --border-color: #30363d; + --border-muted: #21262d; + + /* Accent colors */ + --accent-blue: #58a6ff; + --accent-green: #3fb950; + --accent-yellow: #d29922; + --accent-red: #f85149; + --accent-purple: #a371f7; + + /* Coverage colors */ + --coverage-high: #3fb950; + --coverage-high-bg: rgba(63, 185, 80, 0.15); + --coverage-medium: #d29922; + --coverage-medium-bg: rgba(210, 153, 34, 0.15); + --coverage-low: #f85149; + --coverage-low-bg: rgba(248, 81, 73, 0.15); + --coverage-unknown: #6e7681; + + /* Spacing */ + --sidebar-width: 280px; + --header-height: 56px; + + /* Fonts */ + --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; + --font-mono: 'SF Mono', 'Fira Code', Consolas, 'Liberation Mono', Menlo, monospace; + + /* Radius */ + --radius-sm: 4px; + --radius-md: 6px; + --radius-lg: 8px; + + /* Transitions */ + --transition-fast: 0.15s ease; + --transition-normal: 0.25s ease; +} + +/* Light Mode */ +[data-theme="light"] { + --bg-primary: #ffffff; + --bg-secondary: #f6f8fa; + --bg-tertiary: #eaeef2; + --bg-hover: #d0d7de; + --bg-active: rgba(84, 174, 255, 0.15); + + --text-primary: #1f2328; + --text-secondary: #656d76; + --text-muted: #8c959f; + + --border-color: #d0d7de; + --border-muted: #eaeef2; + + --accent-blue: #0969da; + --accent-green: #1a7f37; + --accent-yellow: #9a6700; + --accent-red: #cf222e; + --accent-purple: #8250df; + + --coverage-high: #1a7f37; + --coverage-high-bg: rgba(26, 127, 55, 0.15); + --coverage-medium: #9a6700; + --coverage-medium-bg: rgba(154, 103, 0, 0.15); + --coverage-low: #cf222e; + --coverage-low-bg: rgba(207, 34, 46, 0.15); +} + +/* Smooth theme transitions */ +body, .sidebar, .main-content, .main-header, .main-footer, +.sidebar-header, .sidebar-nav, .sidebar-footer, +.summary-card, .file-list-container, .source-container, +.tree-item-header, .coverage-badge, .tree-coverage, +.btn, .nav-link, input { + transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease; +} + +/* Coverage class colors */ +.coverage-high { color: var(--coverage-high) !important; } +.coverage-medium { color: var(--coverage-medium) !important; } +.coverage-low, .coverage-none { color: var(--coverage-low) !important; } +.coverage-unknown { color: var(--coverage-unknown) !important; } + +/* Reset */ +*, *::before, *::after { + box-sizing: border-box; +} + +body { + margin: 0; + padding: 0; + font-family: var(--font-sans); + font-size: 14px; + line-height: 1.5; + color: var(--text-primary); + background: var(--bg-primary); + overflow-x: hidden; +} + +a { + color: var(--accent-blue); + text-decoration: none; + transition: color var(--transition-fast); +} + +a:hover { + color: #79c0ff; + text-decoration: underline; +} + +/* =========================================== + App Layout + =========================================== */ + +.app-container { + display: flex; + min-height: 100vh; +} + +/* =========================================== + Sidebar + =========================================== */ + +.sidebar { + position: fixed; + left: 0; + top: 0; + bottom: 0; + width: var(--sidebar-width); + background: var(--bg-secondary); + border-right: 1px solid var(--border-color); + display: flex; + flex-direction: column; + z-index: 100; + transition: transform var(--transition-normal); +} + +.sidebar.collapsed { + transform: translateX(-100%); +} + +.sidebar-header { + padding: 16px; + border-bottom: 1px solid var(--border-color); +} + +.sidebar-title-row { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; +} + +.sidebar-title-link { + color: inherit; + text-decoration: none; +} + +.sidebar-title-link:hover { + color: var(--accent-blue); +} + +.sidebar-header h2 { + margin: 0; + font-size: 14px; + font-weight: 600; + color: var(--text-primary); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +/* Theme Toggle */ +.theme-toggle { + width: 32px; + height: 32px; + border-radius: var(--radius-md); + border: 1px solid var(--border-color); + background: var(--bg-tertiary); + color: var(--text-secondary); + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all var(--transition-fast); + padding: 0; +} + +.theme-toggle:hover { + background: var(--bg-hover); + color: var(--text-primary); + border-color: var(--text-muted); +} + +.theme-toggle svg { + width: 16px; + height: 16px; +} + +.theme-toggle .icon-sun { display: none; } +.theme-toggle .icon-moon { display: block; } + +[data-theme="light"] .theme-toggle .icon-sun { display: block; } +[data-theme="light"] .theme-toggle .icon-moon { display: none; } + +.sidebar-search { + position: relative; +} + +.sidebar-search input { + width: 100%; + padding: 8px 12px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + color: var(--text-primary); + font-size: 13px; + outline: none; + transition: border-color var(--transition-fast), box-shadow var(--transition-fast); +} + +.sidebar-search input:focus { + border-color: var(--accent-blue); + box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.15); +} + +.sidebar-search input::placeholder { + color: var(--text-muted); +} + +/* Tree Controls */ +.tree-controls { + display: flex; + gap: 8px; + padding: 8px 16px; + border-bottom: 1px solid var(--border-color); +} + +.tree-control-btn { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 4px 8px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + color: var(--text-secondary); + font-size: 11px; + cursor: pointer; + transition: all var(--transition-fast); +} + +.tree-control-btn:hover { + background: var(--bg-hover); + color: var(--text-primary); +} + +.tree-control-btn svg { + width: 12px; + height: 12px; +} + +.sidebar-nav { + flex: 1; + overflow-y: auto; + overflow-x: hidden; + padding: 8px 0; +} + +.sidebar-footer { + padding: 12px 16px; + border-top: 1px solid var(--border-color); + background: var(--bg-tertiary); +} + +.coverage-summary-mini { + display: flex; + align-items: center; + gap: 8px; +} + +.coverage-badge { + padding: 4px 10px; + border-radius: var(--radius-sm); + font-weight: 600; + font-size: 13px; +} + +.coverage-badge.coverage-high { + background: var(--coverage-high-bg); +} + +.coverage-badge.coverage-medium { + background: var(--coverage-medium-bg); +} + +.coverage-badge.coverage-low { + background: var(--coverage-low-bg); +} + +.coverage-label { + color: var(--text-secondary); + font-size: 12px; +} + +/* Tree View */ +.tree-loading { + padding: 16px; + color: var(--text-muted); + font-size: 13px; +} + +.tree-item { + user-select: none; +} + +.tree-item-header { + display: flex; + align-items: center; + padding: 2px 12px 2px 8px; + cursor: pointer; + transition: background var(--transition-fast); + gap: 4px; + /* Extend background full width */ + margin-left: -200px; + padding-left: 208px; + margin-right: -12px; + padding-right: 24px; +} + +.tree-item-header:hover { + background: var(--bg-hover); +} + +.tree-item-header.active, +.tree-item.active > .tree-item-header { + background: var(--bg-active); +} + +.tree-item.active > .tree-item-header .tree-label { + color: var(--accent-blue); + font-weight: 500; +} + +/* Folder toggle button (+/-) - minimal style */ +.tree-folder-toggle { + width: 16px; + height: 16px; + display: inline-flex; + align-items: center; + justify-content: center; + background: transparent; + border: none; + color: var(--text-muted); + font-size: 11px; + font-weight: 400; + font-family: var(--font-mono); + flex-shrink: 0; + cursor: pointer; + transition: color var(--transition-fast); + text-decoration: none; + line-height: 1; + margin-right: 2px; + padding: 0; +} + +.tree-folder-toggle:hover { + color: var(--text-primary); + text-decoration: none; +} + +/* Spacer for files (no toggle) */ +.tree-spacer { + width: 20px; + flex-shrink: 0; +} + +/* Legacy toggle classes */ +.tree-toggle { + width: 18px; + height: 18px; + display: flex; + align-items: center; + justify-content: center; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + color: var(--text-secondary); + font-size: 12px; + font-weight: 600; + font-family: var(--font-mono); + flex-shrink: 0; + cursor: pointer; + transition: all var(--transition-fast); + padding: 0; + line-height: 1; + text-decoration: none; +} + +.tree-toggle:hover { + background: var(--bg-hover); + color: var(--text-primary); + border-color: var(--accent-blue); + text-decoration: none; +} + +.tree-toggle .toggle-icon { + display: block; + color: var(--text-primary); + font-size: 14px; + line-height: 1; +} + +.tree-toggle-spacer { + width: 18px; + flex-shrink: 0; +} + +.tree-item.no-children .tree-toggle { + visibility: hidden; +} + +.tree-icon { + width: 16px; + height: 16px; + flex-shrink: 0; +} + +.tree-icon-folder { + color: var(--accent-blue); +} + +.tree-icon-file { + color: var(--text-muted); +} + +/* Legacy classes */ +.tree-icon.folder { + color: var(--accent-blue); +} + +.tree-icon.file { + color: var(--text-secondary); +} + +.tree-label { + flex: 1; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 13px; + color: var(--text-primary); +} + +.tree-coverage { + font-size: 11px; + font-weight: 600; + padding: 2px 6px; + border-radius: var(--radius-sm); + flex-shrink: 0; +} + +.tree-coverage.coverage-high { + background: var(--coverage-high-bg); +} + +.tree-coverage.coverage-medium { + background: var(--coverage-medium-bg); +} + +.tree-coverage.coverage-low { + background: var(--coverage-low-bg); +} + +.tree-children { + display: none; + margin-left: 20px; + position: relative; +} + +.tree-item.expanded > .tree-children { + display: block; +} + +.tree-children-inner { + /* Animation support */ +} + + +/* =========================================== + Main Content + =========================================== */ + +.main-content { + flex: 1; + margin-left: var(--sidebar-width); + display: flex; + flex-direction: column; + min-height: 100vh; + transition: margin-left var(--transition-normal); +} + +.sidebar.collapsed + .main-content { + margin-left: 0; +} + +.main-header { + position: sticky; + top: 0; + z-index: 50; + display: flex; + align-items: center; + gap: 16px; + padding: 12px 24px; + background: var(--bg-secondary); + border-bottom: 1px solid var(--border-color); + height: var(--header-height); +} + +.sidebar-toggle { + display: flex; + flex-direction: column; + justify-content: center; + gap: 4px; + width: 32px; + height: 32px; + padding: 6px; + background: transparent; + border: none; + border-radius: var(--radius-sm); + cursor: pointer; + transition: background var(--transition-fast); +} + +.sidebar-toggle:hover { + background: var(--bg-hover); +} + +.sidebar-toggle span { + display: block; + height: 2px; + background: var(--text-secondary); + border-radius: 1px; + transition: background var(--transition-fast); +} + +.sidebar-toggle:hover span { + background: var(--text-primary); +} + +.breadcrumb { + display: flex; + align-items: center; + flex-wrap: nowrap; + font-size: 14px; + color: var(--text-secondary); + white-space: nowrap; +} + +.breadcrumb a, +.breadcrumb span { + display: inline; + white-space: nowrap; +} + +.breadcrumb a { + color: var(--text-secondary); +} + +.breadcrumb a:hover { + color: var(--accent-blue); +} + +.breadcrumb .separator { + color: var(--text-muted); + padding: 0 6px; +} + +.breadcrumb .current { + color: var(--text-primary); +} + +.header-actions { + margin-left: auto; +} + +.content-wrapper { + flex: 1; + padding: 24px; + max-width: 1400px; + width: 100%; + margin: 0 auto; +} + +.main-footer { + padding: 24px; + text-align: center; + color: var(--text-muted); + font-size: 12px; + border-top: 1px solid var(--border-color); +} + +.main-footer a { + color: var(--text-muted); +} + +/* =========================================== + Summary Cards + =========================================== */ + +.summary-section { + margin-bottom: 24px; +} + +.summary-cards { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 16px; + margin-bottom: 16px; +} + +.summary-card { + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.summary-card-header { + padding: 12px 16px; + border-bottom: 1px solid var(--border-color); + background: var(--bg-tertiary); +} + +.summary-card-header h3 { + margin: 0; + font-size: 12px; + font-weight: 600; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.summary-card-body { + padding: 16px; + display: flex; + align-items: center; + gap: 16px; +} + +.coverage-ring { + position: relative; + width: 72px; + height: 72px; + flex-shrink: 0; +} + +.coverage-ring svg { + width: 100%; + height: 100%; + transform: rotate(-90deg); +} + +.coverage-ring .ring-bg { + fill: none; + stroke: var(--bg-tertiary); + stroke-width: 3; +} + +.coverage-ring .ring-fill { + fill: none; + stroke: currentColor; + stroke-width: 3; + stroke-linecap: round; + transition: stroke-dasharray var(--transition-normal); +} + +.coverage-ring.coverage-high .ring-fill { stroke: var(--coverage-high); } +.coverage-ring.coverage-medium .ring-fill { stroke: var(--coverage-medium); } +.coverage-ring.coverage-low .ring-fill { stroke: var(--coverage-low); } + +.coverage-ring .ring-text { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 14px; + font-weight: 600; +} + +.summary-stats { + flex: 1; +} + +.stat-row { + display: flex; + justify-content: space-between; + padding: 4px 0; + font-size: 13px; +} + +.stat-row .stat-label { + color: var(--text-secondary); +} + +.stat-row .stat-value { + font-weight: 500; + color: var(--text-primary); +} + +.coverage-legend { + display: flex; + gap: 16px; + flex-wrap: wrap; +} + +.legend-item { + padding: 4px 12px; + border-radius: var(--radius-sm); + font-size: 12px; + font-weight: 500; +} + +.legend-item.coverage-high { + background: var(--coverage-high-bg); + color: var(--coverage-high); +} + +.legend-item.coverage-medium { + background: var(--coverage-medium-bg); + color: var(--coverage-medium); +} + +.legend-item.coverage-low { + background: var(--coverage-low-bg); + color: var(--coverage-low); +} + +/* =========================================== + File List + =========================================== */ + +.file-list-container { + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.file-list-header { + display: grid; + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px 100px 100px; + gap: 8px; + padding: 12px 16px; + background: var(--bg-tertiary); + border-bottom: 1px solid var(--border-color); + font-size: 12px; + font-weight: 600; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.file-list-header > div { + display: flex; + align-items: center; + gap: 4px; +} + +.file-list-header .sortable { + cursor: pointer; + user-select: none; +} + +.file-list-header .sortable:hover { + color: var(--text-primary); +} + +.file-list-header .sorted-ascending::after { + content: ' ↑'; +} + +.file-list-header .sorted-descending::after { + content: ' ↓'; +} + +.file-row { + display: grid; + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px 100px 100px; + gap: 8px; + padding: 4px 16px; + border-bottom: 1px solid var(--border-muted); + align-items: center; + transition: background var(--transition-fast); +} + +.file-row:last-child { + border-bottom: none; +} + +.file-row:hover { + background: var(--bg-hover); +} + +/* Adjust grid when columns are hidden */ +.no-functions.no-branches .file-list-header, +.no-functions.no-branches .file-row { + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px; +} + +.no-functions:not(.no-branches) .file-list-header, +.no-functions:not(.no-branches) .file-row { + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px 100px; +} + +.no-branches:not(.no-functions) .file-list-header, +.no-branches:not(.no-functions) .file-row { + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px 100px; +} + +.file-row:nth-child(even) { + background: rgba(56, 139, 253, 0.03); +} + +.file-row:nth-child(even):hover { + background: var(--bg-hover); +} + +.col-name { + display: flex; + align-items: center; + gap: 8px; + min-width: 0; +} + +.file-icon { + flex-shrink: 0; + color: var(--text-muted); +} + +.file-icon svg { + display: block; +} + +.file-row.directory .file-icon { + color: var(--accent-blue); +} + +.col-name a { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.col-name .no-link { + color: var(--text-secondary); +} + +.col-coverage { + display: flex; + align-items: center; + gap: 12px; +} + +.coverage-bar-container { + flex: 1; + height: 6px; + background: var(--bg-tertiary); + border-radius: 3px; + overflow: hidden; +} + +.coverage-bar { + height: 100%; + border-radius: 3px; + transition: width var(--transition-normal); +} + +.coverage-bar.coverage-high { background: var(--coverage-high); } +.coverage-bar.coverage-medium { background: var(--coverage-medium); } +.coverage-bar.coverage-low { background: var(--coverage-low); } + +.coverage-percent { + font-weight: 600; + font-size: 13px; + min-width: 48px; + text-align: right; +} + +.col-lines, .col-functions, .col-branches { + text-align: right; + font-size: 13px; +} + +.stat-value { + font-weight: 500; +} + +.stat-separator { + color: var(--text-muted); + margin: 0 2px; +} + +.stat-total { + color: var(--text-secondary); +} + +/* =========================================== + Source Code View + =========================================== */ + +.source-summary { + display: flex; + justify-content: space-between; + align-items: flex-start; + flex-wrap: wrap; + gap: 16px; + margin-bottom: 16px; +} + +.source-info h2 { + margin: 0 0 8px 0; + font-size: 18px; + font-weight: 600; + color: var(--text-primary); + font-family: var(--font-mono); +} + +.source-stats { + display: flex; + gap: 16px; + flex-wrap: wrap; +} + +.source-stats .stat { + font-size: 13px; + color: var(--text-secondary); +} + +.source-stats .stat strong { + margin-right: 4px; +} + +.source-controls { + display: flex; + gap: 8px; +} + +.btn { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 8px 12px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + color: var(--text-secondary); + font-size: 13px; + cursor: pointer; + transition: all var(--transition-fast); +} + +.btn:hover { + background: var(--bg-hover); + color: var(--text-primary); +} + +.btn.btn-sm { + padding: 4px 10px; + font-size: 12px; +} + +.btn-count { + font-weight: 600; +} + +.btn-toggle { + text-decoration: line-through; + opacity: 0.6; +} + +.btn-toggle.show_coveredLine, +.btn-toggle.show_uncoveredLine, +.btn-toggle.show_partialCoveredLine, +.btn-toggle.show_excludedLine { + text-decoration: none; + opacity: 1; +} + +.color-dot { + width: 8px; + height: 8px; + border-radius: 50%; +} + +.color-dot.covered { background: var(--coverage-high); } +.color-dot.uncovered { background: var(--coverage-low); } + +.source-container { + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.source-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 16px; + background: var(--bg-tertiary); + border-bottom: 1px solid var(--border-color); + flex-wrap: wrap; + gap: 12px; +} + +.source-title { + font-family: var(--font-mono); + font-size: 13px; + font-weight: 500; + color: var(--text-primary); +} + +.source-actions { + display: flex; + gap: 8px; + flex-wrap: wrap; +} + +.source-table-container { + overflow-x: auto; +} + +.source-table { + width: 100%; + border-collapse: collapse; + font-family: var(--font-mono); + font-size: 12px; + line-height: 1.5; +} + +.source-table thead { + position: sticky; + top: 0; + z-index: 10; +} + +.source-table th { + padding: 8px 12px; + background: var(--bg-tertiary); + color: var(--text-secondary); + font-weight: 600; + text-align: left; + border-bottom: 1px solid var(--border-color); + white-space: nowrap; +} + +.source-table th.col-lineno, +.source-table th.col-count, +.source-table th.col-branch { + text-align: right; +} + +.source-table td { + padding: 0 12px; + vertical-align: top; + border-bottom: 1px solid var(--border-muted); +} + +.source-table .col-lineno { + background: var(--bg-tertiary); + border-right: 1px solid var(--border-color); + text-align: right; + user-select: none; + width: 60px; +} + +.source-table .col-lineno a { + color: var(--text-muted); + text-decoration: none; + display: block; + padding: 2px 0; +} + +.source-table .col-lineno a:hover { + color: var(--accent-blue); +} + +.source-table .col-branch, +.source-table .col-condition, +.source-table .col-decision, +.source-table .col-call { + background: var(--bg-tertiary); + border-right: 1px solid var(--border-color); + text-align: center; + width: 60px; +} + +.source-table .col-count { + text-align: right; + width: 60px; + color: var(--text-muted); +} + +.source-table .col-source { + white-space: pre; + padding-left: 16px; +} + +/* Line coverage highlighting */ +.source-line.coveredLine.show_coveredLine td.col-source, +.source-line.coveredLine.show_coveredLine td.col-count { + background: var(--coverage-high-bg); +} + +.source-line.uncoveredLine.show_uncoveredLine td.col-source, +.source-line.uncoveredLine.show_uncoveredLine td.col-count { + background: var(--coverage-low-bg); +} + +.source-line.partialCoveredLine.show_partialCoveredLine td.col-source, +.source-line.partialCoveredLine.show_partialCoveredLine td.col-count { + background: var(--coverage-medium-bg); +} + +.source-line.excludedLine.show_excludedLine td.col-source, +.source-line.excludedLine.show_excludedLine td.col-count { + background: rgba(110, 118, 129, 0.15); +} + +.hit-miss { + color: var(--coverage-low); + font-weight: bold; +} + +.hit-excluded { + color: var(--text-muted); +} + +/* Branch/condition popup */ +.branch-details, .condition-details, .decision-details, .call-details { + position: relative; +} + +.branch-summary, .condition-summary, .decision-summary, .call-summary { + cursor: pointer; + padding: 2px 4px; + border-radius: var(--radius-sm); +} + +.branch-summary:hover, .condition-summary:hover, .decision-summary:hover, .call-summary:hover { + background: var(--bg-hover); +} + +.branch-popup, .condition-popup, .decision-popup, .call-popup { + position: absolute; + top: 100%; + left: 0; + z-index: 100; + min-width: 250px; + padding: 12px; + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); + font-size: 12px; + line-height: 1.6; +} + +.function-name { + font-weight: 600; + color: var(--accent-blue); + margin-bottom: 4px; +} + +.branch-taken, .condition-covered, .decision-taken, .call-invoked { + color: var(--coverage-high); +} + +.branch-not-taken, .condition-not-covered, .decision-not-taken, .call-not-invoked { + color: var(--coverage-low); +} + +.branch-excluded, .condition-excluded, .decision-uncheckable, .call-excluded { + color: var(--text-muted); +} + +/* =========================================== + Navigation + =========================================== */ + +.nav-links { + display: flex; + gap: 12px; +} + +.nav-link { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 6px 12px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + color: var(--text-secondary); + font-size: 13px; + transition: all var(--transition-fast); +} + +.nav-link:hover { + background: var(--bg-hover); + color: var(--text-primary); + text-decoration: none; +} + +.nav-link svg { + flex-shrink: 0; +} + +/* =========================================== + Functions Page + =========================================== */ + +.summary-inline { + display: flex; + gap: 24px; + flex-wrap: wrap; + padding: 16px; + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + margin-bottom: 24px; +} + +.summary-inline .summary-stat { + display: flex; + align-items: center; + gap: 8px; +} + +.summary-inline .stat-label { + color: var(--text-secondary); + font-size: 13px; +} + +.summary-inline .stat-value { + font-weight: 600; + font-size: 14px; +} + +.summary-inline .stat-detail { + color: var(--text-muted); + font-size: 12px; +} + +.functions-container { + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.functions-header { + display: grid; + grid-template-columns: 2fr 120px 80px 80px; + gap: 16px; + padding: 12px 16px; + background: var(--bg-tertiary); + border-bottom: 1px solid var(--border-color); + font-size: 12px; + font-weight: 600; + color: var(--text-secondary); + text-transform: uppercase; +} + +.function-row { + display: grid; + grid-template-columns: 2fr 120px 80px 80px; + gap: 16px; + padding: 10px 16px; + border-bottom: 1px solid var(--border-muted); + align-items: center; + transition: background var(--transition-fast); +} + +.function-row:hover { + background: var(--bg-hover); +} + +.function-row .col-function a { + display: block; +} + +.function-name { + font-weight: 500; + display: block; +} + +.function-location { + font-size: 11px; + color: var(--text-muted); +} + +.function-row .excluded { + color: var(--text-muted); + font-style: italic; +} + +.function-row .not-called { + color: var(--coverage-low); +} + +.function-row .called { + color: var(--coverage-high); + font-weight: 500; +} + +/* =========================================== + Responsive + =========================================== */ + +@media (max-width: 1024px) { + .sidebar { + transform: translateX(-100%); + } + + .sidebar.open { + transform: translateX(0); + } + + .main-content { + margin-left: 0; + } + + .file-list-header, + .file-row { + grid-template-columns: 1fr 120px 80px; + } + + .col-functions, + .col-branches { + display: none; + } +} + +@media (max-width: 768px) { + .content-wrapper { + padding: 16px; + } + + .summary-cards { + grid-template-columns: 1fr; + } + + .file-list-header, + .file-row { + grid-template-columns: 1fr 100px; + } + + .col-lines { + display: none; + } + + .source-header { + flex-direction: column; + align-items: flex-start; + } +} + +/* =========================================== + Syntax Highlighting (Dark Theme) + =========================================== */ + +/* Dark theme syntax highlighting */ +.c { color: #8b949e; font-style: italic; } /* Comment */ +.k { color: #ff7b72; font-weight: bold; } /* Keyword */ +.o { color: #79c0ff; } /* Operator */ +.cm { color: #8b949e; font-style: italic; } /* Comment.Multiline */ +.cp { color: #d29922; } /* Comment.Preproc */ +.c1 { color: #8b949e; font-style: italic; } /* Comment.Single */ +.cs { color: #8b949e; font-weight: bold; } /* Comment.Special */ +.gd { color: #f85149; } /* Generic.Deleted */ +.gi { color: #3fb950; } /* Generic.Inserted */ +.kc { color: #79c0ff; } /* Keyword.Constant */ +.kd { color: #ff7b72; } /* Keyword.Declaration */ +.kn { color: #ff7b72; } /* Keyword.Namespace */ +.kt { color: #ffa657; } /* Keyword.Type */ +.m { color: #a5d6ff; } /* Literal.Number */ +.s { color: #a5d6ff; } /* Literal.String */ +.na { color: #79c0ff; } /* Name.Attribute */ +.nb { color: #ffa657; } /* Name.Builtin */ +.nc { color: #ffa657; font-weight: bold; } /* Name.Class */ +.nf { color: #d2a8ff; } /* Name.Function */ +.nn { color: #ffa657; } /* Name.Namespace */ +.nt { color: #7ee787; } /* Name.Tag */ +.nv { color: #79c0ff; } /* Name.Variable */ +.ow { color: #ff7b72; font-weight: bold; } /* Operator.Word */ +.s1 { color: #a5d6ff; } /* Literal.String.Single */ +.s2 { color: #a5d6ff; } /* Literal.String.Double */ + +/* Light theme syntax highlighting */ +[data-theme="light"] .c { color: #6e7781; } +[data-theme="light"] .k { color: #cf222e; } +[data-theme="light"] .o { color: #0550ae; } +[data-theme="light"] .cm { color: #6e7781; } +[data-theme="light"] .cp { color: #9a6700; } +[data-theme="light"] .c1 { color: #6e7781; } +[data-theme="light"] .cs { color: #6e7781; } +[data-theme="light"] .gd { color: #cf222e; } +[data-theme="light"] .gi { color: #1a7f37; } +[data-theme="light"] .kc { color: #0550ae; } +[data-theme="light"] .kd { color: #cf222e; } +[data-theme="light"] .kn { color: #cf222e; } +[data-theme="light"] .kt { color: #953800; } +[data-theme="light"] .m { color: #0550ae; } +[data-theme="light"] .s { color: #0a3069; } +[data-theme="light"] .na { color: #0550ae; } +[data-theme="light"] .nb { color: #953800; } +[data-theme="light"] .nc { color: #953800; } +[data-theme="light"] .nf { color: #8250df; } +[data-theme="light"] .nn { color: #953800; } +[data-theme="light"] .nt { color: #1a7f37; } +[data-theme="light"] .nv { color: #0550ae; } +[data-theme="light"] .ow { color: #cf222e; } +[data-theme="light"] .s1 { color: #0a3069; } +[data-theme="light"] .s2 { color: #0a3069; } + +/* =========================================== + Scrollbar + =========================================== */ + +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: var(--bg-primary); +} + +::-webkit-scrollbar-thumb { + background: var(--bg-tertiary); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--bg-hover); +} + +/* Button toggle classes for gcovr compatibility */ +.button_toggle_coveredLine, +.button_toggle_uncoveredLine, +.button_toggle_partialCoveredLine, +.button_toggle_excludedLine { + text-decoration: line-through; + opacity: 0.6; +} + +.button_toggle_coveredLine.show_coveredLine, +.button_toggle_uncoveredLine.show_uncoveredLine, +.button_toggle_partialCoveredLine.show_partialCoveredLine, +.button_toggle_excludedLine.show_excludedLine { + text-decoration: none; + opacity: 1; +} diff --git a/json/gcovr/index.d2s.hpp.cde3922f605044959e8be4ef6db1abab.html b/json/gcovr/index.d2s.hpp.cde3922f605044959e8be4ef6db1abab.html new file mode 100644 index 00000000..a53b090a --- /dev/null +++ b/json/gcovr/index.d2s.hpp.cde3922f605044959e8be4ef6db1abab.html @@ -0,0 +1,4222 @@ + + + + + + detail/ryu/detail/d2s.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/ryu/detail/d2s.hpp

+
+ + 100.0% Lines (42/42) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/ryu/detail/d2s.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2018 Ulf Adams
+ 2 + + //
+ 3 + + // The contents of this file may be used under the terms of the Apache License,
+ 4 + + // Version 2.0.
+ 5 + + //
+ 6 + + // (See accompanying file LICENSE-Apache or copy at
+ 7 + + // http://www.apache.org/licenses/LICENSE-2.0)
+ 8 + + //
+ 9 + + // Alternatively, the contents of this file may be used under the terms of
+ 10 + + // the Boost Software License, Version 1.0.
+ 11 + + // (See accompanying file LICENSE-Boost or copy at
+ 12 + + // https://www.boost.org/LICENSE_1_0.txt)
+ 13 + + //
+ 14 + + // Unless required by applicable law or agreed to in writing, this software
+ 15 + + // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ 16 + + // KIND, either express or implied.
+ 17 + +
+ 18 + + /*
+ 19 + + This is a derivative work
+ 20 + + */
+ 21 + +
+ 22 + + #ifndef BOOST_JSON_DETAIL_RYU_DETAIL_D2S_HPP
+ 23 + + #define BOOST_JSON_DETAIL_RYU_DETAIL_D2S_HPP
+ 24 + +
+ 25 + + #include <boost/json/detail/config.hpp>
+ 26 + + #include <boost/json/detail/ryu/detail/common.hpp>
+ 27 + +
+ 28 + + // Only include the full table if we're not optimizing for size.
+ 29 + + #if !defined(BOOST_JSON_RYU_OPTIMIZE_SIZE)
+ 30 + + #include <boost/json/detail/ryu/detail/d2s_full_table.hpp>
+ 31 + + #endif
+ 32 + + #if defined(BOOST_JSON_RYU_HAS_UINT128)
+ 33 + + typedef __uint128_t uint128_t;
+ 34 + + #else
+ 35 + + #include <boost/json/detail/ryu/detail/d2s_intrinsics.hpp>
+ 36 + + #endif
+ 37 + +
+ 38 + + namespace boost {
+ 39 + + namespace json {
+ 40 + + namespace detail {
+ 41 + +
+ 42 + + namespace ryu {
+ 43 + + namespace detail {
+ 44 + +
+ 45 + + constexpr int DOUBLE_POW5_INV_BITCOUNT = 122;
+ 46 + + constexpr int DOUBLE_POW5_BITCOUNT = 121;
+ 47 + +
+ 48 + + #if defined(BOOST_JSON_RYU_OPTIMIZE_SIZE)
+ 49 + +
+ 50 + + constexpr int POW5_TABLE_SIZE = 26;
+ 51 + +
+ 52 + + inline
+ 53 + + std::uint64_t const
+ 54 + +1186 (&DOUBLE_POW5_TABLE() noexcept)[POW5_TABLE_SIZE]
+ 55 + + {
+ 56 + + static constexpr std::uint64_t arr[26] = {
+ 57 + + 1ull, 5ull, 25ull, 125ull, 625ull, 3125ull, 15625ull, 78125ull, 390625ull,
+ 58 + + 1953125ull, 9765625ull, 48828125ull, 244140625ull, 1220703125ull, 6103515625ull,
+ 59 + + 30517578125ull, 152587890625ull, 762939453125ull, 3814697265625ull,
+ 60 + + 19073486328125ull, 95367431640625ull, 476837158203125ull,
+ 61 + + 2384185791015625ull, 11920928955078125ull, 59604644775390625ull,
+ 62 + + 298023223876953125ull //, 1490116119384765625ull
+ 63 + + };
+ 64 + +1186 return arr;
+ 65 + + }
+ 66 + +
+ 67 + + inline
+ 68 + + std::uint64_t const
+ 69 + +652 (&DOUBLE_POW5_SPLIT2() noexcept)[13][2]
+ 70 + + {
+ 71 + + static constexpr std::uint64_t arr[13][2] = {
+ 72 + + { 0u, 72057594037927936u },
+ 73 + + { 10376293541461622784u, 93132257461547851u },
+ 74 + + { 15052517733678820785u, 120370621524202240u },
+ 75 + + { 6258995034005762182u, 77787690973264271u },
+ 76 + + { 14893927168346708332u, 100538234169297439u },
+ 77 + + { 4272820386026678563u, 129942622070561240u },
+ 78 + + { 7330497575943398595u, 83973451344588609u },
+ 79 + + { 18377130505971182927u, 108533142064701048u },
+ 80 + + { 10038208235822497557u, 140275798336537794u },
+ 81 + + { 7017903361312433648u, 90651109995611182u },
+ 82 + + { 6366496589810271835u, 117163813585596168u },
+ 83 + + { 9264989777501460624u, 75715339914673581u },
+ 84 + + { 17074144231291089770u, 97859783203563123u }};
+ 85 + +652 return arr;
+ 86 + + }
+ 87 + +
+ 88 + + // Unfortunately, the results are sometimes off by one. We use an additional
+ 89 + + // lookup table to store those cases and adjust the result.
+ 90 + + inline
+ 91 + + std::uint32_t const
+ 92 + +626 (&POW5_OFFSETS() noexcept)[13]
+ 93 + + {
+ 94 + + static constexpr std::uint32_t arr[13] = {
+ 95 + + 0x00000000, 0x00000000, 0x00000000, 0x033c55be, 0x03db77d8, 0x0265ffb2,
+ 96 + + 0x00000800, 0x01a8ff56, 0x00000000, 0x0037a200, 0x00004000, 0x03fffffc,
+ 97 + + 0x00003ffe};
+ 98 + +626 return arr;
+ 99 + + }
+ 100 + +
+ 101 + + inline
+ 102 + + std::uint64_t const
+ 103 + +584 (&DOUBLE_POW5_INV_SPLIT2() noexcept)[13][2]
+ 104 + + {
+ 105 + + static constexpr std::uint64_t arr[13][2] = {
+ 106 + + { 1u, 288230376151711744u },
+ 107 + + { 7661987648932456967u, 223007451985306231u },
+ 108 + + { 12652048002903177473u, 172543658669764094u },
+ 109 + + { 5522544058086115566u, 266998379490113760u },
+ 110 + + { 3181575136763469022u, 206579990246952687u },
+ 111 + + { 4551508647133041040u, 159833525776178802u },
+ 112 + + { 1116074521063664381u, 247330401473104534u },
+ 113 + + { 17400360011128145022u, 191362629322552438u },
+ 114 + + { 9297997190148906106u, 148059663038321393u },
+ 115 + + { 11720143854957885429u, 229111231347799689u },
+ 116 + + { 15401709288678291155u, 177266229209635622u },
+ 117 + + { 3003071137298187333u, 274306203439684434u },
+ 118 + + { 17516772882021341108u, 212234145163966538u }};
+ 119 + +584 return arr;
+ 120 + + }
+ 121 + +
+ 122 + + inline
+ 123 + + std::uint32_t const
+ 124 + +560 (&POW5_INV_OFFSETS() noexcept)[20]
+ 125 + + {
+ 126 + + static constexpr std::uint32_t arr[20] = {
+ 127 + + 0x51505404, 0x55054514, 0x45555545, 0x05511411, 0x00505010, 0x00000004,
+ 128 + + 0x00000000, 0x00000000, 0x55555040, 0x00505051, 0x00050040, 0x55554000,
+ 129 + + 0x51659559, 0x00001000, 0x15000010, 0x55455555, 0x41404051, 0x00001010,
+ 130 + + 0x00000014, 0x00000000};
+ 131 + +560 return arr;
+ 132 + + }
+ 133 + +
+ 134 + + #if defined(BOOST_JSON_RYU_HAS_UINT128)
+ 135 + +
+ 136 + + // Computes 5^i in the form required by Ryu, and stores it in the given pointer.
+ 137 + + inline
+ 138 + + void
+ 139 + +652 double_computePow5(
+ 140 + + const std::uint32_t i,
+ 141 + + std::uint64_t* const result)
+ 142 + + {
+ 143 + +652 const std::uint32_t base = i / POW5_TABLE_SIZE;
+ 144 + +652 const std::uint32_t base2 = base * POW5_TABLE_SIZE;
+ 145 + +652 const std::uint32_t offset = i - base2;
+ 146 + +652 const std::uint64_t* const mul = DOUBLE_POW5_SPLIT2()[base];
+ 147 + +652 if (offset == 0)
+ 148 + + {
+ 149 + +26 result[0] = mul[0];
+ 150 + +26 result[1] = mul[1];
+ 151 + +26 return;
+ 152 + + }
+ 153 + +626 const std::uint64_t m = DOUBLE_POW5_TABLE()[offset];
+ 154 + +626 const uint128_t b0 = ((uint128_t)m) * mul[0];
+ 155 + +626 const uint128_t b2 = ((uint128_t)m) * mul[1];
+ 156 + +626 const std::uint32_t delta = pow5bits(i) - pow5bits(base2);
+ 157 + +626 const uint128_t shiftedSum = (b0 >> delta) + (b2 << (64 - delta)) + ((POW5_OFFSETS()[base] >> offset) & 1);
+ 158 + +626 result[0] = (std::uint64_t)shiftedSum;
+ 159 + +626 result[1] = (std::uint64_t)(shiftedSum >> 64);
+ 160 + + }
+ 161 + +
+ 162 + + // Computes 5^-i in the form required by Ryu, and stores it in the given pointer.
+ 163 + + inline
+ 164 + + void
+ 165 + +584 double_computeInvPow5(
+ 166 + + const std::uint32_t i,
+ 167 + + std::uint64_t* const result)
+ 168 + + {
+ 169 + +584 const std::uint32_t base = (i + POW5_TABLE_SIZE - 1) / POW5_TABLE_SIZE;
+ 170 + +584 const std::uint32_t base2 = base * POW5_TABLE_SIZE;
+ 171 + +584 const std::uint32_t offset = base2 - i;
+ 172 + +584 const std::uint64_t* const mul = DOUBLE_POW5_INV_SPLIT2()[base]; // 1/5^base2
+ 173 + +584 if (offset == 0)
+ 174 + + {
+ 175 + +24 result[0] = mul[0];
+ 176 + +24 result[1] = mul[1];
+ 177 + +24 return;
+ 178 + + }
+ 179 + +560 const std::uint64_t m = DOUBLE_POW5_TABLE()[offset]; // 5^offset
+ 180 + +560 const uint128_t b0 = ((uint128_t)m) * (mul[0] - 1);
+ 181 + +560 const uint128_t b2 = ((uint128_t)m) * mul[1]; // 1/5^base2 * 5^offset = 1/5^(base2-offset) = 1/5^i
+ 182 + +560 const std::uint32_t delta = pow5bits(base2) - pow5bits(i);
+ 183 + + const uint128_t shiftedSum =
+ 184 + +560 ((b0 >> delta) + (b2 << (64 - delta))) + 1 + ((POW5_INV_OFFSETS()[i / 16] >> ((i % 16) << 1)) & 3);
+ 185 + +560 result[0] = (std::uint64_t)shiftedSum;
+ 186 + +560 result[1] = (std::uint64_t)(shiftedSum >> 64);
+ 187 + + }
+ 188 + +
+ 189 + + #else // defined(BOOST_JSON_RYU_HAS_UINT128)
+ 190 + +
+ 191 + + // Computes 5^i in the form required by Ryu, and stores it in the given pointer.
+ 192 + + inline
+ 193 + + void
+ 194 + + double_computePow5(
+ 195 + + const std::uint32_t i,
+ 196 + + std::uint64_t* const result)
+ 197 + + {
+ 198 + + const std::uint32_t base = i / POW5_TABLE_SIZE;
+ 199 + + const std::uint32_t base2 = base * POW5_TABLE_SIZE;
+ 200 + + const std::uint32_t offset = i - base2;
+ 201 + + const std::uint64_t* const mul = DOUBLE_POW5_SPLIT2()[base];
+ 202 + + if (offset == 0)
+ 203 + + {
+ 204 + + result[0] = mul[0];
+ 205 + + result[1] = mul[1];
+ 206 + + return;
+ 207 + + }
+ 208 + + std::uint64_t const m = DOUBLE_POW5_TABLE()[offset];
+ 209 + + std::uint64_t high1;
+ 210 + + std::uint64_t const low1 = umul128(m, mul[1], &high1);
+ 211 + + std::uint64_t high0;
+ 212 + + std::uint64_t const low0 = umul128(m, mul[0], &high0);
+ 213 + + std::uint64_t const sum = high0 + low1;
+ 214 + + if (sum < high0)
+ 215 + + ++high1; // overflow into high1
+ 216 + + // high1 | sum | low0
+ 217 + + std::uint32_t const delta = pow5bits(i) - pow5bits(base2);
+ 218 + + result[0] = shiftright128(low0, sum, delta) + ((POW5_OFFSETS()[base] >> offset) & 1);
+ 219 + + result[1] = shiftright128(sum, high1, delta);
+ 220 + + }
+ 221 + +
+ 222 + + // Computes 5^-i in the form required by Ryu, and stores it in the given pointer.
+ 223 + + inline
+ 224 + + void
+ 225 + + double_computeInvPow5(
+ 226 + + const std::uint32_t i,
+ 227 + + std::uint64_t* const result)
+ 228 + + {
+ 229 + + const std::uint32_t base = (i + POW5_TABLE_SIZE - 1) / POW5_TABLE_SIZE;
+ 230 + + const std::uint32_t base2 = base * POW5_TABLE_SIZE;
+ 231 + + const std::uint32_t offset = base2 - i;
+ 232 + + const std::uint64_t* const mul = DOUBLE_POW5_INV_SPLIT2()[base]; // 1/5^base2
+ 233 + + if (offset == 0)
+ 234 + + {
+ 235 + + result[0] = mul[0];
+ 236 + + result[1] = mul[1];
+ 237 + + return;
+ 238 + + }
+ 239 + + std::uint64_t const m = DOUBLE_POW5_TABLE()[offset];
+ 240 + + std::uint64_t high1;
+ 241 + + std::uint64_t const low1 = umul128(m, mul[1], &high1);
+ 242 + + std::uint64_t high0;
+ 243 + + std::uint64_t const low0 = umul128(m, mul[0] - 1, &high0);
+ 244 + + std::uint64_t const sum = high0 + low1;
+ 245 + + if (sum < high0)
+ 246 + + ++high1; // overflow into high1
+ 247 + + // high1 | sum | low0
+ 248 + + std::uint32_t const delta = pow5bits(base2) - pow5bits(i);
+ 249 + + result[0] = shiftright128(low0, sum, delta) + 1 + ((POW5_INV_OFFSETS()[i / 16] >> ((i % 16) << 1)) & 3);
+ 250 + + result[1] = shiftright128(sum, high1, delta);
+ 251 + + }
+ 252 + +
+ 253 + + #endif // defined(BOOST_JSON_RYU_HAS_UINT128)
+ 254 + +
+ 255 + + #endif // defined(BOOST_JSON_RYU_OPTIMIZE_SIZE)
+ 256 + +
+ 257 + + } // detail
+ 258 + + } // ryu
+ 259 + +
+ 260 + + } // detail
+ 261 + + } // namespace json
+ 262 + + } // namespace boost
+ 263 + +
+ 264 + + #endif
+ 265 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.d2s.ipp.5c6823db6d8cdf35aa2e1efe1dbd8e24.html b/json/gcovr/index.d2s.ipp.5c6823db6d8cdf35aa2e1efe1dbd8e24.html new file mode 100644 index 00000000..730e4376 --- /dev/null +++ b/json/gcovr/index.d2s.ipp.5c6823db6d8cdf35aa2e1efe1dbd8e24.html @@ -0,0 +1,7966 @@ + + + + + + detail/ryu/impl/d2s.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/ryu/impl/d2s.ipp

+
+ + 99.6% Lines (224/225) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/ryu/impl/d2s.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2018 Ulf Adams
+ 2 + + //
+ 3 + + // The contents of this file may be used under the terms of the Apache License,
+ 4 + + // Version 2.0.
+ 5 + + //
+ 6 + + // (See accompanying file LICENSE-Apache or copy at
+ 7 + + // http://www.apache.org/licenses/LICENSE-2.0)
+ 8 + + //
+ 9 + + // Alternatively, the contents of this file may be used under the terms of
+ 10 + + // the Boost Software License, Version 1.0.
+ 11 + + // (See accompanying file LICENSE-Boost or copy at
+ 12 + + // https://www.boost.org/LICENSE_1_0.txt)
+ 13 + + //
+ 14 + + // Unless required by applicable law or agreed to in writing, this software
+ 15 + + // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ 16 + + // KIND, either express or implied.
+ 17 + +
+ 18 + + // Runtime compiler options:
+ 19 + + // -DRYU_DEBUG Generate verbose debugging output to stdout.
+ 20 + + //
+ 21 + + // -DRYU_ONLY_64_BIT_OPS Avoid using uint128_t or 64-bit intrinsics. Slower,
+ 22 + + // depending on your compiler.
+ 23 + + //
+ 24 + + // -DRYU_OPTIMIZE_SIZE Use smaller lookup tables. Instead of storing every
+ 25 + + // required power of 5, only store every 26th entry, and compute
+ 26 + + // intermediate values with a multiplication. This reduces the lookup table
+ 27 + + // size by about 10x (only one case, and only double) at the cost of some
+ 28 + + // performance. Currently requires MSVC intrinsics.
+ 29 + +
+ 30 + + /*
+ 31 + + This is a derivative work
+ 32 + + */
+ 33 + +
+ 34 + + #ifndef BOOST_JSON_DETAIL_RYU_IMPL_D2S_IPP
+ 35 + + #define BOOST_JSON_DETAIL_RYU_IMPL_D2S_IPP
+ 36 + +
+ 37 + + #include <boost/json/detail/ryu/ryu.hpp>
+ 38 + + #include <cstdlib>
+ 39 + + #include <cstring>
+ 40 + +
+ 41 + + #ifdef RYU_DEBUG
+ 42 + + #include <stdio.h>
+ 43 + + #endif
+ 44 + +
+ 45 + + // ABSL avoids uint128_t on Win32 even if __SIZEOF_INT128__ is defined.
+ 46 + + // Let's do the same for now.
+ 47 + + #if defined(__SIZEOF_INT128__) && !defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS)
+ 48 + + #define BOOST_JSON_RYU_HAS_UINT128
+ 49 + + #elif defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS) && defined(_M_X64)
+ 50 + + #define BOOST_JSON_RYU_HAS_64_BIT_INTRINSICS
+ 51 + + #endif
+ 52 + +
+ 53 + + #include <boost/json/detail/ryu/detail/common.hpp>
+ 54 + + #include <boost/json/detail/ryu/detail/digit_table.hpp>
+ 55 + + #include <boost/json/detail/ryu/detail/d2s.hpp>
+ 56 + + #include <boost/json/detail/ryu/detail/d2s_intrinsics.hpp>
+ 57 + +
+ 58 + + namespace boost {
+ 59 + + namespace json {
+ 60 + + namespace detail {
+ 61 + +
+ 62 + + namespace ryu {
+ 63 + + namespace detail {
+ 64 + +
+ 65 + + // We need a 64x128-bit multiplication and a subsequent 128-bit shift.
+ 66 + + // Multiplication:
+ 67 + + // The 64-bit factor is variable and passed in, the 128-bit factor comes
+ 68 + + // from a lookup table. We know that the 64-bit factor only has 55
+ 69 + + // significant bits (i.e., the 9 topmost bits are zeros). The 128-bit
+ 70 + + // factor only has 124 significant bits (i.e., the 4 topmost bits are
+ 71 + + // zeros).
+ 72 + + // Shift:
+ 73 + + // In principle, the multiplication result requires 55 + 124 = 179 bits to
+ 74 + + // represent. However, we then shift this value to the right by j, which is
+ 75 + + // at least j >= 115, so the result is guaranteed to fit into 179 - 115 = 64
+ 76 + + // bits. This means that we only need the topmost 64 significant bits of
+ 77 + + // the 64x128-bit multiplication.
+ 78 + + //
+ 79 + + // There are several ways to do this:
+ 80 + + // 1. Best case: the compiler exposes a 128-bit type.
+ 81 + + // We perform two 64x64-bit multiplications, add the higher 64 bits of the
+ 82 + + // lower result to the higher result, and shift by j - 64 bits.
+ 83 + + //
+ 84 + + // We explicitly cast from 64-bit to 128-bit, so the compiler can tell
+ 85 + + // that these are only 64-bit inputs, and can map these to the best
+ 86 + + // possible sequence of assembly instructions.
+ 87 + + // x64 machines happen to have matching assembly instructions for
+ 88 + + // 64x64-bit multiplications and 128-bit shifts.
+ 89 + + //
+ 90 + + // 2. Second best case: the compiler exposes intrinsics for the x64 assembly
+ 91 + + // instructions mentioned in 1.
+ 92 + + //
+ 93 + + // 3. We only have 64x64 bit instructions that return the lower 64 bits of
+ 94 + + // the result, i.e., we have to use plain C.
+ 95 + + // Our inputs are less than the full width, so we have three options:
+ 96 + + // a. Ignore this fact and just implement the intrinsics manually.
+ 97 + + // b. Split both into 31-bit pieces, which guarantees no internal overflow,
+ 98 + + // but requires extra work upfront (unless we change the lookup table).
+ 99 + + // c. Split only the first factor into 31-bit pieces, which also guarantees
+ 100 + + // no internal overflow, but requires extra work since the intermediate
+ 101 + + // results are not perfectly aligned.
+ 102 + + #if defined(BOOST_JSON_RYU_HAS_UINT128)
+ 103 + +
+ 104 + + // Best case: use 128-bit type.
+ 105 + + inline
+ 106 + + std::uint64_t
+ 107 + +786 mulShift(
+ 108 + + const std::uint64_t m,
+ 109 + + const std::uint64_t* const mul,
+ 110 + + const std::int32_t j) noexcept
+ 111 + + {
+ 112 + +786 const uint128_t b0 = ((uint128_t) m) * mul[0];
+ 113 + +786 const uint128_t b2 = ((uint128_t) m) * mul[1];
+ 114 + +786 return (std::uint64_t) (((b0 >> 64) + b2) >> (j - 64));
+ 115 + + }
+ 116 + +
+ 117 + + inline
+ 118 + + uint64_t
+ 119 + +262 mulShiftAll(
+ 120 + + const std::uint64_t m,
+ 121 + + const std::uint64_t* const mul,
+ 122 + + std::int32_t const j,
+ 123 + + std::uint64_t* const vp,
+ 124 + + std::uint64_t* const vm,
+ 125 + + const std::uint32_t mmShift) noexcept
+ 126 + + {
+ 127 + + // m <<= 2;
+ 128 + + // uint128_t b0 = ((uint128_t) m) * mul[0]; // 0
+ 129 + + // uint128_t b2 = ((uint128_t) m) * mul[1]; // 64
+ 130 + + //
+ 131 + + // uint128_t hi = (b0 >> 64) + b2;
+ 132 + + // uint128_t lo = b0 & 0xffffffffffffffffull;
+ 133 + + // uint128_t factor = (((uint128_t) mul[1]) << 64) + mul[0];
+ 134 + + // uint128_t vpLo = lo + (factor << 1);
+ 135 + + // *vp = (std::uint64_t) ((hi + (vpLo >> 64)) >> (j - 64));
+ 136 + + // uint128_t vmLo = lo - (factor << mmShift);
+ 137 + + // *vm = (std::uint64_t) ((hi + (vmLo >> 64) - (((uint128_t) 1ull) << 64)) >> (j - 64));
+ 138 + + // return (std::uint64_t) (hi >> (j - 64));
+ 139 + +262 *vp = mulShift(4 * m + 2, mul, j);
+ 140 + +262 *vm = mulShift(4 * m - 1 - mmShift, mul, j);
+ 141 + +262 return mulShift(4 * m, mul, j);
+ 142 + + }
+ 143 + +
+ 144 + + #elif defined(BOOST_JSON_RYU_HAS_64_BIT_INTRINSICS)
+ 145 + +
+ 146 + + inline
+ 147 + + std::uint64_t
+ 148 + + mulShift(
+ 149 + + const std::uint64_t m,
+ 150 + + const std::uint64_t* const mul,
+ 151 + + const std::int32_t j) noexcept
+ 152 + + {
+ 153 + + // m is maximum 55 bits
+ 154 + + std::uint64_t high1; // 128
+ 155 + + std::uint64_t const low1 = umul128(m, mul[1], &high1); // 64
+ 156 + + std::uint64_t high0; // 64
+ 157 + + umul128(m, mul[0], &high0); // 0
+ 158 + + std::uint64_t const sum = high0 + low1;
+ 159 + + if (sum < high0)
+ 160 + + ++high1; // overflow into high1
+ 161 + + return shiftright128(sum, high1, j - 64);
+ 162 + + }
+ 163 + +
+ 164 + + inline
+ 165 + + std::uint64_t
+ 166 + + mulShiftAll(
+ 167 + + const std::uint64_t m,
+ 168 + + const std::uint64_t* const mul,
+ 169 + + const std::int32_t j,
+ 170 + + std::uint64_t* const vp,
+ 171 + + std::uint64_t* const vm,
+ 172 + + const std::uint32_t mmShift) noexcept
+ 173 + + {
+ 174 + + *vp = mulShift(4 * m + 2, mul, j);
+ 175 + + *vm = mulShift(4 * m - 1 - mmShift, mul, j);
+ 176 + + return mulShift(4 * m, mul, j);
+ 177 + + }
+ 178 + +
+ 179 + + #else // !defined(BOOST_JSON_RYU_HAS_UINT128) && !defined(BOOST_JSON_RYU_HAS_64_BIT_INTRINSICS)
+ 180 + +
+ 181 + + inline
+ 182 + + std::uint64_t
+ 183 + + mulShiftAll(
+ 184 + + std::uint64_t m,
+ 185 + + const std::uint64_t* const mul,
+ 186 + + const std::int32_t j,
+ 187 + + std::uint64_t* const vp,
+ 188 + + std::uint64_t* const vm,
+ 189 + + const std::uint32_t mmShift)
+ 190 + + {
+ 191 + + m <<= 1;
+ 192 + + // m is maximum 55 bits
+ 193 + + std::uint64_t tmp;
+ 194 + + std::uint64_t const lo = umul128(m, mul[0], &tmp);
+ 195 + + std::uint64_t hi;
+ 196 + + std::uint64_t const mid = tmp + umul128(m, mul[1], &hi);
+ 197 + + hi += mid < tmp; // overflow into hi
+ 198 + +
+ 199 + + const std::uint64_t lo2 = lo + mul[0];
+ 200 + + const std::uint64_t mid2 = mid + mul[1] + (lo2 < lo);
+ 201 + + const std::uint64_t hi2 = hi + (mid2 < mid);
+ 202 + + *vp = shiftright128(mid2, hi2, (std::uint32_t)(j - 64 - 1));
+ 203 + +
+ 204 + + if (mmShift == 1)
+ 205 + + {
+ 206 + + const std::uint64_t lo3 = lo - mul[0];
+ 207 + + const std::uint64_t mid3 = mid - mul[1] - (lo3 > lo);
+ 208 + + const std::uint64_t hi3 = hi - (mid3 > mid);
+ 209 + + *vm = shiftright128(mid3, hi3, (std::uint32_t)(j - 64 - 1));
+ 210 + + }
+ 211 + + else
+ 212 + + {
+ 213 + + const std::uint64_t lo3 = lo + lo;
+ 214 + + const std::uint64_t mid3 = mid + mid + (lo3 < lo);
+ 215 + + const std::uint64_t hi3 = hi + hi + (mid3 < mid);
+ 216 + + const std::uint64_t lo4 = lo3 - mul[0];
+ 217 + + const std::uint64_t mid4 = mid3 - mul[1] - (lo4 > lo3);
+ 218 + + const std::uint64_t hi4 = hi3 - (mid4 > mid3);
+ 219 + + *vm = shiftright128(mid4, hi4, (std::uint32_t)(j - 64));
+ 220 + + }
+ 221 + +
+ 222 + + return shiftright128(mid, hi, (std::uint32_t)(j - 64 - 1));
+ 223 + + }
+ 224 + +
+ 225 + + #endif // BOOST_JSON_RYU_HAS_64_BIT_INTRINSICS
+ 226 + +
+ 227 + + inline
+ 228 + + std::uint32_t
+ 229 + +538 decimalLength17(
+ 230 + + const std::uint64_t v)
+ 231 + + {
+ 232 + + // This is slightly faster than a loop.
+ 233 + + // The average output length is 16.38 digits, so we check high-to-low.
+ 234 + + // Function precondition: v is not an 18, 19, or 20-digit number.
+ 235 + + // (17 digits are sufficient for round-tripping.)
+ 236 + +538 BOOST_ASSERT(v < 100000000000000000L);
+ 237 + +538 if (v >= 10000000000000000L) { return 17; }
+ 238 + +528 if (v >= 1000000000000000L) { return 16; }
+ 239 + +509 if (v >= 100000000000000L) { return 15; }
+ 240 + +505 if (v >= 10000000000000L) { return 14; }
+ 241 + +500 if (v >= 1000000000000L) { return 13; }
+ 242 + +494 if (v >= 100000000000L) { return 12; }
+ 243 + +489 if (v >= 10000000000L) { return 11; }
+ 244 + +484 if (v >= 1000000000L) { return 10; }
+ 245 + +474 if (v >= 100000000L) { return 9; }
+ 246 + +467 if (v >= 10000000L) { return 8; }
+ 247 + +461 if (v >= 1000000L) { return 7; }
+ 248 + +455 if (v >= 100000L) { return 6; }
+ 249 + +450 if (v >= 10000L) { return 5; }
+ 250 + +445 if (v >= 1000L) { return 4; }
+ 251 + +439 if (v >= 100L) { return 3; }
+ 252 + +421 if (v >= 10L) { return 2; }
+ 253 + +415 return 1;
+ 254 + + }
+ 255 + +
+ 256 + + // A floating decimal representing m * 10^e.
+ 257 + + struct floating_decimal_64
+ 258 + + {
+ 259 + + std::uint64_t mantissa;
+ 260 + + // Decimal exponent's range is -324 to 308
+ 261 + + // inclusive, and can fit in a short if needed.
+ 262 + + std::int32_t exponent;
+ 263 + + };
+ 264 + +
+ 265 + + inline
+ 266 + + floating_decimal_64
+ 267 + +262 d2d(
+ 268 + + const std::uint64_t ieeeMantissa,
+ 269 + + const std::uint32_t ieeeExponent)
+ 270 + + {
+ 271 + + std::int32_t e2;
+ 272 + + std::uint64_t m2;
+ 273 + +262 if (ieeeExponent == 0)
+ 274 + + {
+ 275 + + // We subtract 2 so that the bounds computation has 2 additional bits.
+ 276 + +15 e2 = 1 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2;
+ 277 + +15 m2 = ieeeMantissa;
+ 278 + + }
+ 279 + + else
+ 280 + + {
+ 281 + +247 e2 = (std::int32_t)ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2;
+ 282 + +247 m2 = (1ull << DOUBLE_MANTISSA_BITS) | ieeeMantissa;
+ 283 + + }
+ 284 + +262 const bool even = (m2 & 1) == 0;
+ 285 + +262 const bool acceptBounds = even;
+ 286 + +
+ 287 + + #ifdef RYU_DEBUG
+ 288 + + printf("-> %" PRIu64 " * 2^%d\n", m2, e2 + 2);
+ 289 + + #endif
+ 290 + +
+ 291 + + // Step 2: Determine the interval of valid decimal representations.
+ 292 + +262 const std::uint64_t mv = 4 * m2;
+ 293 + + // Implicit bool -> int conversion. True is 1, false is 0.
+ 294 + +262 const std::uint32_t mmShift = ieeeMantissa != 0 || ieeeExponent <= 1;
+ 295 + + // We would compute mp and mm like this:
+ 296 + + // uint64_t mp = 4 * m2 + 2;
+ 297 + + // uint64_t mm = mv - 1 - mmShift;
+ 298 + +
+ 299 + + // Step 3: Convert to a decimal power base using 128-bit arithmetic.
+ 300 + + std::uint64_t vr, vp, vm;
+ 301 + + std::int32_t e10;
+ 302 + +262 bool vmIsTrailingZeros = false;
+ 303 + +262 bool vrIsTrailingZeros = false;
+ 304 + +262 if (e2 >= 0) {
+ 305 + + // I tried special-casing q == 0, but there was no effect on performance.
+ 306 + + // This expression is slightly faster than max(0, log10Pow2(e2) - 1).
+ 307 + +128 const std::uint32_t q = log10Pow2(e2) - (e2 > 3);
+ 308 + +128 e10 = (std::int32_t)q;
+ 309 + +128 const std::int32_t k = DOUBLE_POW5_INV_BITCOUNT + pow5bits((int32_t)q) - 1;
+ 310 + +128 const std::int32_t i = -e2 + (std::int32_t)q + k;
+ 311 + + #if defined(BOOST_JSON_RYU_OPTIMIZE_SIZE)
+ 312 + + uint64_t pow5[2];
+ 313 + + double_computeInvPow5(q, pow5);
+ 314 + + vr = mulShiftAll(m2, pow5, i, &vp, &vm, mmShift);
+ 315 + + #else
+ 316 + +128 vr = mulShiftAll(m2, DOUBLE_POW5_INV_SPLIT()[q], i, &vp, &vm, mmShift);
+ 317 + + #endif
+ 318 + + #ifdef RYU_DEBUG
+ 319 + + printf("%" PRIu64 " * 2^%d / 10^%u\n", mv, e2, q);
+ 320 + + printf("V+=%" PRIu64 "\nV =%" PRIu64 "\nV-=%" PRIu64 "\n", vp, vr, vm);
+ 321 + + #endif
+ 322 + +128 if (q <= 21)
+ 323 + + {
+ 324 + + // This should use q <= 22, but I think 21 is also safe. Smaller values
+ 325 + + // may still be safe, but it's more difficult to reason about them.
+ 326 + + // Only one of mp, mv, and mm can be a multiple of 5, if any.
+ 327 + +114 const std::uint32_t mvMod5 = ((std::uint32_t)mv) - 5 * ((std::uint32_t)div5(mv));
+ 328 + +114 if (mvMod5 == 0)
+ 329 + + {
+ 330 + +86 vrIsTrailingZeros = multipleOfPowerOf5(mv, q);
+ 331 + + }
+ 332 + +28 else if (acceptBounds)
+ 333 + + {
+ 334 + + // Same as min(e2 + (~mm & 1), pow5Factor(mm)) >= q
+ 335 + + // <=> e2 + (~mm & 1) >= q && pow5Factor(mm) >= q
+ 336 + + // <=> true && pow5Factor(mm) >= q, since e2 >= q.
+ 337 + +11 vmIsTrailingZeros = multipleOfPowerOf5(mv - 1 - mmShift, q);
+ 338 + + }
+ 339 + + else
+ 340 + + {
+ 341 + + // Same as min(e2 + 1, pow5Factor(mp)) >= q.
+ 342 + +17 vp -= multipleOfPowerOf5(mv + 2, q);
+ 343 + + }
+ 344 + + }
+ 345 + + }
+ 346 + + else
+ 347 + + {
+ 348 + + // This expression is slightly faster than max(0, log10Pow5(-e2) - 1).
+ 349 + +134 const std::uint32_t q = log10Pow5(-e2) - (-e2 > 1);
+ 350 + +134 e10 = (std::int32_t)q + e2;
+ 351 + +134 const std::int32_t i = -e2 - (std::int32_t)q;
+ 352 + +134 const std::int32_t k = pow5bits(i) - DOUBLE_POW5_BITCOUNT;
+ 353 + +134 const std::int32_t j = (std::int32_t)q - k;
+ 354 + + #if defined(BOOST_JSON_RYU_OPTIMIZE_SIZE)
+ 355 + + std::uint64_t pow5[2];
+ 356 + + double_computePow5(i, pow5);
+ 357 + + vr = mulShiftAll(m2, pow5, j, &vp, &vm, mmShift);
+ 358 + + #else
+ 359 + +134 vr = mulShiftAll(m2, DOUBLE_POW5_SPLIT()[i], j, &vp, &vm, mmShift);
+ 360 + + #endif
+ 361 + + #ifdef RYU_DEBUG
+ 362 + + printf("%" PRIu64 " * 5^%d / 10^%u\n", mv, -e2, q);
+ 363 + + printf("%u %d %d %d\n", q, i, k, j);
+ 364 + + printf("V+=%" PRIu64 "\nV =%" PRIu64 "\nV-=%" PRIu64 "\n", vp, vr, vm);
+ 365 + + #endif
+ 366 + +134 if (q <= 1)
+ 367 + + {
+ 368 + + // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits.
+ 369 + + // mv = 4 * m2, so it always has at least two trailing 0 bits.
+ 370 + +3 vrIsTrailingZeros = true;
+ 371 + +3 if (acceptBounds)
+ 372 + + {
+ 373 + + // mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff mmShift == 1.
+ 374 + +3 vmIsTrailingZeros = mmShift == 1;
+ 375 + + }
+ 376 + + else
+ 377 + + {
+ 378 + + // mp = mv + 2, so it always has at least one trailing 0 bit.
+ 379 + + --vp;
+ 380 + + }
+ 381 + + }
+ 382 + +131 else if (q < 63)
+ 383 + + {
+ 384 + + // TODO(ulfjack): Use a tighter bound here.
+ 385 + + // We want to know if the full product has at least q trailing zeros.
+ 386 + + // We need to compute min(p2(mv), p5(mv) - e2) >= q
+ 387 + + // <=> p2(mv) >= q && p5(mv) - e2 >= q
+ 388 + + // <=> p2(mv) >= q (because -e2 >= q)
+ 389 + +96 vrIsTrailingZeros = multipleOfPowerOf2(mv, q);
+ 390 + + #ifdef RYU_DEBUG
+ 391 + + printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
+ 392 + + #endif
+ 393 + + }
+ 394 + + }
+ 395 + + #ifdef RYU_DEBUG
+ 396 + + printf("e10=%d\n", e10);
+ 397 + + printf("V+=%" PRIu64 "\nV =%" PRIu64 "\nV-=%" PRIu64 "\n", vp, vr, vm);
+ 398 + + printf("vm is trailing zeros=%s\n", vmIsTrailingZeros ? "true" : "false");
+ 399 + + printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
+ 400 + + #endif
+ 401 + +
+ 402 + + // Step 4: Find the shortest decimal representation in the interval of valid representations.
+ 403 + +262 std::int32_t removed = 0;
+ 404 + +262 std::uint8_t lastRemovedDigit = 0;
+ 405 + + std::uint64_t output;
+ 406 + + // On average, we remove ~2 digits.
+ 407 + +262 if (vmIsTrailingZeros || vrIsTrailingZeros)
+ 408 + + {
+ 409 + + // General case, which happens rarely (~0.7%).
+ 410 + + for (;;)
+ 411 + + {
+ 412 + +1663 const std::uint64_t vpDiv10 = div10(vp);
+ 413 + +1663 const std::uint64_t vmDiv10 = div10(vm);
+ 414 + +1663 if (vpDiv10 <= vmDiv10)
+ 415 + +94 break;
+ 416 + +1569 const std::uint32_t vmMod10 = ((std::uint32_t)vm) - 10 * ((std::uint32_t)vmDiv10);
+ 417 + +1569 const std::uint64_t vrDiv10 = div10(vr);
+ 418 + +1569 const std::uint32_t vrMod10 = ((std::uint32_t)vr) - 10 * ((std::uint32_t)vrDiv10);
+ 419 + +1569 vmIsTrailingZeros &= vmMod10 == 0;
+ 420 + +1569 vrIsTrailingZeros &= lastRemovedDigit == 0;
+ 421 + +1569 lastRemovedDigit = (uint8_t)vrMod10;
+ 422 + +1569 vr = vrDiv10;
+ 423 + +1569 vp = vpDiv10;
+ 424 + +1569 vm = vmDiv10;
+ 425 + +1569 ++removed;
+ 426 + +1569 }
+ 427 + + #ifdef RYU_DEBUG
+ 428 + + printf("V+=%" PRIu64 "\nV =%" PRIu64 "\nV-=%" PRIu64 "\n", vp, vr, vm);
+ 429 + + printf("d-10=%s\n", vmIsTrailingZeros ? "true" : "false");
+ 430 + + #endif
+ 431 + +94 if (vmIsTrailingZeros)
+ 432 + + {
+ 433 + + for (;;)
+ 434 + + {
+ 435 + +3 const std::uint64_t vmDiv10 = div10(vm);
+ 436 + +3 const std::uint32_t vmMod10 = ((std::uint32_t)vm) - 10 * ((std::uint32_t)vmDiv10);
+ 437 + +3 if (vmMod10 != 0)
+ 438 + +2 break;
+ 439 + +1 const std::uint64_t vpDiv10 = div10(vp);
+ 440 + +1 const std::uint64_t vrDiv10 = div10(vr);
+ 441 + +1 const std::uint32_t vrMod10 = ((std::uint32_t)vr) - 10 * ((std::uint32_t)vrDiv10);
+ 442 + +1 vrIsTrailingZeros &= lastRemovedDigit == 0;
+ 443 + +1 lastRemovedDigit = (uint8_t)vrMod10;
+ 444 + +1 vr = vrDiv10;
+ 445 + +1 vp = vpDiv10;
+ 446 + +1 vm = vmDiv10;
+ 447 + +1 ++removed;
+ 448 + +1 }
+ 449 + + }
+ 450 + + #ifdef RYU_DEBUG
+ 451 + + printf("%" PRIu64 " %d\n", vr, lastRemovedDigit);
+ 452 + + printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
+ 453 + + #endif
+ 454 + +94 if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0)
+ 455 + + {
+ 456 + + // Round even if the exact number is .....50..0.
+ 457 + +1 lastRemovedDigit = 4;
+ 458 + + }
+ 459 + + // We need to take vr + 1 if vr is outside bounds or we need to round up.
+ 460 + +94 output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5);
+ 461 + +94 }
+ 462 + + else
+ 463 + + {
+ 464 + + // Specialized for the common case (~99.3%). Percentages below are relative to this.
+ 465 + +168 bool roundUp = false;
+ 466 + +168 const std::uint64_t vpDiv100 = div100(vp);
+ 467 + +168 const std::uint64_t vmDiv100 = div100(vm);
+ 468 + +168 if (vpDiv100 > vmDiv100)
+ 469 + + {
+ 470 + + // Optimization: remove two digits at a time (~86.2%).
+ 471 + +161 const std::uint64_t vrDiv100 = div100(vr);
+ 472 + +161 const std::uint32_t vrMod100 = ((std::uint32_t)vr) - 100 * ((std::uint32_t)vrDiv100);
+ 473 + +161 roundUp = vrMod100 >= 50;
+ 474 + +161 vr = vrDiv100;
+ 475 + +161 vp = vpDiv100;
+ 476 + +161 vm = vmDiv100;
+ 477 + +161 removed += 2;
+ 478 + + }
+ 479 + + // Loop iterations below (approximately), without optimization above:
+ 480 + + // 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02%
+ 481 + + // Loop iterations below (approximately), with optimization above:
+ 482 + + // 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02%
+ 483 + + for (;;)
+ 484 + + {
+ 485 + +2256 const std::uint64_t vpDiv10 = div10(vp);
+ 486 + +2256 const std::uint64_t vmDiv10 = div10(vm);
+ 487 + +2256 if (vpDiv10 <= vmDiv10)
+ 488 + +168 break;
+ 489 + +2088 const std::uint64_t vrDiv10 = div10(vr);
+ 490 + +2088 const std::uint32_t vrMod10 = ((std::uint32_t)vr) - 10 * ((std::uint32_t)vrDiv10);
+ 491 + +2088 roundUp = vrMod10 >= 5;
+ 492 + +2088 vr = vrDiv10;
+ 493 + +2088 vp = vpDiv10;
+ 494 + +2088 vm = vmDiv10;
+ 495 + +2088 ++removed;
+ 496 + +2088 }
+ 497 + + #ifdef RYU_DEBUG
+ 498 + + printf("%" PRIu64 " roundUp=%s\n", vr, roundUp ? "true" : "false");
+ 499 + + printf("vr is trailing zeros=%s\n", vrIsTrailingZeros ? "true" : "false");
+ 500 + + #endif
+ 501 + + // We need to take vr + 1 if vr is outside bounds or we need to round up.
+ 502 + +168 output = vr + (vr == vm || roundUp);
+ 503 + + }
+ 504 + +262 const std::int32_t exp = e10 + removed;
+ 505 + +
+ 506 + + #ifdef RYU_DEBUG
+ 507 + + printf("V+=%" PRIu64 "\nV =%" PRIu64 "\nV-=%" PRIu64 "\n", vp, vr, vm);
+ 508 + + printf("O=%" PRIu64 "\n", output);
+ 509 + + printf("EXP=%d\n", exp);
+ 510 + + #endif
+ 511 + +
+ 512 + + floating_decimal_64 fd;
+ 513 + +262 fd.exponent = exp;
+ 514 + +262 fd.mantissa = output;
+ 515 + +262 return fd;
+ 516 + + }
+ 517 + +
+ 518 + + inline
+ 519 + + int
+ 520 + +538 to_chars(
+ 521 + + const floating_decimal_64 v,
+ 522 + + const bool sign,
+ 523 + + char* const result)
+ 524 + + {
+ 525 + + // Step 5: Print the decimal representation.
+ 526 + +538 int index = 0;
+ 527 + +538 if (sign)
+ 528 + +129 result[index++] = '-';
+ 529 + +
+ 530 + +538 std::uint64_t output = v.mantissa;
+ 531 + +538 std::uint32_t const olength = decimalLength17(output);
+ 532 + +
+ 533 + + #ifdef RYU_DEBUG
+ 534 + + printf("DIGITS=%" PRIu64 "\n", v.mantissa);
+ 535 + + printf("OLEN=%u\n", olength);
+ 536 + + printf("EXP=%u\n", v.exponent + olength);
+ 537 + + #endif
+ 538 + +
+ 539 + + // Print the decimal digits.
+ 540 + + // The following code is equivalent to:
+ 541 + + // for (uint32_t i = 0; i < olength - 1; ++i) {
+ 542 + + // const uint32_t c = output % 10; output /= 10;
+ 543 + + // result[index + olength - i] = (char) ('0' + c);
+ 544 + + // }
+ 545 + + // result[index] = '0' + output % 10;
+ 546 + +
+ 547 + +538 std::uint32_t i = 0;
+ 548 + + // We prefer 32-bit operations, even on 64-bit platforms.
+ 549 + + // We have at most 17 digits, and uint32_t can store 9 digits.
+ 550 + + // If output doesn't fit into uint32_t, we cut off 8 digits,
+ 551 + + // so the rest will fit into uint32_t.
+ 552 + +538 if ((output >> 32) != 0)
+ 553 + + {
+ 554 + + // Expensive 64-bit division.
+ 555 + +59 std::uint64_t const q = div1e8(output);
+ 556 + +59 std::uint32_t output2 = ((std::uint32_t)output) - 100000000 * ((std::uint32_t)q);
+ 557 + +59 output = q;
+ 558 + +
+ 559 + +59 const std::uint32_t c = output2 % 10000;
+ 560 + +59 output2 /= 10000;
+ 561 + +59 const std::uint32_t d = output2 % 10000;
+ 562 + +59 const std::uint32_t c0 = (c % 100) << 1;
+ 563 + +59 const std::uint32_t c1 = (c / 100) << 1;
+ 564 + +59 const std::uint32_t d0 = (d % 100) << 1;
+ 565 + +59 const std::uint32_t d1 = (d / 100) << 1;
+ 566 + +59 std::memcpy(result + index + olength - i - 1, DIGIT_TABLE() + c0, 2);
+ 567 + +59 std::memcpy(result + index + olength - i - 3, DIGIT_TABLE() + c1, 2);
+ 568 + +59 std::memcpy(result + index + olength - i - 5, DIGIT_TABLE() + d0, 2);
+ 569 + +59 std::memcpy(result + index + olength - i - 7, DIGIT_TABLE() + d1, 2);
+ 570 + +59 i += 8;
+ 571 + + }
+ 572 + +538 uint32_t output2 = (std::uint32_t)output;
+ 573 + +638 while (output2 >= 10000)
+ 574 + + {
+ 575 + + #ifdef __clang__ // https://bugs.llvm.org/show_bug.cgi?id=38217
+ 576 + + const uint32_t c = output2 - 10000 * (output2 / 10000);
+ 577 + + #else
+ 578 + +100 const uint32_t c = output2 % 10000;
+ 579 + + #endif
+ 580 + +100 output2 /= 10000;
+ 581 + +100 const uint32_t c0 = (c % 100) << 1;
+ 582 + +100 const uint32_t c1 = (c / 100) << 1;
+ 583 + +100 memcpy(result + index + olength - i - 1, DIGIT_TABLE() + c0, 2);
+ 584 + +100 memcpy(result + index + olength - i - 3, DIGIT_TABLE() + c1, 2);
+ 585 + +100 i += 4;
+ 586 + + }
+ 587 + +538 if (output2 >= 100) {
+ 588 + +69 const uint32_t c = (output2 % 100) << 1;
+ 589 + +69 output2 /= 100;
+ 590 + +69 memcpy(result + index + olength - i - 1, DIGIT_TABLE() + c, 2);
+ 591 + +69 i += 2;
+ 592 + + }
+ 593 + +538 if (output2 >= 10) {
+ 594 + +62 const uint32_t c = output2 << 1;
+ 595 + + // We can't use memcpy here: the decimal dot goes between these two digits.
+ 596 + +62 result[index + olength - i] = DIGIT_TABLE()[c + 1];
+ 597 + +62 result[index] = DIGIT_TABLE()[c];
+ 598 + + }
+ 599 + + else {
+ 600 + +476 result[index] = (char)('0' + output2);
+ 601 + + }
+ 602 + +
+ 603 + + // Print decimal point if needed.
+ 604 + +538 if (olength > 1) {
+ 605 + +123 result[index + 1] = '.';
+ 606 + +123 index += olength + 1;
+ 607 + + }
+ 608 + + else {
+ 609 + +415 ++index;
+ 610 + + }
+ 611 + +
+ 612 + + // Print the exponent.
+ 613 + +538 result[index++] = 'E';
+ 614 + +538 int32_t exp = v.exponent + (int32_t)olength - 1;
+ 615 + +538 if (exp < 0) {
+ 616 + +92 result[index++] = '-';
+ 617 + +92 exp = -exp;
+ 618 + + }
+ 619 + +
+ 620 + +538 if (exp >= 100) {
+ 621 + +33 const int32_t c = exp % 10;
+ 622 + +33 memcpy(result + index, DIGIT_TABLE() + 2 * (exp / 10), 2);
+ 623 + +33 result[index + 2] = (char)('0' + c);
+ 624 + +33 index += 3;
+ 625 + + }
+ 626 + +505 else if (exp >= 10) {
+ 627 + +180 memcpy(result + index, DIGIT_TABLE() + 2 * exp, 2);
+ 628 + +180 index += 2;
+ 629 + + }
+ 630 + + else {
+ 631 + +325 result[index++] = (char)('0' + exp);
+ 632 + + }
+ 633 + +
+ 634 + +538 return index;
+ 635 + + }
+ 636 + +
+ 637 + +538 static inline bool d2d_small_int(const uint64_t ieeeMantissa, const uint32_t ieeeExponent,
+ 638 + + floating_decimal_64* const v) {
+ 639 + +538 const uint64_t m2 = (1ull << DOUBLE_MANTISSA_BITS) | ieeeMantissa;
+ 640 + +538 const int32_t e2 = (int32_t) ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS;
+ 641 + +
+ 642 + +538 if (e2 > 0) {
+ 643 + + // f = m2 * 2^e2 >= 2^53 is an integer.
+ 644 + + // Ignore this case for now.
+ 645 + +131 return false;
+ 646 + + }
+ 647 + +
+ 648 + +407 if (e2 < -52) {
+ 649 + + // f < 1.
+ 650 + +92 return false;
+ 651 + + }
+ 652 + +
+ 653 + + // Since 2^52 <= m2 < 2^53 and 0 <= -e2 <= 52: 1 <= f = m2 / 2^-e2 < 2^53.
+ 654 + + // Test if the lower -e2 bits of the significand are 0, i.e. whether the fraction is 0.
+ 655 + +315 const uint64_t mask = (1ull << -e2) - 1;
+ 656 + +315 const uint64_t fraction = m2 & mask;
+ 657 + +315 if (fraction != 0) {
+ 658 + +39 return false;
+ 659 + + }
+ 660 + +
+ 661 + + // f is an integer in the range [1, 2^53).
+ 662 + + // Note: mantissa might contain trailing (decimal) 0's.
+ 663 + + // Note: since 2^53 < 10^16, there is no need to adjust decimalLength17().
+ 664 + +276 v->mantissa = m2 >> -e2;
+ 665 + +276 v->exponent = 0;
+ 666 + +276 return true;
+ 667 + + }
+ 668 + +
+ 669 + + } // detail
+ 670 + +
+ 671 + + int
+ 672 + +609 d2s_buffered_n(
+ 673 + + double f,
+ 674 + + char* result,
+ 675 + + bool allow_infinity_and_nan) noexcept
+ 676 + + {
+ 677 + + using namespace detail;
+ 678 + + // Step 1: Decode the floating-point number, and unify normalized and subnormal cases.
+ 679 + +609 std::uint64_t const bits = double_to_bits(f);
+ 680 + +
+ 681 + + #ifdef RYU_DEBUG
+ 682 + + printf("IN=");
+ 683 + + for (std::int32_t bit = 63; bit >= 0; --bit) {
+ 684 + + printf("%d", (int)((bits >> bit) & 1));
+ 685 + + }
+ 686 + + printf("\n");
+ 687 + + #endif
+ 688 + +
+ 689 + + // Decode bits into sign, mantissa, and exponent.
+ 690 + +609 const bool ieeeSign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0;
+ 691 + +609 const std::uint64_t ieeeMantissa = bits & ((1ull << DOUBLE_MANTISSA_BITS) - 1);
+ 692 + +609 const std::uint32_t ieeeExponent = (std::uint32_t)((bits >> DOUBLE_MANTISSA_BITS) & ((1u << DOUBLE_EXPONENT_BITS) - 1));
+ 693 + + // Case distinction; exit early for the easy cases.
+ 694 + +609 if (ieeeExponent == ((1u << DOUBLE_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) {
+ 695 + + // We changed how special numbers are output by default
+ 696 + +71 if (allow_infinity_and_nan)
+ 697 + +11 return copy_special_str(result, ieeeSign, ieeeExponent != 0, ieeeMantissa != 0);
+ 698 + + else
+ 699 + +60 return copy_special_str_conforming(result, ieeeSign, ieeeExponent != 0, ieeeMantissa != 0);
+ 700 + +
+ 701 + + }
+ 702 + +
+ 703 + + floating_decimal_64 v;
+ 704 + +538 const bool isSmallInt = d2d_small_int(ieeeMantissa, ieeeExponent, &v);
+ 705 + +538 if (isSmallInt) {
+ 706 + + // For small integers in the range [1, 2^53), v.mantissa might contain trailing (decimal) zeros.
+ 707 + + // For scientific notation we need to move these zeros into the exponent.
+ 708 + + // (This is not needed for fixed-point notation, so it might be beneficial to trim
+ 709 + + // trailing zeros in to_chars only if needed - once fixed-point notation output is implemented.)
+ 710 + + for (;;) {
+ 711 + +698 std::uint64_t const q = div10(v.mantissa);
+ 712 + +698 std::uint32_t const r = ((std::uint32_t) v.mantissa) - 10 * ((std::uint32_t) q);
+ 713 + +698 if (r != 0)
+ 714 + +276 break;
+ 715 + +422 v.mantissa = q;
+ 716 + +422 ++v.exponent;
+ 717 + +422 }
+ 718 + + }
+ 719 + + else {
+ 720 + +262 v = d2d(ieeeMantissa, ieeeExponent);
+ 721 + + }
+ 722 + +
+ 723 + +538 return to_chars(v, ieeeSign, result);
+ 724 + + }
+ 725 + +
+ 726 + + } // ryu
+ 727 + +
+ 728 + + } // detail
+ 729 + + } // namespace json
+ 730 + + } // namespace boost
+ 731 + +
+ 732 + + #endif
+ 733 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.d2s_full_table.hpp.08b587354545c40cd025a0cdb25e60c9.html b/json/gcovr/index.d2s_full_table.hpp.08b587354545c40cd025a0cdb25e60c9.html new file mode 100644 index 00000000..fae46192 --- /dev/null +++ b/json/gcovr/index.d2s_full_table.hpp.08b587354545c40cd025a0cdb25e60c9.html @@ -0,0 +1,5030 @@ + + + + + + detail/ryu/detail/d2s_full_table.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/ryu/detail/d2s_full_table.hpp

+
+ + 100.0% Lines (4/4) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/ryu/detail/d2s_full_table.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2018 Ulf Adams
+ 2 + + //
+ 3 + + // The contents of this file may be used under the terms of the Apache License,
+ 4 + + // Version 2.0.
+ 5 + + //
+ 6 + + // (See accompanying file LICENSE-Apache or copy at
+ 7 + + // http://www.apache.org/licenses/LICENSE-2.0)
+ 8 + + //
+ 9 + + // Alternatively, the contents of this file may be used under the terms of
+ 10 + + // the Boost Software License, Version 1.0.
+ 11 + + // (See accompanying file LICENSE-Boost or copy at
+ 12 + + // https://www.boost.org/LICENSE_1_0.txt)
+ 13 + + //
+ 14 + + // Unless required by applicable law or agreed to in writing, this software
+ 15 + + // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ 16 + + // KIND, either express or implied.
+ 17 + +
+ 18 + + /*
+ 19 + + This is a derivative work
+ 20 + + */
+ 21 + +
+ 22 + + #ifndef BOOST_JSON_DETAIL_RYU_DETAIL_D2S_FULL_TABLE_HPP
+ 23 + + #define BOOST_JSON_DETAIL_RYU_DETAIL_D2S_FULL_TABLE_HPP
+ 24 + +
+ 25 + + #include <boost/json/detail/config.hpp>
+ 26 + +
+ 27 + + namespace boost {
+ 28 + + namespace json {
+ 29 + + namespace detail {
+ 30 + +
+ 31 + + namespace ryu {
+ 32 + +
+ 33 + + // These tables are generated by PrintDoubleLookupTable.
+ 34 + + inline
+ 35 + + std::uint64_t const
+ 36 + +1004 (&DOUBLE_POW5_INV_SPLIT() noexcept)[292][2]
+ 37 + + {
+ 38 + + static constexpr std::uint64_t arr[292][2] = {
+ 39 + + { 1u, 288230376151711744u }, { 3689348814741910324u, 230584300921369395u },
+ 40 + + { 2951479051793528259u, 184467440737095516u }, { 17118578500402463900u, 147573952589676412u },
+ 41 + + { 12632330341676300947u, 236118324143482260u }, { 10105864273341040758u, 188894659314785808u },
+ 42 + + { 15463389048156653253u, 151115727451828646u }, { 17362724847566824558u, 241785163922925834u },
+ 43 + + { 17579528692795369969u, 193428131138340667u }, { 6684925324752475329u, 154742504910672534u },
+ 44 + + { 18074578149087781173u, 247588007857076054u }, { 18149011334012135262u, 198070406285660843u },
+ 45 + + { 3451162622983977240u, 158456325028528675u }, { 5521860196774363583u, 253530120045645880u },
+ 46 + + { 4417488157419490867u, 202824096036516704u }, { 7223339340677503017u, 162259276829213363u },
+ 47 + + { 7867994130342094503u, 259614842926741381u }, { 2605046489531765280u, 207691874341393105u },
+ 48 + + { 2084037191625412224u, 166153499473114484u }, { 10713157136084480204u, 265845599156983174u },
+ 49 + + { 12259874523609494487u, 212676479325586539u }, { 13497248433629505913u, 170141183460469231u },
+ 50 + + { 14216899864323388813u, 272225893536750770u }, { 11373519891458711051u, 217780714829400616u },
+ 51 + + { 5409467098425058518u, 174224571863520493u }, { 4965798542738183305u, 278759314981632789u },
+ 52 + + { 7661987648932456967u, 223007451985306231u }, { 2440241304404055250u, 178405961588244985u },
+ 53 + + { 3904386087046488400u, 285449538541191976u }, { 17880904128604832013u, 228359630832953580u },
+ 54 + + { 14304723302883865611u, 182687704666362864u }, { 15133127457049002812u, 146150163733090291u },
+ 55 + + { 16834306301794583852u, 233840261972944466u }, { 9778096226693756759u, 187072209578355573u },
+ 56 + + { 15201174610838826053u, 149657767662684458u }, { 2185786488890659746u, 239452428260295134u },
+ 57 + + { 5437978005854438120u, 191561942608236107u }, { 15418428848909281466u, 153249554086588885u },
+ 58 + + { 6222742084545298729u, 245199286538542217u }, { 16046240111861969953u, 196159429230833773u },
+ 59 + + { 1768945645263844993u, 156927543384667019u }, { 10209010661905972635u, 251084069415467230u },
+ 60 + + { 8167208529524778108u, 200867255532373784u }, { 10223115638361732810u, 160693804425899027u },
+ 61 + + { 1599589762411131202u, 257110087081438444u }, { 4969020624670815285u, 205688069665150755u },
+ 62 + + { 3975216499736652228u, 164550455732120604u }, { 13739044029062464211u, 263280729171392966u },
+ 63 + + { 7301886408508061046u, 210624583337114373u }, { 13220206756290269483u, 168499666669691498u },
+ 64 + + { 17462981995322520850u, 269599466671506397u }, { 6591687966774196033u, 215679573337205118u },
+ 65 + + { 12652048002903177473u, 172543658669764094u }, { 9175230360419352987u, 276069853871622551u },
+ 66 + + { 3650835473593572067u, 220855883097298041u }, { 17678063637842498946u, 176684706477838432u },
+ 67 + + { 13527506561580357021u, 282695530364541492u }, { 3443307619780464970u, 226156424291633194u },
+ 68 + + { 6443994910566282300u, 180925139433306555u }, { 5155195928453025840u, 144740111546645244u },
+ 69 + + { 15627011115008661990u, 231584178474632390u }, { 12501608892006929592u, 185267342779705912u },
+ 70 + + { 2622589484121723027u, 148213874223764730u }, { 4196143174594756843u, 237142198758023568u },
+ 71 + + { 10735612169159626121u, 189713759006418854u }, { 12277838550069611220u, 151771007205135083u },
+ 72 + + { 15955192865369467629u, 242833611528216133u }, { 1696107848069843133u, 194266889222572907u },
+ 73 + + { 12424932722681605476u, 155413511378058325u }, { 1433148282581017146u, 248661618204893321u },
+ 74 + + { 15903913885032455010u, 198929294563914656u }, { 9033782293284053685u, 159143435651131725u },
+ 75 + + { 14454051669254485895u, 254629497041810760u }, { 11563241335403588716u, 203703597633448608u },
+ 76 + + { 16629290697806691620u, 162962878106758886u }, { 781423413297334329u, 260740604970814219u },
+ 77 + + { 4314487545379777786u, 208592483976651375u }, { 3451590036303822229u, 166873987181321100u },
+ 78 + + { 5522544058086115566u, 266998379490113760u }, { 4418035246468892453u, 213598703592091008u },
+ 79 + + { 10913125826658934609u, 170878962873672806u }, { 10082303693170474728u, 273406340597876490u },
+ 80 + + { 8065842954536379782u, 218725072478301192u }, { 17520720807854834795u, 174980057982640953u },
+ 81 + + { 5897060404116273733u, 279968092772225526u }, { 1028299508551108663u, 223974474217780421u },
+ 82 + + { 15580034865808528224u, 179179579374224336u }, { 17549358155809824511u, 286687326998758938u },
+ 83 + + { 2971440080422128639u, 229349861599007151u }, { 17134547323305344204u, 183479889279205720u },
+ 84 + + { 13707637858644275364u, 146783911423364576u }, { 14553522944347019935u, 234854258277383322u },
+ 85 + + { 4264120725993795302u, 187883406621906658u }, { 10789994210278856888u, 150306725297525326u },
+ 86 + + { 9885293106962350374u, 240490760476040522u }, { 529536856086059653u, 192392608380832418u },
+ 87 + + { 7802327114352668369u, 153914086704665934u }, { 1415676938738538420u, 246262538727465495u },
+ 88 + + { 1132541550990830736u, 197010030981972396u }, { 15663428499760305882u, 157608024785577916u },
+ 89 + + { 17682787970132668764u, 252172839656924666u }, { 10456881561364224688u, 201738271725539733u },
+ 90 + + { 15744202878575200397u, 161390617380431786u }, { 17812026976236499989u, 258224987808690858u },
+ 91 + + { 3181575136763469022u, 206579990246952687u }, { 13613306553636506187u, 165263992197562149u },
+ 92 + + { 10713244041592678929u, 264422387516099439u }, { 12259944048016053467u, 211537910012879551u },
+ 93 + + { 6118606423670932450u, 169230328010303641u }, { 2411072648389671274u, 270768524816485826u },
+ 94 + + { 16686253377679378312u, 216614819853188660u }, { 13349002702143502650u, 173291855882550928u },
+ 95 + + { 17669055508687693916u, 277266969412081485u }, { 14135244406950155133u, 221813575529665188u },
+ 96 + + { 240149081334393137u, 177450860423732151u }, { 11452284974360759988u, 283921376677971441u },
+ 97 + + { 5472479164746697667u, 227137101342377153u }, { 11756680961281178780u, 181709681073901722u },
+ 98 + + { 2026647139541122378u, 145367744859121378u }, { 18000030682233437097u, 232588391774594204u },
+ 99 + + { 18089373360528660001u, 186070713419675363u }, { 3403452244197197031u, 148856570735740291u },
+ 100 + + { 16513570034941246220u, 238170513177184465u }, { 13210856027952996976u, 190536410541747572u },
+ 101 + + { 3189987192878576934u, 152429128433398058u }, { 1414630693863812771u, 243886605493436893u },
+ 102 + + { 8510402184574870864u, 195109284394749514u }, { 10497670562401807014u, 156087427515799611u },
+ 103 + + { 9417575270359070576u, 249739884025279378u }, { 14912757845771077107u, 199791907220223502u },
+ 104 + + { 4551508647133041040u, 159833525776178802u }, { 10971762650154775986u, 255733641241886083u },
+ 105 + + { 16156107749607641435u, 204586912993508866u }, { 9235537384944202825u, 163669530394807093u },
+ 106 + + { 11087511001168814197u, 261871248631691349u }, { 12559357615676961681u, 209496998905353079u },
+ 107 + + { 13736834907283479668u, 167597599124282463u }, { 18289587036911657145u, 268156158598851941u },
+ 108 + + { 10942320814787415393u, 214524926879081553u }, { 16132554281313752961u, 171619941503265242u },
+ 109 + + { 11054691591134363444u, 274591906405224388u }, { 16222450902391311402u, 219673525124179510u },
+ 110 + + { 12977960721913049122u, 175738820099343608u }, { 17075388340318968271u, 281182112158949773u },
+ 111 + + { 2592264228029443648u, 224945689727159819u }, { 5763160197165465241u, 179956551781727855u },
+ 112 + + { 9221056315464744386u, 287930482850764568u }, { 14755542681855616155u, 230344386280611654u },
+ 113 + + { 15493782960226403247u, 184275509024489323u }, { 1326979923955391628u, 147420407219591459u },
+ 114 + + { 9501865507812447252u, 235872651551346334u }, { 11290841220991868125u, 188698121241077067u },
+ 115 + + { 1653975347309673853u, 150958496992861654u }, { 10025058185179298811u, 241533595188578646u },
+ 116 + + { 4330697733401528726u, 193226876150862917u }, { 14532604630946953951u, 154581500920690333u },
+ 117 + + { 1116074521063664381u, 247330401473104534u }, { 4582208431592841828u, 197864321178483627u },
+ 118 + + { 14733813189500004432u, 158291456942786901u }, { 16195403473716186445u, 253266331108459042u },
+ 119 + + { 5577625149489128510u, 202613064886767234u }, { 8151448934333213131u, 162090451909413787u },
+ 120 + + { 16731667109675051333u, 259344723055062059u }, { 17074682502481951390u, 207475778444049647u },
+ 121 + + { 6281048372501740465u, 165980622755239718u }, { 6360328581260874421u, 265568996408383549u },
+ 122 + + { 8777611679750609860u, 212455197126706839u }, { 10711438158542398211u, 169964157701365471u },
+ 123 + + { 9759603424184016492u, 271942652322184754u }, { 11497031554089123517u, 217554121857747803u },
+ 124 + + { 16576322872755119460u, 174043297486198242u }, { 11764721337440549842u, 278469275977917188u },
+ 125 + + { 16790474699436260520u, 222775420782333750u }, { 13432379759549008416u, 178220336625867000u },
+ 126 + + { 3045063541568861850u, 285152538601387201u }, { 17193446092222730773u, 228122030881109760u },
+ 127 + + { 13754756873778184618u, 182497624704887808u }, { 18382503128506368341u, 145998099763910246u },
+ 128 + + { 3586563302416817083u, 233596959622256395u }, { 2869250641933453667u, 186877567697805116u },
+ 129 + + { 17052795772514404226u, 149502054158244092u }, { 12527077977055405469u, 239203286653190548u },
+ 130 + + { 17400360011128145022u, 191362629322552438u }, { 2852241564676785048u, 153090103458041951u },
+ 131 + + { 15631632947708587046u, 244944165532867121u }, { 8815957543424959314u, 195955332426293697u },
+ 132 + + { 18120812478965698421u, 156764265941034957u }, { 14235904707377476180u, 250822825505655932u },
+ 133 + + { 4010026136418160298u, 200658260404524746u }, { 17965416168102169531u, 160526608323619796u },
+ 134 + + { 2919224165770098987u, 256842573317791675u }, { 2335379332616079190u, 205474058654233340u },
+ 135 + + { 1868303466092863352u, 164379246923386672u }, { 6678634360490491686u, 263006795077418675u },
+ 136 + + { 5342907488392393349u, 210405436061934940u }, { 4274325990713914679u, 168324348849547952u },
+ 137 + + { 10528270399884173809u, 269318958159276723u }, { 15801313949391159694u, 215455166527421378u },
+ 138 + + { 1573004715287196786u, 172364133221937103u }, { 17274202803427156150u, 275782613155099364u },
+ 139 + + { 17508711057483635243u, 220626090524079491u }, { 10317620031244997871u, 176500872419263593u },
+ 140 + + { 12818843235250086271u, 282401395870821749u }, { 13944423402941979340u, 225921116696657399u },
+ 141 + + { 14844887537095493795u, 180736893357325919u }, { 15565258844418305359u, 144589514685860735u },
+ 142 + + { 6457670077359736959u, 231343223497377177u }, { 16234182506113520537u, 185074578797901741u },
+ 143 + + { 9297997190148906106u, 148059663038321393u }, { 11187446689496339446u, 236895460861314229u },
+ 144 + + { 12639306166338981880u, 189516368689051383u }, { 17490142562555006151u, 151613094951241106u },
+ 145 + + { 2158786396894637579u, 242580951921985771u }, { 16484424376483351356u, 194064761537588616u },
+ 146 + + { 9498190686444770762u, 155251809230070893u }, { 11507756283569722895u, 248402894768113429u },
+ 147 + + { 12895553841597688639u, 198722315814490743u }, { 17695140702761971558u, 158977852651592594u },
+ 148 + + { 17244178680193423523u, 254364564242548151u }, { 10105994129412828495u, 203491651394038521u },
+ 149 + + { 4395446488788352473u, 162793321115230817u }, { 10722063196803274280u, 260469313784369307u },
+ 150 + + { 1198952927958798777u, 208375451027495446u }, { 15716557601334680315u, 166700360821996356u },
+ 151 + + { 17767794532651667857u, 266720577315194170u }, { 14214235626121334286u, 213376461852155336u },
+ 152 + + { 7682039686155157106u, 170701169481724269u }, { 1223217053622520399u, 273121871170758831u },
+ 153 + + { 15735968901865657612u, 218497496936607064u }, { 16278123936234436413u, 174797997549285651u },
+ 154 + + { 219556594781725998u, 279676796078857043u }, { 7554342905309201445u, 223741436863085634u },
+ 155 + + { 9732823138989271479u, 178993149490468507u }, { 815121763415193074u, 286389039184749612u },
+ 156 + + { 11720143854957885429u, 229111231347799689u }, { 13065463898708218666u, 183288985078239751u },
+ 157 + + { 6763022304224664610u, 146631188062591801u }, { 3442138057275642729u, 234609900900146882u },
+ 158 + + { 13821756890046245153u, 187687920720117505u }, { 11057405512036996122u, 150150336576094004u },
+ 159 + + { 6623802375033462826u, 240240538521750407u }, { 16367088344252501231u, 192192430817400325u },
+ 160 + + { 13093670675402000985u, 153753944653920260u }, { 2503129006933649959u, 246006311446272417u },
+ 161 + + { 13070549649772650937u, 196805049157017933u }, { 17835137349301941396u, 157444039325614346u },
+ 162 + + { 2710778055689733971u, 251910462920982955u }, { 2168622444551787177u, 201528370336786364u },
+ 163 + + { 5424246770383340065u, 161222696269429091u }, { 1300097203129523457u, 257956314031086546u },
+ 164 + + { 15797473021471260058u, 206365051224869236u }, { 8948629602435097724u, 165092040979895389u },
+ 165 + + { 3249760919670425388u, 264147265567832623u }, { 9978506365220160957u, 211317812454266098u },
+ 166 + + { 15361502721659949412u, 169054249963412878u }, { 2442311466204457120u, 270486799941460606u },
+ 167 + + { 16711244431931206989u, 216389439953168484u }, { 17058344360286875914u, 173111551962534787u },
+ 168 + + { 12535955717491360170u, 276978483140055660u }, { 10028764573993088136u, 221582786512044528u },
+ 169 + + { 15401709288678291155u, 177266229209635622u }, { 9885339602917624555u, 283625966735416996u },
+ 170 + + { 4218922867592189321u, 226900773388333597u }, { 14443184738299482427u, 181520618710666877u },
+ 171 + + { 4175850161155765295u, 145216494968533502u }, { 10370709072591134795u, 232346391949653603u },
+ 172 + + { 15675264887556728482u, 185877113559722882u }, { 5161514280561562140u, 148701690847778306u },
+ 173 + + { 879725219414678777u, 237922705356445290u }, { 703780175531743021u, 190338164285156232u },
+ 174 + + { 11631070584651125387u, 152270531428124985u }, { 162968861732249003u, 243632850284999977u },
+ 175 + + { 11198421533611530172u, 194906280227999981u }, { 5269388412147313814u, 155925024182399985u },
+ 176 + + { 8431021459435702103u, 249480038691839976u }, { 3055468352806651359u, 199584030953471981u },
+ 177 + + { 17201769941212962380u, 159667224762777584u }, { 16454785461715008838u, 255467559620444135u },
+ 178 + + { 13163828369372007071u, 204374047696355308u }, { 17909760324981426303u, 163499238157084246u },
+ 179 + + { 2830174816776909822u, 261598781051334795u }, { 2264139853421527858u, 209279024841067836u },
+ 180 + + { 16568707141704863579u, 167423219872854268u }, { 4373838538276319787u, 267877151796566830u },
+ 181 + + { 3499070830621055830u, 214301721437253464u }, { 6488605479238754987u, 171441377149802771u },
+ 182 + + { 3003071137298187333u, 274306203439684434u }, { 6091805724580460189u, 219444962751747547u },
+ 183 + + { 15941491023890099121u, 175555970201398037u }, { 10748990379256517301u, 280889552322236860u },
+ 184 + + { 8599192303405213841u, 224711641857789488u }, { 14258051472207991719u, 179769313486231590u }};
+ 185 + +1004 return arr;
+ 186 + + }
+ 187 + +
+ 188 + + inline
+ 189 + + std::uint64_t const
+ 190 + +1112 (&DOUBLE_POW5_SPLIT() noexcept)[326][2]
+ 191 + + {
+ 192 + + static constexpr std::uint64_t arr[326][2] = {
+ 193 + + { 0u, 72057594037927936u }, { 0u, 90071992547409920u },
+ 194 + + { 0u, 112589990684262400u }, { 0u, 140737488355328000u },
+ 195 + + { 0u, 87960930222080000u }, { 0u, 109951162777600000u },
+ 196 + + { 0u, 137438953472000000u }, { 0u, 85899345920000000u },
+ 197 + + { 0u, 107374182400000000u }, { 0u, 134217728000000000u },
+ 198 + + { 0u, 83886080000000000u }, { 0u, 104857600000000000u },
+ 199 + + { 0u, 131072000000000000u }, { 0u, 81920000000000000u },
+ 200 + + { 0u, 102400000000000000u }, { 0u, 128000000000000000u },
+ 201 + + { 0u, 80000000000000000u }, { 0u, 100000000000000000u },
+ 202 + + { 0u, 125000000000000000u }, { 0u, 78125000000000000u },
+ 203 + + { 0u, 97656250000000000u }, { 0u, 122070312500000000u },
+ 204 + + { 0u, 76293945312500000u }, { 0u, 95367431640625000u },
+ 205 + + { 0u, 119209289550781250u }, { 4611686018427387904u, 74505805969238281u },
+ 206 + + { 10376293541461622784u, 93132257461547851u }, { 8358680908399640576u, 116415321826934814u },
+ 207 + + { 612489549322387456u, 72759576141834259u }, { 14600669991935148032u, 90949470177292823u },
+ 208 + + { 13639151471491547136u, 113686837721616029u }, { 3213881284082270208u, 142108547152020037u },
+ 209 + + { 4314518811765112832u, 88817841970012523u }, { 781462496279003136u, 111022302462515654u },
+ 210 + + { 10200200157203529728u, 138777878078144567u }, { 13292654125893287936u, 86736173798840354u },
+ 211 + + { 7392445620511834112u, 108420217248550443u }, { 4628871007212404736u, 135525271560688054u },
+ 212 + + { 16728102434789916672u, 84703294725430033u }, { 7075069988205232128u, 105879118406787542u },
+ 213 + + { 18067209522111315968u, 132348898008484427u }, { 8986162942105878528u, 82718061255302767u },
+ 214 + + { 6621017659204960256u, 103397576569128459u }, { 3664586055578812416u, 129246970711410574u },
+ 215 + + { 16125424340018921472u, 80779356694631608u }, { 1710036351314100224u, 100974195868289511u },
+ 216 + + { 15972603494424788992u, 126217744835361888u }, { 9982877184015493120u, 78886090522101180u },
+ 217 + + { 12478596480019366400u, 98607613152626475u }, { 10986559581596820096u, 123259516440783094u },
+ 218 + + { 2254913720070624656u, 77037197775489434u }, { 12042014186943056628u, 96296497219361792u },
+ 219 + + { 15052517733678820785u, 120370621524202240u }, { 9407823583549262990u, 75231638452626400u },
+ 220 + + { 11759779479436578738u, 94039548065783000u }, { 14699724349295723422u, 117549435082228750u },
+ 221 + + { 4575641699882439235u, 73468396926392969u }, { 10331238143280436948u, 91835496157991211u },
+ 222 + + { 8302361660673158281u, 114794370197489014u }, { 1154580038986672043u, 143492962746861268u },
+ 223 + + { 9944984561221445835u, 89683101716788292u }, { 12431230701526807293u, 112103877145985365u },
+ 224 + + { 1703980321626345405u, 140129846432481707u }, { 17205888765512323542u, 87581154020301066u },
+ 225 + + { 12283988920035628619u, 109476442525376333u }, { 1519928094762372062u, 136845553156720417u },
+ 226 + + { 12479170105294952299u, 85528470722950260u }, { 15598962631618690374u, 106910588403687825u },
+ 227 + + { 5663645234241199255u, 133638235504609782u }, { 17374836326682913246u, 83523897190381113u },
+ 228 + + { 7883487353071477846u, 104404871487976392u }, { 9854359191339347308u, 130506089359970490u },
+ 229 + + { 10770660513014479971u, 81566305849981556u }, { 13463325641268099964u, 101957882312476945u },
+ 230 + + { 2994098996302961243u, 127447352890596182u }, { 15706369927971514489u, 79654595556622613u },
+ 231 + + { 5797904354682229399u, 99568244445778267u }, { 2635694424925398845u, 124460305557222834u },
+ 232 + + { 6258995034005762182u, 77787690973264271u }, { 3212057774079814824u, 97234613716580339u },
+ 233 + + { 17850130272881932242u, 121543267145725423u }, { 18073860448192289507u, 75964541966078389u },
+ 234 + + { 8757267504958198172u, 94955677457597987u }, { 6334898362770359811u, 118694596821997484u },
+ 235 + + { 13182683513586250689u, 74184123013748427u }, { 11866668373555425458u, 92730153767185534u },
+ 236 + + { 5609963430089506015u, 115912692208981918u }, { 17341285199088104971u, 72445432630613698u },
+ 237 + + { 12453234462005355406u, 90556790788267123u }, { 10954857059079306353u, 113195988485333904u },
+ 238 + + { 13693571323849132942u, 141494985606667380u }, { 17781854114260483896u, 88434366004167112u },
+ 239 + + { 3780573569116053255u, 110542957505208891u }, { 114030942967678664u, 138178696881511114u },
+ 240 + + { 4682955357782187069u, 86361685550944446u }, { 15077066234082509644u, 107952106938680557u },
+ 241 + + { 5011274737320973344u, 134940133673350697u }, { 14661261756894078100u, 84337583545844185u },
+ 242 + + { 4491519140835433913u, 105421979432305232u }, { 5614398926044292391u, 131777474290381540u },
+ 243 + + { 12732371365632458552u, 82360921431488462u }, { 6692092170185797382u, 102951151789360578u },
+ 244 + + { 17588487249587022536u, 128688939736700722u }, { 15604490549419276989u, 80430587335437951u },
+ 245 + + { 14893927168346708332u, 100538234169297439u }, { 14005722942005997511u, 125672792711621799u },
+ 246 + + { 15671105866394830300u, 78545495444763624u }, { 1142138259283986260u, 98181869305954531u },
+ 247 + + { 15262730879387146537u, 122727336632443163u }, { 7233363790403272633u, 76704585395276977u },
+ 248 + + { 13653390756431478696u, 95880731744096221u }, { 3231680390257184658u, 119850914680120277u },
+ 249 + + { 4325643253124434363u, 74906821675075173u }, { 10018740084832930858u, 93633527093843966u },
+ 250 + + { 3300053069186387764u, 117041908867304958u }, { 15897591223523656064u, 73151193042065598u },
+ 251 + + { 10648616992549794273u, 91438991302581998u }, { 4087399203832467033u, 114298739128227498u },
+ 252 + + { 14332621041645359599u, 142873423910284372u }, { 18181260187883125557u, 89295889943927732u },
+ 253 + + { 4279831161144355331u, 111619862429909666u }, { 14573160988285219972u, 139524828037387082u },
+ 254 + + { 13719911636105650386u, 87203017523366926u }, { 7926517508277287175u, 109003771904208658u },
+ 255 + + { 684774848491833161u, 136254714880260823u }, { 7345513307948477581u, 85159196800163014u },
+ 256 + + { 18405263671790372785u, 106448996000203767u }, { 18394893571310578077u, 133061245000254709u },
+ 257 + + { 13802651491282805250u, 83163278125159193u }, { 3418256308821342851u, 103954097656448992u },
+ 258 + + { 4272820386026678563u, 129942622070561240u }, { 2670512741266674102u, 81214138794100775u },
+ 259 + + { 17173198981865506339u, 101517673492625968u }, { 3019754653622331308u, 126897091865782461u },
+ 260 + + { 4193189667727651020u, 79310682416114038u }, { 14464859121514339583u, 99138353020142547u },
+ 261 + + { 13469387883465536574u, 123922941275178184u }, { 8418367427165960359u, 77451838296986365u },
+ 262 + + { 15134645302384838353u, 96814797871232956u }, { 471562554271496325u, 121018497339041196u },
+ 263 + + { 9518098633274461011u, 75636560836900747u }, { 7285937273165688360u, 94545701046125934u },
+ 264 + + { 18330793628311886258u, 118182126307657417u }, { 4539216990053847055u, 73863828942285886u },
+ 265 + + { 14897393274422084627u, 92329786177857357u }, { 4786683537745442072u, 115412232722321697u },
+ 266 + + { 14520892257159371055u, 72132645451451060u }, { 18151115321449213818u, 90165806814313825u },
+ 267 + + { 8853836096529353561u, 112707258517892282u }, { 1843923083806916143u, 140884073147365353u },
+ 268 + + { 12681666973447792349u, 88052545717103345u }, { 2017025661527576725u, 110065682146379182u },
+ 269 + + { 11744654113764246714u, 137582102682973977u }, { 422879793461572340u, 85988814176858736u },
+ 270 + + { 528599741826965425u, 107486017721073420u }, { 660749677283706782u, 134357522151341775u },
+ 271 + + { 7330497575943398595u, 83973451344588609u }, { 13774807988356636147u, 104966814180735761u },
+ 272 + + { 3383451930163631472u, 131208517725919702u }, { 15949715511634433382u, 82005323578699813u },
+ 273 + + { 6102086334260878016u, 102506654473374767u }, { 3015921899398709616u, 128133318091718459u },
+ 274 + + { 18025852251620051174u, 80083323807324036u }, { 4085571240815512351u, 100104154759155046u },
+ 275 + + { 14330336087874166247u, 125130193448943807u }, { 15873989082562435760u, 78206370905589879u },
+ 276 + + { 15230800334775656796u, 97757963631987349u }, { 5203442363187407284u, 122197454539984187u },
+ 277 + + { 946308467778435600u, 76373409087490117u }, { 5794571603150432404u, 95466761359362646u },
+ 278 + + { 16466586540792816313u, 119333451699203307u }, { 7985773578781816244u, 74583407312002067u },
+ 279 + + { 5370530955049882401u, 93229259140002584u }, { 6713163693812353001u, 116536573925003230u },
+ 280 + + { 18030785363914884337u, 72835358703127018u }, { 13315109668038829614u, 91044198378908773u },
+ 281 + + { 2808829029766373305u, 113805247973635967u }, { 17346094342490130344u, 142256559967044958u },
+ 282 + + { 6229622945628943561u, 88910349979403099u }, { 3175342663608791547u, 111137937474253874u },
+ 283 + + { 13192550366365765242u, 138922421842817342u }, { 3633657960551215372u, 86826513651760839u },
+ 284 + + { 18377130505971182927u, 108533142064701048u }, { 4524669058754427043u, 135666427580876311u },
+ 285 + + { 9745447189362598758u, 84791517238047694u }, { 2958436949848472639u, 105989396547559618u },
+ 286 + + { 12921418224165366607u, 132486745684449522u }, { 12687572408530742033u, 82804216052780951u },
+ 287 + + { 11247779492236039638u, 103505270065976189u }, { 224666310012885835u, 129381587582470237u },
+ 288 + + { 2446259452971747599u, 80863492239043898u }, { 12281196353069460307u, 101079365298804872u },
+ 289 + + { 15351495441336825384u, 126349206623506090u }, { 14206370669262903769u, 78968254139691306u },
+ 290 + + { 8534591299723853903u, 98710317674614133u }, { 15279925143082205283u, 123387897093267666u },
+ 291 + + { 14161639232853766206u, 77117435683292291u }, { 13090363022639819853u, 96396794604115364u },
+ 292 + + { 16362953778299774816u, 120495993255144205u }, { 12532689120651053212u, 75309995784465128u },
+ 293 + + { 15665861400813816515u, 94137494730581410u }, { 10358954714162494836u, 117671868413226763u },
+ 294 + + { 4168503687137865320u, 73544917758266727u }, { 598943590494943747u, 91931147197833409u },
+ 295 + + { 5360365506546067587u, 114913933997291761u }, { 11312142901609972388u, 143642417496614701u },
+ 296 + + { 9375932322719926695u, 89776510935384188u }, { 11719915403399908368u, 112220638669230235u },
+ 297 + + { 10038208235822497557u, 140275798336537794u }, { 10885566165816448877u, 87672373960336121u },
+ 298 + + { 18218643725697949000u, 109590467450420151u }, { 18161618638695048346u, 136988084313025189u },
+ 299 + + { 13656854658398099168u, 85617552695640743u }, { 12459382304570236056u, 107021940869550929u },
+ 300 + + { 1739169825430631358u, 133777426086938662u }, { 14922039196176308311u, 83610891304336663u },
+ 301 + + { 14040862976792997485u, 104513614130420829u }, { 3716020665709083144u, 130642017663026037u },
+ 302 + + { 4628355925281870917u, 81651261039391273u }, { 10397130925029726550u, 102064076299239091u },
+ 303 + + { 8384727637859770284u, 127580095374048864u }, { 5240454773662356427u, 79737559608780540u },
+ 304 + + { 6550568467077945534u, 99671949510975675u }, { 3576524565420044014u, 124589936888719594u },
+ 305 + + { 6847013871814915412u, 77868710555449746u }, { 17782139376623420074u, 97335888194312182u },
+ 306 + + { 13004302183924499284u, 121669860242890228u }, { 17351060901807587860u, 76043662651806392u },
+ 307 + + { 3242082053549933210u, 95054578314757991u }, { 17887660622219580224u, 118818222893447488u },
+ 308 + + { 11179787888887237640u, 74261389308404680u }, { 13974734861109047050u, 92826736635505850u },
+ 309 + + { 8245046539531533005u, 116033420794382313u }, { 16682369133275677888u, 72520887996488945u },
+ 310 + + { 7017903361312433648u, 90651109995611182u }, { 17995751238495317868u, 113313887494513977u },
+ 311 + + { 8659630992836983623u, 141642359368142472u }, { 5412269370523114764u, 88526474605089045u },
+ 312 + + { 11377022731581281359u, 110658093256361306u }, { 4997906377621825891u, 138322616570451633u },
+ 313 + + { 14652906532082110942u, 86451635356532270u }, { 9092761128247862869u, 108064544195665338u },
+ 314 + + { 2142579373455052779u, 135080680244581673u }, { 12868327154477877747u, 84425425152863545u },
+ 315 + + { 2250350887815183471u, 105531781441079432u }, { 2812938609768979339u, 131914726801349290u },
+ 316 + + { 6369772649532999991u, 82446704250843306u }, { 17185587848771025797u, 103058380313554132u },
+ 317 + + { 3035240737254230630u, 128822975391942666u }, { 6508711479211282048u, 80514359619964166u },
+ 318 + + { 17359261385868878368u, 100642949524955207u }, { 17087390713908710056u, 125803686906194009u },
+ 319 + + { 3762090168551861929u, 78627304316371256u }, { 4702612710689827411u, 98284130395464070u },
+ 320 + + { 15101637925217060072u, 122855162994330087u }, { 16356052730901744401u, 76784476871456304u },
+ 321 + + { 1998321839917628885u, 95980596089320381u }, { 7109588318324424010u, 119975745111650476u },
+ 322 + + { 13666864735807540814u, 74984840694781547u }, { 12471894901332038114u, 93731050868476934u },
+ 323 + + { 6366496589810271835u, 117163813585596168u }, { 3979060368631419896u, 73227383490997605u },
+ 324 + + { 9585511479216662775u, 91534229363747006u }, { 2758517312166052660u, 114417786704683758u },
+ 325 + + { 12671518677062341634u, 143022233380854697u }, { 1002170145522881665u, 89388895863034186u },
+ 326 + + { 10476084718758377889u, 111736119828792732u }, { 13095105898447972362u, 139670149785990915u },
+ 327 + + { 5878598177316288774u, 87293843616244322u }, { 16571619758500136775u, 109117304520305402u },
+ 328 + + { 11491152661270395161u, 136396630650381753u }, { 264441385652915120u, 85247894156488596u },
+ 329 + + { 330551732066143900u, 106559867695610745u }, { 5024875683510067779u, 133199834619513431u },
+ 330 + + { 10058076329834874218u, 83249896637195894u }, { 3349223375438816964u, 104062370796494868u },
+ 331 + + { 4186529219298521205u, 130077963495618585u }, { 14145795808130045513u, 81298727184761615u },
+ 332 + + { 13070558741735168987u, 101623408980952019u }, { 11726512408741573330u, 127029261226190024u },
+ 333 + + { 7329070255463483331u, 79393288266368765u }, { 13773023837756742068u, 99241610332960956u },
+ 334 + + { 17216279797195927585u, 124052012916201195u }, { 8454331864033760789u, 77532508072625747u },
+ 335 + + { 5956228811614813082u, 96915635090782184u }, { 7445286014518516353u, 121144543863477730u },
+ 336 + + { 9264989777501460624u, 75715339914673581u }, { 16192923240304213684u, 94644174893341976u },
+ 337 + + { 1794409976670715490u, 118305218616677471u }, { 8039035263060279037u, 73940761635423419u },
+ 338 + + { 5437108060397960892u, 92425952044279274u }, { 16019757112352226923u, 115532440055349092u },
+ 339 + + { 788976158365366019u, 72207775034593183u }, { 14821278253238871236u, 90259718793241478u },
+ 340 + + { 9303225779693813237u, 112824648491551848u }, { 11629032224617266546u, 141030810614439810u },
+ 341 + + { 11879831158813179495u, 88144256634024881u }, { 1014730893234310657u, 110180320792531102u },
+ 342 + + { 10491785653397664129u, 137725400990663877u }, { 8863209042587234033u, 86078375619164923u },
+ 343 + + { 6467325284806654637u, 107597969523956154u }, { 17307528642863094104u, 134497461904945192u },
+ 344 + + { 10817205401789433815u, 84060913690590745u }, { 18133192770664180173u, 105076142113238431u },
+ 345 + + { 18054804944902837312u, 131345177641548039u }, { 18201782118205355176u, 82090736025967524u },
+ 346 + + { 4305483574047142354u, 102613420032459406u }, { 14605226504413703751u, 128266775040574257u },
+ 347 + + { 2210737537617482988u, 80166734400358911u }, { 16598479977304017447u, 100208418000448638u },
+ 348 + + { 11524727934775246001u, 125260522500560798u }, { 2591268940807140847u, 78287826562850499u },
+ 349 + + { 17074144231291089770u, 97859783203563123u }, { 16730994270686474309u, 122324729004453904u },
+ 350 + + { 10456871419179046443u, 76452955627783690u }, { 3847717237119032246u, 95566194534729613u },
+ 351 + + { 9421332564826178211u, 119457743168412016u }, { 5888332853016361382u, 74661089480257510u },
+ 352 + + { 16583788103125227536u, 93326361850321887u }, { 16118049110479146516u, 116657952312902359u },
+ 353 + + { 16991309721690548428u, 72911220195563974u }, { 12015765115258409727u, 91139025244454968u },
+ 354 + + { 15019706394073012159u, 113923781555568710u }, { 9551260955736489391u, 142404726944460888u },
+ 355 + + { 5969538097335305869u, 89002954340288055u }, { 2850236603241744433u, 111253692925360069u }};
+ 356 + +1112 return arr;
+ 357 + + }
+ 358 + +
+ 359 + + } // ryu
+ 360 + +
+ 361 + + } // detail
+ 362 + + } // namespace json
+ 363 + + } // namespace boost
+ 364 + +
+ 365 + + #endif
+ 366 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.d2s_intrinsics.hpp.83ef835088fb80240623093e946e5ee8.html b/json/gcovr/index.d2s_intrinsics.hpp.83ef835088fb80240623093e946e5ee8.html new file mode 100644 index 00000000..17a04da7 --- /dev/null +++ b/json/gcovr/index.d2s_intrinsics.hpp.83ef835088fb80240623093e946e5ee8.html @@ -0,0 +1,3958 @@ + + + + + + detail/ryu/detail/d2s_intrinsics.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/ryu/detail/d2s_intrinsics.hpp

+
+ + 100.0% Lines (28/28) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/ryu/detail/d2s_intrinsics.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2018 Ulf Adams
+ 2 + + //
+ 3 + + // The contents of this file may be used under the terms of the Apache License,
+ 4 + + // Version 2.0.
+ 5 + + //
+ 6 + + // (See accompanying file LICENSE-Apache or copy at
+ 7 + + // http://www.apache.org/licenses/LICENSE-2.0)
+ 8 + + //
+ 9 + + // Alternatively, the contents of this file may be used under the terms of
+ 10 + + // the Boost Software License, Version 1.0.
+ 11 + + // (See accompanying file LICENSE-Boost or copy at
+ 12 + + // https://www.boost.org/LICENSE_1_0.txt)
+ 13 + + //
+ 14 + + // Unless required by applicable law or agreed to in writing, this software
+ 15 + + // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ 16 + + // KIND, either express or implied.
+ 17 + +
+ 18 + + /*
+ 19 + + This is a derivative work
+ 20 + + */
+ 21 + +
+ 22 + + #ifndef BOOST_JSON_DETAIL_RYU_DETAIL_D2S_INTRINSICS_HPP
+ 23 + + #define BOOST_JSON_DETAIL_RYU_DETAIL_D2S_INTRINSICS_HPP
+ 24 + +
+ 25 + + #include <boost/json/detail/config.hpp>
+ 26 + +
+ 27 + + // This sets BOOST_JSON_RYU_32_BIT_PLATFORM as a side effect if applicable.
+ 28 + + #include <boost/json/detail/ryu/detail/common.hpp>
+ 29 + +
+ 30 + + #if defined(BOOST_JSON_RYU_HAS_64_BIT_INTRINSICS)
+ 31 + + #include <intrin.h>
+ 32 + + #endif
+ 33 + +
+ 34 + + namespace boost {
+ 35 + + namespace json {
+ 36 + + namespace detail {
+ 37 + +
+ 38 + + namespace ryu {
+ 39 + + namespace detail {
+ 40 + +
+ 41 + + #if defined(BOOST_JSON_RYU_HAS_64_BIT_INTRINSICS)
+ 42 + +
+ 43 + + inline uint64_t umul128(const uint64_t a, const uint64_t b, uint64_t* const productHi) {
+ 44 + + return _umul128(a, b, productHi);
+ 45 + + }
+ 46 + +
+ 47 + + inline uint64_t shiftright128(const uint64_t lo, const uint64_t hi, const uint32_t dist) {
+ 48 + + // For the __shiftright128 intrinsic, the shift value is always
+ 49 + + // modulo 64.
+ 50 + + // In the current implementation of the double-precision version
+ 51 + + // of Ryu, the shift value is always < 64. (In the case
+ 52 + + // RYU_OPTIMIZE_SIZE == 0, the shift value is in the range [49, 58].
+ 53 + + // Otherwise in the range [2, 59].)
+ 54 + + // Check this here in case a future change requires larger shift
+ 55 + + // values. In this case this function needs to be adjusted.
+ 56 + + BOOST_ASSERT(dist < 64);
+ 57 + + return __shiftright128(lo, hi, (unsigned char) dist);
+ 58 + + }
+ 59 + +
+ 60 + + #else // defined(HAS_64_BIT_INTRINSICS)
+ 61 + +
+ 62 + + inline uint64_t umul128(const uint64_t a, const uint64_t b, uint64_t* const productHi) {
+ 63 + + // The casts here help MSVC to avoid calls to the __allmul library function.
+ 64 + + const uint32_t aLo = (uint32_t)a;
+ 65 + + const uint32_t aHi = (uint32_t)(a >> 32);
+ 66 + + const uint32_t bLo = (uint32_t)b;
+ 67 + + const uint32_t bHi = (uint32_t)(b >> 32);
+ 68 + +
+ 69 + + const uint64_t b00 = (uint64_t)aLo * bLo;
+ 70 + + const uint64_t b01 = (uint64_t)aLo * bHi;
+ 71 + + const uint64_t b10 = (uint64_t)aHi * bLo;
+ 72 + + const uint64_t b11 = (uint64_t)aHi * bHi;
+ 73 + +
+ 74 + + const uint32_t b00Lo = (uint32_t)b00;
+ 75 + + const uint32_t b00Hi = (uint32_t)(b00 >> 32);
+ 76 + +
+ 77 + + const uint64_t mid1 = b10 + b00Hi;
+ 78 + + const uint32_t mid1Lo = (uint32_t)(mid1);
+ 79 + + const uint32_t mid1Hi = (uint32_t)(mid1 >> 32);
+ 80 + +
+ 81 + + const uint64_t mid2 = b01 + mid1Lo;
+ 82 + + const uint32_t mid2Lo = (uint32_t)(mid2);
+ 83 + + const uint32_t mid2Hi = (uint32_t)(mid2 >> 32);
+ 84 + +
+ 85 + + const uint64_t pHi = b11 + mid1Hi + mid2Hi;
+ 86 + + const uint64_t pLo = ((uint64_t)mid2Lo << 32) | b00Lo;
+ 87 + +
+ 88 + + *productHi = pHi;
+ 89 + + return pLo;
+ 90 + + }
+ 91 + +
+ 92 + + inline uint64_t shiftright128(const uint64_t lo, const uint64_t hi, const uint32_t dist) {
+ 93 + + // We don't need to handle the case dist >= 64 here (see above).
+ 94 + + BOOST_ASSERT(dist < 64);
+ 95 + + #if defined(RYU_OPTIMIZE_SIZE) || !defined(RYU_32_BIT_PLATFORM)
+ 96 + + BOOST_ASSERT(dist > 0);
+ 97 + + return (hi << (64 - dist)) | (lo >> dist);
+ 98 + + #else
+ 99 + + // Avoid a 64-bit shift by taking advantage of the range of shift values.
+ 100 + + BOOST_ASSERT(dist >= 32);
+ 101 + + return (hi << (64 - dist)) | ((uint32_t)(lo >> 32) >> (dist - 32));
+ 102 + + #endif
+ 103 + + }
+ 104 + +
+ 105 + + #endif // defined(HAS_64_BIT_INTRINSICS)
+ 106 + +
+ 107 + + #ifdef RYU_32_BIT_PLATFORM
+ 108 + +
+ 109 + + // Returns the high 64 bits of the 128-bit product of a and b.
+ 110 + + inline uint64_t umulh(const uint64_t a, const uint64_t b) {
+ 111 + + // Reuse the umul128 implementation.
+ 112 + + // Optimizers will likely eliminate the instructions used to compute the
+ 113 + + // low part of the product.
+ 114 + + uint64_t hi;
+ 115 + + umul128(a, b, &hi);
+ 116 + + return hi;
+ 117 + + }
+ 118 + +
+ 119 + + // On 32-bit platforms, compilers typically generate calls to library
+ 120 + + // functions for 64-bit divisions, even if the divisor is a constant.
+ 121 + + //
+ 122 + + // E.g.:
+ 123 + + // https://bugs.llvm.org/show_bug.cgi?id=37932
+ 124 + + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17958
+ 125 + + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37443
+ 126 + + //
+ 127 + + // The functions here perform division-by-constant using multiplications
+ 128 + + // in the same way as 64-bit compilers would do.
+ 129 + + //
+ 130 + + // NB:
+ 131 + + // The multipliers and shift values are the ones generated by clang x64
+ 132 + + // for expressions like x/5, x/10, etc.
+ 133 + +
+ 134 + + inline uint64_t div5(const uint64_t x) {
+ 135 + + return umulh(x, 0xCCCCCCCCCCCCCCCDu) >> 2;
+ 136 + + }
+ 137 + +
+ 138 + + inline uint64_t div10(const uint64_t x) {
+ 139 + + return umulh(x, 0xCCCCCCCCCCCCCCCDu) >> 3;
+ 140 + + }
+ 141 + +
+ 142 + + inline uint64_t div100(const uint64_t x) {
+ 143 + + return umulh(x >> 2, 0x28F5C28F5C28F5C3u) >> 2;
+ 144 + + }
+ 145 + +
+ 146 + + inline uint64_t div1e8(const uint64_t x) {
+ 147 + + return umulh(x, 0xABCC77118461CEFDu) >> 26;
+ 148 + + }
+ 149 + +
+ 150 + + inline uint64_t div1e9(const uint64_t x) {
+ 151 + + return umulh(x >> 9, 0x44B82FA09B5A53u) >> 11;
+ 152 + + }
+ 153 + +
+ 154 + + inline uint32_t mod1e9(const uint64_t x) {
+ 155 + + // Avoid 64-bit math as much as possible.
+ 156 + + // Returning (uint32_t) (x - 1000000000 * div1e9(x)) would
+ 157 + + // perform 32x64-bit multiplication and 64-bit subtraction.
+ 158 + + // x and 1000000000 * div1e9(x) are guaranteed to differ by
+ 159 + + // less than 10^9, so their highest 32 bits must be identical,
+ 160 + + // so we can truncate both sides to uint32_t before subtracting.
+ 161 + + // We can also simplify (uint32_t) (1000000000 * div1e9(x)).
+ 162 + + // We can truncate before multiplying instead of after, as multiplying
+ 163 + + // the highest 32 bits of div1e9(x) can't affect the lowest 32 bits.
+ 164 + + return ((uint32_t) x) - 1000000000 * ((uint32_t) div1e9(x));
+ 165 + + }
+ 166 + +
+ 167 + + #else // RYU_32_BIT_PLATFORM
+ 168 + +
+ 169 + +1974 inline uint64_t div5(const uint64_t x) {
+ 170 + +1974 return x / 5;
+ 171 + + }
+ 172 + +
+ 173 + +12198 inline uint64_t div10(const uint64_t x) {
+ 174 + +12198 return x / 10;
+ 175 + + }
+ 176 + +
+ 177 + +497 inline uint64_t div100(const uint64_t x) {
+ 178 + +497 return x / 100;
+ 179 + + }
+ 180 + +
+ 181 + +59 inline uint64_t div1e8(const uint64_t x) {
+ 182 + +59 return x / 100000000;
+ 183 + + }
+ 184 + +
+ 185 + +17 inline uint64_t div1e9(const uint64_t x) {
+ 186 + +17 return x / 1000000000;
+ 187 + + }
+ 188 + +
+ 189 + +17 inline uint32_t mod1e9(const uint64_t x) {
+ 190 + +17 return (uint32_t) (x - 1000000000 * div1e9(x));
+ 191 + + }
+ 192 + +
+ 193 + + #endif // RYU_32_BIT_PLATFORM
+ 194 + +
+ 195 + +114 inline uint32_t pow5Factor(uint64_t value) {
+ 196 + +114 uint32_t count = 0;
+ 197 + + for (;;) {
+ 198 + +1860 BOOST_ASSERT(value != 0);
+ 199 + +1860 const uint64_t q = div5(value);
+ 200 + +1860 const uint32_t r = ((uint32_t) value) - 5 * ((uint32_t) q);
+ 201 + +1860 if (r != 0) {
+ 202 + +114 break;
+ 203 + + }
+ 204 + +1746 value = q;
+ 205 + +1746 ++count;
+ 206 + +1746 }
+ 207 + +114 return count;
+ 208 + + }
+ 209 + +
+ 210 + + // Returns true if value is divisible by 5^p.
+ 211 + +114 inline bool multipleOfPowerOf5(const uint64_t value, const uint32_t p) {
+ 212 + + // I tried a case distinction on p, but there was no performance difference.
+ 213 + +114 return pow5Factor(value) >= p;
+ 214 + + }
+ 215 + +
+ 216 + + // Returns true if value is divisible by 2^p.
+ 217 + +96 inline bool multipleOfPowerOf2(const uint64_t value, const uint32_t p) {
+ 218 + +96 BOOST_ASSERT(value != 0);
+ 219 + + // return __builtin_ctzll(value) >= p;
+ 220 + +96 return (value & ((1ull << p) - 1)) == 0;
+ 221 + + }
+ 222 + +
+ 223 + +
+ 224 + + } // detail
+ 225 + + } // ryu
+ 226 + +
+ 227 + + } // detail
+ 228 + + } // namespace json
+ 229 + + } // namespace boost
+ 230 + +
+ 231 + + #endif
+ 232 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.decimal_to_binary.hpp.aa9ca29d0a37b3474618fa96dc2b5923.html b/json/gcovr/index.decimal_to_binary.hpp.aa9ca29d0a37b3474618fa96dc2b5923.html new file mode 100644 index 00000000..fbfd638a --- /dev/null +++ b/json/gcovr/index.decimal_to_binary.hpp.aa9ca29d0a37b3474618fa96dc2b5923.html @@ -0,0 +1,3678 @@ + + + + + + detail/charconv/detail/fast_float/decimal_to_binary.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/fast_float/decimal_to_binary.hpp

+
+ + 94.7% Lines (54/57) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/fast_float/decimal_to_binary.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2020-2023 Daniel Lemire
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + + //
+ 6 + + // Derivative of: https://github.com/fastfloat/fast_float
+ 7 + +
+ 8 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_DECIMAL_TO_BINARY_HPP
+ 9 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_DECIMAL_TO_BINARY_HPP
+ 10 + +
+ 11 + + #include <boost/json/detail/charconv/detail/fast_float/float_common.hpp>
+ 12 + + #include <boost/json/detail/charconv/detail/fast_float/fast_table.hpp>
+ 13 + + #include <cfloat>
+ 14 + + #include <cinttypes>
+ 15 + + #include <cmath>
+ 16 + + #include <cstdint>
+ 17 + + #include <cstdlib>
+ 18 + + #include <cstring>
+ 19 + +
+ 20 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float {
+ 21 + +
+ 22 + + // This will compute or rather approximate w * 5**q and return a pair of 64-bit words approximating
+ 23 + + // the result, with the "high" part corresponding to the most significant bits and the
+ 24 + + // low part corresponding to the least significant bits.
+ 25 + + //
+ 26 + + template <int bit_precision>
+ 27 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 28 + + value128 compute_product_approximation(int64_t q, uint64_t w) {
+ 29 + +2005879 const int index = 2 * int(q - powers::smallest_power_of_five);
+ 30 + + // For small values of q, e.g., q in [0,27], the answer is always exact because
+ 31 + + // The line value128 firstproduct = full_multiplication(w, power_of_five_128[index]);
+ 32 + + // gives the exact answer.
+ 33 + +4011758 value128 firstproduct = full_multiplication(w, powers::power_of_five_128[index]);
+ 34 + + static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]");
+ 35 + +2005879 constexpr uint64_t precision_mask = (bit_precision < 64) ?
+ 36 + + (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
+ 37 + + : uint64_t(0xFFFFFFFFFFFFFFFF);
+ 38 + +2005879 if((firstproduct.high & precision_mask) == precision_mask) { // could further guard with (lower + w < lower)
+ 39 + + // regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed.
+ 40 + +4995 value128 secondproduct = full_multiplication(w, powers::power_of_five_128[index + 1]);
+ 41 + +4995 firstproduct.low += secondproduct.high;
+ 42 + +4995 if(secondproduct.high > firstproduct.low) {
+ 43 + +1825 firstproduct.high++;
+ 44 + + }
+ 45 + + }
+ 46 + +2005879 return firstproduct;
+ 47 + + }
+ 48 + +
+ 49 + + namespace detail {
+ 50 + + /**
+ 51 + + * For q in (0,350), we have that
+ 52 + + * f = (((152170 + 65536) * q ) >> 16);
+ 53 + + * is equal to
+ 54 + + * floor(p) + q
+ 55 + + * where
+ 56 + + * p = log(5**q)/log(2) = q * log(5)/log(2)
+ 57 + + *
+ 58 + + * For negative values of q in (-400,0), we have that
+ 59 + + * f = (((152170 + 65536) * q ) >> 16);
+ 60 + + * is equal to
+ 61 + + * -ceil(p) + q
+ 62 + + * where
+ 63 + + * p = log(5**-q)/log(2) = -q * log(5)/log(2)
+ 64 + + */
+ 65 + + constexpr BOOST_FORCEINLINE int32_t power(int32_t q) noexcept {
+ 66 + +2005879 return (((152170 + 65536) * q) >> 16) + 63;
+ 67 + + }
+ 68 + + } // namespace detail
+ 69 + +
+ 70 + + // create an adjusted mantissa, biased by the invalid power2
+ 71 + + // for significant digits already multiplied by 10 ** q.
+ 72 + + template <typename binary>
+ 73 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 74 + + adjusted_mantissa compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept {
+ 75 + +2986 int hilz = int(w >> 63) ^ 1;
+ 76 + +2986 adjusted_mantissa answer;
+ 77 + +2986 answer.mantissa = w << hilz;
+ 78 + +2986 int bias = binary::mantissa_explicit_bits() - binary::minimum_exponent();
+ 79 + +5972 answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 + invalid_am_bias);
+ 80 + +2986 return answer;
+ 81 + + }
+ 82 + +
+ 83 + + // w * 10 ** q, without rounding the representation up.
+ 84 + + // the power2 in the exponent will be adjusted by invalid_am_bias.
+ 85 + + template <typename binary>
+ 86 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 87 + + adjusted_mantissa compute_error(int64_t q, uint64_t w) noexcept {
+ 88 + +2986 int lz = leading_zeroes(w);
+ 89 + +2986 w <<= lz;
+ 90 + + value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
+ 91 + +8958 return compute_error_scaled<binary>(q, product.high, lz);
+ 92 + + }
+ 93 + +
+ 94 + + // w * 10 ** q
+ 95 + + // The returned value should be a valid ieee64 number that simply need to be packed.
+ 96 + + // However, in some very rare cases, the computation will fail. In such cases, we
+ 97 + + // return an adjusted_mantissa with a negative power of 2: the caller should recompute
+ 98 + + // in such cases.
+ 99 + + template <typename binary>
+ 100 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 101 + + adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
+ 102 + +2004452 adjusted_mantissa answer;
+ 103 + +2004452 if ((w == 0) || (q < binary::smallest_power_of_ten())) {
+ 104 + +1 answer.power2 = 0;
+ 105 + +1 answer.mantissa = 0;
+ 106 + + // result should be zero
+ 107 + +1 return answer;
+ 108 + + }
+ 109 + +2004451 if (q > binary::largest_power_of_ten()) {
+ 110 + + // we want to get infinity:
+ 111 + +1558 answer.power2 = binary::infinite_power();
+ 112 + +1558 answer.mantissa = 0;
+ 113 + +1558 return answer;
+ 114 + + }
+ 115 + + // At this point in time q is in [powers::smallest_power_of_five, powers::largest_power_of_five].
+ 116 + +
+ 117 + + // We want the most significant bit of i to be 1. Shift if needed.
+ 118 + +2002893 int lz = leading_zeroes(w);
+ 119 + +2002893 w <<= lz;
+ 120 + +
+ 121 + + // The required precision is binary::mantissa_explicit_bits() + 3 because
+ 122 + + // 1. We need the implicit bit
+ 123 + + // 2. We need an extra bit for rounding purposes
+ 124 + + // 3. We might lose a bit due to the "upperbit" routine (result too small, requiring a shift)
+ 125 + +
+ 126 + + value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
+ 127 + + // The computed 'product' is always sufficient.
+ 128 + + // Mathematical proof:
+ 129 + + // Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to appear)
+ 130 + + // See script/mushtak_lemire.py
+ 131 + +
+ 132 + + // The "compute_product_approximation" function can be slightly slower than a branchless approach:
+ 133 + + // value128 product = compute_product(q, w);
+ 134 + + // but in practice, we can win big with the compute_product_approximation if its additional branch
+ 135 + + // is easily predicted. Which is best is data specific.
+ 136 + +2002893 int upperbit = int(product.high >> 63);
+ 137 + +
+ 138 + +2002893 answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
+ 139 + +
+ 140 + +4005786 answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz - binary::minimum_exponent());
+ 141 + +2002893 if (answer.power2 <= 0) { // we have a subnormal?
+ 142 + + // Here have that answer.power2 <= 0 so -answer.power2 >= 0
+ 143 + +82 if(-answer.power2 + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure.
+ 144 + + answer.power2 = 0;
+ 145 + + answer.mantissa = 0;
+ 146 + + // result should be zero
+ 147 + + return answer;
+ 148 + + }
+ 149 + + // next line is safe because -answer.power2 + 1 < 64
+ 150 + +82 answer.mantissa >>= -answer.power2 + 1;
+ 151 + + // Thankfully, we can't have both "round-to-even" and subnormals because
+ 152 + + // "round-to-even" only occurs for powers close to 0.
+ 153 + +82 answer.mantissa += (answer.mantissa & 1); // round up
+ 154 + +82 answer.mantissa >>= 1;
+ 155 + + // There is a weird scenario where we don't have a subnormal but just.
+ 156 + + // Suppose we start with 2.2250738585072013e-308, we end up
+ 157 + + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal
+ 158 + + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round
+ 159 + + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer
+ 160 + + // subnormal, but we can only know this after rounding.
+ 161 + + // So we only declare a subnormal if we are smaller than the threshold.
+ 162 + +82 answer.power2 = (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) ? 0 : 1;
+ 163 + +82 return answer;
+ 164 + + }
+ 165 + +
+ 166 + + // usually, we round *up*, but if we fall right in between and and we have an
+ 167 + + // even basis, we need to round down
+ 168 + + // We are only concerned with the cases where 5**q fits in single 64-bit word.
+ 169 + +2009538 if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && (q <= binary::max_exponent_round_to_even()) &&
+ 170 + +6727 ((answer.mantissa & 3) == 1) ) { // we may fall between two floats!
+ 171 + + // To be in-between two floats we need that in doing
+ 172 + + // answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
+ 173 + + // ... we dropped out only zeroes. But if this happened, then we can go back!!!
+ 174 + +1857 if((answer.mantissa << (upperbit + 64 - binary::mantissa_explicit_bits() - 3)) == product.high) {
+ 175 + +14 answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up
+ 176 + + }
+ 177 + + }
+ 178 + +
+ 179 + +2002811 answer.mantissa += (answer.mantissa & 1); // round up
+ 180 + +2002811 answer.mantissa >>= 1;
+ 181 + +2002811 if (answer.mantissa >= (uint64_t(2) << binary::mantissa_explicit_bits())) {
+ 182 + +360 answer.mantissa = (uint64_t(1) << binary::mantissa_explicit_bits());
+ 183 + +360 answer.power2++; // undo previous addition
+ 184 + + }
+ 185 + +
+ 186 + +2002811 answer.mantissa &= ~(uint64_t(1) << binary::mantissa_explicit_bits());
+ 187 + +2002811 if (answer.power2 >= binary::infinite_power()) { // infinity
+ 188 + +59658 answer.power2 = binary::infinite_power();
+ 189 + +59658 answer.mantissa = 0;
+ 190 + + }
+ 191 + +2002811 return answer;
+ 192 + + }
+ 193 + +
+ 194 + + }}}}}} // namespace fast_float
+ 195 + +
+ 196 + + #endif
+ 197 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.default_resource.hpp.cf498b84410e67aa58bd4c613cab1f84.html b/json/gcovr/index.default_resource.hpp.cf498b84410e67aa58bd4c613cab1f84.html new file mode 100644 index 00000000..a1402b5e --- /dev/null +++ b/json/gcovr/index.default_resource.hpp.cf498b84410e67aa58bd4c613cab1f84.html @@ -0,0 +1,2918 @@ + + + + + + detail/default_resource.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/default_resource.hpp

+
+ + 100.0% Lines (4/4) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/default_resource.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DEFAULT_RESOURCE_HPP
+ 11 + + #define BOOST_JSON_DEFAULT_RESOURCE_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/container/pmr/memory_resource.hpp>
+ 15 + +
+ 16 + + namespace boost {
+ 17 + + namespace json {
+ 18 + + namespace detail {
+ 19 + +
+ 20 + + #ifdef _MSC_VER
+ 21 + + #pragma warning(push)
+ 22 + + #pragma warning(disable: 4251) // class needs to have dll-interface to be used by clients of class
+ 23 + + #pragma warning(disable: 4275) // non dll-interface class used as base for dll-interface class
+ 24 + + #endif
+ 25 + +
+ 26 + + // A simple memory resource that uses operator new and delete.
+ 27 + + class
+ 28 + + BOOST_SYMBOL_VISIBLE
+ 29 + + BOOST_JSON_DECL
+ 30 + + default_resource final
+ 31 + + : public container::pmr::memory_resource
+ 32 + + {
+ 33 + + union holder;
+ 34 + +
+ 35 + + #ifndef BOOST_JSON_WEAK_CONSTINIT
+ 36 + + # ifndef BOOST_JSON_NO_DESTROY
+ 37 + + static holder instance_;
+ 38 + + # else
+ 39 + + BOOST_JSON_NO_DESTROY
+ 40 + + static default_resource instance_;
+ 41 + + # endif
+ 42 + + #endif
+ 43 + +
+ 44 + + public:
+ 45 + + static
+ 46 + + container::pmr::memory_resource*
+ 47 + +530672 get() noexcept
+ 48 + + {
+ 49 + + #ifdef BOOST_JSON_WEAK_CONSTINIT
+ 50 + + static default_resource instance_;
+ 51 + + #endif
+ 52 + + return reinterpret_cast<memory_resource*>(
+ 53 + + reinterpret_cast<std::uintptr_t*>(
+ 54 + +530672 &instance_));
+ 55 + + }
+ 56 + +
+ 57 + + ~default_resource();
+ 58 + +
+ 59 + + void*
+ 60 + + do_allocate(
+ 61 + + std::size_t n,
+ 62 + + std::size_t) override;
+ 63 + +
+ 64 + + void
+ 65 + + do_deallocate(
+ 66 + + void* p,
+ 67 + + std::size_t,
+ 68 + + std::size_t) override;
+ 69 + +
+ 70 + + bool
+ 71 + + do_is_equal(
+ 72 + + memory_resource const& mr) const noexcept override;
+ 73 + + };
+ 74 + +
+ 75 + + #ifdef _MSC_VER
+ 76 + + #pragma warning(pop)
+ 77 + + #endif
+ 78 + +
+ 79 + + union default_resource::
+ 80 + + holder
+ 81 + + {
+ 82 + + #ifndef BOOST_JSON_WEAK_CONSTINIT
+ 83 + + constexpr
+ 84 + + #endif
+ 85 + + holder()
+ 86 + + : mr()
+ 87 + + {
+ 88 + + }
+ 89 + +
+ 90 + +39 ~holder()
+ 91 + + {
+ 92 + +39 }
+ 93 + +
+ 94 + + default_resource mr;
+ 95 + + };
+ 96 + +
+ 97 + + } // detail
+ 98 + + } // namespace json
+ 99 + + } // namespace boost
+ 100 + +
+ 101 + + #endif
+ 102 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.default_resource.ipp.29b0230184410f16ceaecef9a447dcef.html b/json/gcovr/index.default_resource.ipp.29b0230184410f16ceaecef9a447dcef.html new file mode 100644 index 00000000..27852584 --- /dev/null +++ b/json/gcovr/index.default_resource.ipp.29b0230184410f16ceaecef9a447dcef.html @@ -0,0 +1,2654 @@ + + + + + + detail/impl/default_resource.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/impl/default_resource.ipp

+
+ + 87.5% Lines (7/8) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/impl/default_resource.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_IMPL_DEFAULT_RESOURCE_IPP
+ 11 + + #define BOOST_JSON_DETAIL_IMPL_DEFAULT_RESOURCE_IPP
+ 12 + +
+ 13 + + #include <boost/json/detail/default_resource.hpp>
+ 14 + +
+ 15 + + namespace boost {
+ 16 + + namespace json {
+ 17 + + namespace detail {
+ 18 + +
+ 19 + + #ifndef BOOST_JSON_WEAK_CONSTINIT
+ 20 + + # ifndef BOOST_JSON_NO_DESTROY
+ 21 + + BOOST_JSON_REQUIRE_CONST_INIT
+ 22 + + default_resource::holder
+ 23 + + default_resource::instance_;
+ 24 + + # else
+ 25 + + BOOST_JSON_REQUIRE_CONST_INIT
+ 26 + + default_resource
+ 27 + + default_resource::instance_;
+ 28 + + # endif
+ 29 + + #endif
+ 30 + +
+ 31 + + // this is here so that ~memory_resource
+ 32 + + // is emitted in the library instead of
+ 33 + + // the user's TU.
+ 34 + + default_resource::
+ 35 + + ~default_resource() = default;
+ 36 + +
+ 37 + + void*
+ 38 + +264138 default_resource::
+ 39 + + do_allocate(
+ 40 + + std::size_t n,
+ 41 + + std::size_t)
+ 42 + + {
+ 43 + +264138 return ::operator new(n);
+ 44 + + }
+ 45 + +
+ 46 + + void
+ 47 + +264138 default_resource::
+ 48 + + do_deallocate(
+ 49 + + void* p,
+ 50 + + std::size_t,
+ 51 + + std::size_t)
+ 52 + + {
+ 53 + +264138 ::operator delete(p);
+ 54 + +264138 }
+ 55 + +
+ 56 + + bool
+ 57 + +23 default_resource::
+ 58 + + do_is_equal(
+ 59 + + memory_resource const& mr) const noexcept
+ 60 + + {
+ 61 + +23 return this == &mr;
+ 62 + + }
+ 63 + +
+ 64 + + } // detail
+ 65 + + } // namespace json
+ 66 + + } // namespace boost
+ 67 + +
+ 68 + + #endif
+ 69 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.detail.0ab43ac414239956f09d5b0181f77c50.html b/json/gcovr/index.detail.0ab43ac414239956f09d5b0181f77c50.html new file mode 100644 index 00000000..94e84d1f --- /dev/null +++ b/json/gcovr/index.detail.0ab43ac414239956f09d5b0181f77c50.html @@ -0,0 +1,2872 @@ + + + + + + detail/ - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+
+

Lines

+
+
+
+ + + + + 93.3% +
+
+
+ Hit + 8225 +
+
+ Total + 8811 +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+
+ +
+ High: ≥ 90.0% + Medium: ≥ 75.0% + Low: < 75.0% +
+ +
+
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+
+ +
+
+ +
+ + + + array.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 9 + / + 9 +
+ + +
+
+ +
+ + + + buffer.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 44 + / + 44 +
+ + +
+
+ +
+ + + + charconv +
+ +
+
+
+
+ 52.9% +
+ +
+ 587 + / + 1109 +
+ + +
+
+ +
+ + + + config.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 4 + / + 4 +
+ + +
+
+ + + +
+
+
+
+ 100.0% +
+ +
+ 4 + / + 4 +
+ + +
+
+ +
+ + + + digest.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 27 + / + 27 +
+ + +
+
+ +
+ + + + impl +
+ +
+
+
+
+ 99.3% +
+ +
+ 451 + / + 454 +
+ + +
+
+ +
+ + + + literals.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 2 + / + 2 +
+ + +
+
+ +
+ + + + object.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 13 + / + 13 +
+ + +
+
+ +
+ + + + parse_into.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 395 + / + 395 +
+ + +
+
+ +
+ + + + ryu +
+ +
+
+
+
+ 99.7% +
+ +
+ 338 + / + 339 +
+ + +
+
+ +
+ + + + sbo_buffer.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 44 + / + 44 +
+ + +
+
+ + + +
+
+
+
+ 100.0% +
+ +
+ 9 + / + 9 +
+ + +
+
+ +
+ + + + sse2.hpp +
+ +
+
+
+
+ 97.8% +
+ +
+ 134 + / + 137 +
+ + +
+
+ +
+ + + + stack.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 13 + / + 13 +
+ + +
+
+ +
+ + + + stream.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 101 + / + 101 +
+ + +
+
+ +
+ + + + string_impl.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 73 + / + 73 +
+ + +
+
+ +
+ + + + utf8.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 62 + / + 62 +
+ + +
+
+ +
+ + + + value.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 61 + / + 61 +
+ + +
+
+ +
+ + + + value_from.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 46 + / + 46 +
+ + +
+
+ +
+ + + + value_to.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 157 + / + 157 +
+ + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.detail.287b6ad9e303318f27f0e943b3878477.html b/json/gcovr/index.detail.287b6ad9e303318f27f0e943b3878477.html new file mode 100644 index 00000000..1ce10ea2 --- /dev/null +++ b/json/gcovr/index.detail.287b6ad9e303318f27f0e943b3878477.html @@ -0,0 +1,2368 @@ + + + + + + detail/charconv/detail/ - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+
+

Lines

+
+
+
+ + + + + 93.3% +
+
+
+ Hit + 8225 +
+
+ Total + 8811 +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+
+ +
+ High: ≥ 90.0% + Medium: ≥ 75.0% + Low: < 75.0% +
+ +
+
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+
+ +
+
+ + + +
+
+
+
+ 0.0% +
+ +
+ 0 + / + 53 +
+ + +
+
+ +
+ + + + emulated128.hpp +
+ +
+
+
+
+ 0.0% +
+ +
+ 0 + / + 3 +
+ + +
+
+ +
+ + + + fast_float +
+ +
+
+
+
+ 79.6% +
+ +
+ 584 + / + 734 +
+ + +
+
+ + + +
+
+
+
+ 0.0% +
+ +
+ 0 + / + 49 +
+ + +
+
+ + + +
+
+
+
+ 0.0% +
+ +
+ 0 + / + 56 +
+ + +
+
+ + + +
+
+
+
+ 0.0% +
+ +
+ 0 + / + 40 +
+ + +
+
+ +
+ + + + parser.hpp +
+ +
+
+
+
+ 0.0% +
+ +
+ 0 + / + 162 +
+ + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.detail.e4ef6da21b1421bbb8fd14958bc3b5ac.html b/json/gcovr/index.detail.e4ef6da21b1421bbb8fd14958bc3b5ac.html new file mode 100644 index 00000000..a0be055b --- /dev/null +++ b/json/gcovr/index.detail.e4ef6da21b1421bbb8fd14958bc3b5ac.html @@ -0,0 +1,2296 @@ + + + + + + detail/ryu/detail/ - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+
+

Lines

+
+
+
+ + + + + 93.3% +
+
+
+ Hit + 8225 +
+
+ Total + 8811 +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+
+ +
+ High: ≥ 90.0% + Medium: ≥ 75.0% + Low: < 75.0% +
+ +
+
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+
+ +
+
+ +
+ + + + common.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 38 + / + 38 +
+ + +
+
+ +
+ + + + d2s.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 42 + / + 42 +
+ + +
+
+ +
+ + + + d2s_full_table.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 4 + / + 4 +
+ + +
+
+ +
+ + + + d2s_intrinsics.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 28 + / + 28 +
+ + +
+
+ +
+ + + + digit_table.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 2 + / + 2 +
+ + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.digest.hpp.905cd2165a4f34376c449f885fe1adf1.html b/json/gcovr/index.digest.hpp.905cd2165a4f34376c449f885fe1adf1.html new file mode 100644 index 00000000..67cb84a7 --- /dev/null +++ b/json/gcovr/index.digest.hpp.905cd2165a4f34376c449f885fe1adf1.html @@ -0,0 +1,3030 @@ + + + + + + detail/digest.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/digest.hpp

+
+ + 100.0% Lines (27/27) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/digest.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_DIGEST_HPP
+ 11 + + #define BOOST_JSON_DETAIL_DIGEST_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + +
+ 15 + + #include <algorithm>
+ 16 + + #include <iterator>
+ 17 + +
+ 18 + + namespace boost {
+ 19 + + namespace json {
+ 20 + + namespace detail {
+ 21 + +
+ 22 + + // Calculate salted digest of string
+ 23 + + template<class ForwardIterator>
+ 24 + + std::size_t
+ 25 + +11298 digest(ForwardIterator b, ForwardIterator e, std::size_t salt) noexcept
+ 26 + + {
+ 27 + +11298 std::size_t const len = std::distance(b, e);
+ 28 + +
+ 29 + + #if BOOST_JSON_ARCH == 64
+ 30 + +
+ 31 + + using state_type = std::uint64_t;
+ 32 + +11298 state_type const m = 0xc6a4a7935bd1e995ULL;
+ 33 + +11298 int const r = 47;
+ 34 + +11298 state_type hash = salt ^ (len * m);
+ 35 + +
+ 36 + +11298 constexpr std::size_t N = sizeof(state_type);
+ 37 + +11298 e = std::next( b, len & ~std::size_t(N-1) );
+ 38 + +11328 for( ; b != e; std::advance(b, N) )
+ 39 + + {
+ 40 + + state_type num;
+ 41 + + #ifdef _MSC_VER
+ 42 + + # pragma warning(push)
+ 43 + + # pragma warning(disable: 4996)
+ 44 + + #endif
+ 45 + +30 std::copy_n( b, N, reinterpret_cast<unsigned char*>(&num) );
+ 46 + + #ifdef _MSC_VER
+ 47 + + # pragma warning(pop)
+ 48 + + #endif
+ 49 + +
+ 50 + +30 num *= m;
+ 51 + +30 num ^= num >> r;
+ 52 + +30 num *= m;
+ 53 + +30 hash ^= num;
+ 54 + +30 hash *= m;
+ 55 + + }
+ 56 + +
+ 57 + +11298 switch( len & (N - 1) )
+ 58 + + {
+ 59 + +12 case 7: hash ^= state_type( *std::next(b, 6) ) << 48; // fall through
+ 60 + +24 case 6: hash ^= state_type( *std::next(b, 5) ) << 40; // fall through
+ 61 + +40 case 5: hash ^= state_type( *std::next(b, 4) ) << 32; // fall through
+ 62 + +70 case 4: hash ^= state_type( *std::next(b, 3) ) << 24; // fall through
+ 63 + +5502 case 3: hash ^= state_type( *std::next(b, 2) ) << 16; // fall through
+ 64 + +12624 case 2: hash ^= state_type( *std::next(b, 1) ) << 8; // fall through
+ 65 + +11308 case 1: hash ^= state_type( *std::next(b, 0) );
+ 66 + +11292 hash *= m;
+ 67 + + };
+ 68 + +
+ 69 + +11298 hash ^= hash >> r;
+ 70 + +11298 hash *= m;
+ 71 + +11298 hash ^= hash >> r;
+ 72 + +
+ 73 + + #else
+ 74 + +
+ 75 + + using state_type = std::uint32_t;
+ 76 + + state_type const m = 0x5bd1e995;
+ 77 + + int const r = 24;
+ 78 + + state_type hash = salt ^ len;
+ 79 + +
+ 80 + + constexpr std::size_t N = sizeof(state_type);
+ 81 + + e = std::next( b, len & ~std::size_t(N-1) );
+ 82 + + for( ; b != e; std::advance(b, N) )
+ 83 + + {
+ 84 + + state_type num;
+ 85 + + std::copy_n( b, N, reinterpret_cast<unsigned char*>(&num) );
+ 86 + +
+ 87 + + num *= m;
+ 88 + + num ^= num >> r;
+ 89 + + num *= m;
+ 90 + + hash *= m;
+ 91 + + hash ^= num;
+ 92 + + }
+ 93 + +
+ 94 + + switch( len & (N - 1) )
+ 95 + + {
+ 96 + + case 3: hash ^= state_type( *std::next(b, 2) ) << 16; // fall through
+ 97 + + case 2: hash ^= state_type( *std::next(b, 1) ) << 8; // fall through
+ 98 + + case 1: hash ^= state_type( *std::next(b, 0) );
+ 99 + + hash *= m;
+ 100 + + };
+ 101 + +
+ 102 + + hash ^= hash >> 13;
+ 103 + + hash *= m;
+ 104 + + hash ^= hash >> 15;
+ 105 + +
+ 106 + + #endif
+ 107 + +
+ 108 + +11298 return hash;
+ 109 + + }
+ 110 + +
+ 111 + + } // detail
+ 112 + + } // namespace json
+ 113 + + } // namespace boost
+ 114 + +
+ 115 + + #endif
+ 116 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.digit_comparison.hpp.d6697c5bee8735e93381acb1ede736e7.html b/json/gcovr/index.digit_comparison.hpp.d6697c5bee8735e93381acb1ede736e7.html new file mode 100644 index 00000000..d17060e1 --- /dev/null +++ b/json/gcovr/index.digit_comparison.hpp.d6697c5bee8735e93381acb1ede736e7.html @@ -0,0 +1,5646 @@ + + + + + + detail/charconv/detail/fast_float/digit_comparison.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/fast_float/digit_comparison.hpp

+
+ + 76.9% Lines (143/186) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/fast_float/digit_comparison.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2020-2023 Daniel Lemire
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + + //
+ 6 + + // Derivative of: https://github.com/fastfloat/fast_float
+ 7 + +
+ 8 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_DIGIT_COMPARISON_HPP
+ 9 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_DIGIT_COMPARISON_HPP
+ 10 + +
+ 11 + + #include <boost/json/detail/charconv/detail/fast_float/float_common.hpp>
+ 12 + + #include <boost/json/detail/charconv/detail/fast_float/bigint.hpp>
+ 13 + + #include <boost/json/detail/charconv/detail/fast_float/ascii_number.hpp>
+ 14 + + #include <algorithm>
+ 15 + + #include <cstdint>
+ 16 + + #include <cstring>
+ 17 + + #include <iterator>
+ 18 + +
+ 19 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float {
+ 20 + +
+ 21 + + // 1e0 to 1e19
+ 22 + + constexpr static uint64_t powers_of_ten_uint64[] = {
+ 23 + + 1UL, 10UL, 100UL, 1000UL, 10000UL, 100000UL, 1000000UL, 10000000UL, 100000000UL,
+ 24 + + 1000000000UL, 10000000000UL, 100000000000UL, 1000000000000UL, 10000000000000UL,
+ 25 + + 100000000000000UL, 1000000000000000UL, 10000000000000000UL, 100000000000000000UL,
+ 26 + + 1000000000000000000UL, 10000000000000000000UL};
+ 27 + +
+ 28 + + // calculate the exponent, in scientific notation, of the number.
+ 29 + + // this algorithm is not even close to optimized, but it has no practical
+ 30 + + // effect on performance: in order to have a faster algorithm, we'd need
+ 31 + + // to slow down performance for faster algorithms, and this is still fast.
+ 32 + + template <typename UC>
+ 33 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 34 + + int32_t scientific_exponent(parsed_number_string_t<UC> & num) noexcept {
+ 35 + +2986 uint64_t mantissa = num.mantissa;
+ 36 + +2986 int32_t exponent = int32_t(num.exponent);
+ 37 + +14930 while (mantissa >= 10000) {
+ 38 + +11944 mantissa /= 10000;
+ 39 + +11944 exponent += 4;
+ 40 + + }
+ 41 + +5972 while (mantissa >= 100) {
+ 42 + +2986 mantissa /= 100;
+ 43 + +2986 exponent += 2;
+ 44 + + }
+ 45 + +2986 while (mantissa >= 10) {
+ 46 + + mantissa /= 10;
+ 47 + + exponent += 1;
+ 48 + + }
+ 49 + +2986 return exponent;
+ 50 + + }
+ 51 + +
+ 52 + + // this converts a native floating-point number to an extended-precision float.
+ 53 + + template <typename T>
+ 54 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 55 + + adjusted_mantissa to_extended(T value) noexcept {
+ 56 + + using equiv_uint = typename binary_format<T>::equiv_uint;
+ 57 + +1611 constexpr equiv_uint exponent_mask = binary_format<T>::exponent_mask();
+ 58 + +1611 constexpr equiv_uint mantissa_mask = binary_format<T>::mantissa_mask();
+ 59 + +1611 constexpr equiv_uint hidden_bit_mask = binary_format<T>::hidden_bit_mask();
+ 60 + +
+ 61 + +1611 adjusted_mantissa am;
+ 62 + +1611 int32_t bias = binary_format<T>::mantissa_explicit_bits() - binary_format<T>::minimum_exponent();
+ 63 + + equiv_uint bits;
+ 64 + + #ifdef BOOST_JSON_HAS_BIT_CAST
+ 65 + + bits = std::bit_cast<equiv_uint>(value);
+ 66 + + #else
+ 67 + +1611 ::memcpy(&bits, &value, sizeof(T));
+ 68 + + #endif
+ 69 + +1611 if ((bits & exponent_mask) == 0) {
+ 70 + + // denormal
+ 71 + + am.power2 = 1 - bias;
+ 72 + + am.mantissa = bits & mantissa_mask;
+ 73 + + } else {
+ 74 + + // normal
+ 75 + +1611 am.power2 = int32_t((bits & exponent_mask) >> binary_format<T>::mantissa_explicit_bits());
+ 76 + +1611 am.power2 -= bias;
+ 77 + +1611 am.mantissa = (bits & mantissa_mask) | hidden_bit_mask;
+ 78 + + }
+ 79 + +
+ 80 + +1611 return am;
+ 81 + + }
+ 82 + +
+ 83 + + // get the extended precision value of the halfway point between b and b+u.
+ 84 + + // we are given a native float that represents b, so we need to adjust it
+ 85 + + // halfway between b and b+u.
+ 86 + + template <typename T>
+ 87 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 88 + + adjusted_mantissa to_extended_halfway(T value) noexcept {
+ 89 + +1611 adjusted_mantissa am = to_extended(value);
+ 90 + +1611 am.mantissa <<= 1;
+ 91 + +1611 am.mantissa += 1;
+ 92 + +1611 am.power2 -= 1;
+ 93 + +1611 return am;
+ 94 + + }
+ 95 + +
+ 96 + + // round an extended-precision float to the nearest machine float.
+ 97 + + template <typename T, typename callback>
+ 98 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 99 + + void round(adjusted_mantissa& am, callback cb) noexcept {
+ 100 + +4597 int32_t mantissa_shift = 64 - binary_format<T>::mantissa_explicit_bits() - 1;
+ 101 + +4597 if (-am.power2 >= mantissa_shift) {
+ 102 + + // have a denormal float
+ 103 + + int32_t shift = -am.power2 + 1;
+ 104 + + cb(am, std::min<int32_t>(shift, 64));
+ 105 + + // check for round-up: if rounding-nearest carried us to the hidden bit.
+ 106 + + am.power2 = (am.mantissa < (uint64_t(1) << binary_format<T>::mantissa_explicit_bits())) ? 0 : 1;
+ 107 + + return;
+ 108 + + }
+ 109 + +
+ 110 + + // have a normal float, use the default shift.
+ 111 + +4597 cb(am, mantissa_shift);
+ 112 + +
+ 113 + + // check for carry
+ 114 + +4597 if (am.mantissa >= (uint64_t(2) << binary_format<T>::mantissa_explicit_bits())) {
+ 115 + + am.mantissa = (uint64_t(1) << binary_format<T>::mantissa_explicit_bits());
+ 116 + + am.power2++;
+ 117 + + }
+ 118 + +
+ 119 + + // check for infinite: we could have carried to an infinite power
+ 120 + +4597 am.mantissa &= ~(uint64_t(1) << binary_format<T>::mantissa_explicit_bits());
+ 121 + +4597 if (am.power2 >= binary_format<T>::infinite_power()) {
+ 122 + + am.power2 = binary_format<T>::infinite_power();
+ 123 + + am.mantissa = 0;
+ 124 + + }
+ 125 + + }
+ 126 + +
+ 127 + + template <typename callback>
+ 128 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 129 + + void round_nearest_tie_even(adjusted_mantissa& am, int32_t shift, callback cb) noexcept {
+ 130 + +2986 const uint64_t mask
+ 131 + + = (shift == 64)
+ 132 + + ? UINT64_MAX
+ 133 + +2986 : (uint64_t(1) << shift) - 1;
+ 134 + +2986 const uint64_t halfway
+ 135 + + = (shift == 0)
+ 136 + +2986 ? 0
+ 137 + +2986 : uint64_t(1) << (shift - 1);
+ 138 + +2986 uint64_t truncated_bits = am.mantissa & mask;
+ 139 + +2986 bool is_above = truncated_bits > halfway;
+ 140 + +2986 bool is_halfway = truncated_bits == halfway;
+ 141 + +
+ 142 + + // shift digits into position
+ 143 + +2986 if (shift == 64) {
+ 144 + + am.mantissa = 0;
+ 145 + + } else {
+ 146 + +2986 am.mantissa >>= shift;
+ 147 + + }
+ 148 + +2986 am.power2 += shift;
+ 149 + +
+ 150 + +2986 bool is_odd = (am.mantissa & 1) == 1;
+ 151 + +2986 am.mantissa += uint64_t(cb(is_odd, is_halfway, is_above));
+ 152 + +2986 }
+ 153 + +
+ 154 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 155 + + void round_down(adjusted_mantissa& am, int32_t shift) noexcept {
+ 156 + +1611 if (shift == 64) {
+ 157 + + am.mantissa = 0;
+ 158 + + } else {
+ 159 + +1611 am.mantissa >>= shift;
+ 160 + + }
+ 161 + +1611 am.power2 += shift;
+ 162 + +1611 }
+ 163 + + template <typename UC>
+ 164 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 165 + + void skip_zeros(UC const * & first, UC const * last) noexcept {
+ 166 + + uint64_t val;
+ 167 + +5972 while (!cpp20_and_in_constexpr() && std::distance(first, last) >= int_cmp_len<UC>()) {
+ 168 + +2986 ::memcpy(&val, first, sizeof(uint64_t));
+ 169 + +2986 if (val != int_cmp_zeros<UC>()) {
+ 170 + +2986 break;
+ 171 + + }
+ 172 + + first += int_cmp_len<UC>();
+ 173 + + }
+ 174 + +2986 while (first != last) {
+ 175 + +2986 if (*first != UC('0')) {
+ 176 + +2986 break;
+ 177 + + }
+ 178 + + first++;
+ 179 + + }
+ 180 + +2986 }
+ 181 + +
+ 182 + + // determine if any non-zero digits were truncated.
+ 183 + + // all characters must be valid digits.
+ 184 + + template <typename UC>
+ 185 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 186 + + bool is_truncated(UC const * first, UC const * last) noexcept {
+ 187 + + // do 8-bit optimizations, can just compare to 8 literal 0s.
+ 188 + + uint64_t val;
+ 189 + + while (!cpp20_and_in_constexpr() && std::distance(first, last) >= int_cmp_len<UC>()) {
+ 190 + + ::memcpy(&val, first, sizeof(uint64_t));
+ 191 + + if (val != int_cmp_zeros<UC>()) {
+ 192 + + return true;
+ 193 + + }
+ 194 + + first += int_cmp_len<UC>();
+ 195 + + }
+ 196 + + while (first != last) {
+ 197 + + if (*first != UC('0')) {
+ 198 + + return true;
+ 199 + + }
+ 200 + + ++first;
+ 201 + + }
+ 202 + + return false;
+ 203 + + }
+ 204 + + template <typename UC>
+ 205 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 206 + + bool is_truncated(span<const UC> s) noexcept {
+ 207 + + return is_truncated(s.ptr, s.ptr + s.len());
+ 208 + + }
+ 209 + +
+ 210 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 211 + + void parse_eight_digits(const char16_t*& , limb& , size_t& , size_t& ) noexcept {
+ 212 + + // currently unused
+ 213 + + }
+ 214 + +
+ 215 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 216 + + void parse_eight_digits(const char32_t*& , limb& , size_t& , size_t& ) noexcept {
+ 217 + + // currently unused
+ 218 + + }
+ 219 + +
+ 220 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 221 + + void parse_eight_digits(const char*& p, limb& value, size_t& counter, size_t& count) noexcept {
+ 222 + +11932 value = value * 100000000 + parse_eight_digits_unrolled(p);
+ 223 + +11932 p += 8;
+ 224 + +11932 counter += 8;
+ 225 + +11932 count += 8;
+ 226 + +11932 }
+ 227 + +
+ 228 + + template <typename UC>
+ 229 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 230 + + void parse_one_digit(UC const *& p, limb& value, size_t& counter, size_t& count) noexcept {
+ 231 + +21125 value = value * 10 + limb(*p - UC('0'));
+ 232 + +21125 p++;
+ 233 + +21125 counter++;
+ 234 + +21125 count++;
+ 235 + +21125 }
+ 236 + +
+ 237 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 238 + + void add_native(bigint& big, limb power, limb value) noexcept {
+ 239 + + big.mul(power);
+ 240 + +9437 big.add(value);
+ 241 + +9437 }
+ 242 + +
+ 243 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 244 + + void round_up_bigint(bigint& big, size_t& count) noexcept {
+ 245 + + // need to round-up the digits, but need to avoid rounding
+ 246 + + // ....9999 to ...10000, which could cause a false halfway point.
+ 247 + + add_native(big, 10, 1);
+ 248 + + count++;
+ 249 + + }
+ 250 + +
+ 251 + + // parse the significant digits into a big integer
+ 252 + + template <typename UC>
+ 253 + + inline BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 254 + +2986 void parse_mantissa(bigint& result, parsed_number_string_t<UC>& num, size_t max_digits, size_t& digits) noexcept {
+ 255 + + // try to minimize the number of big integer and scalar multiplication.
+ 256 + + // therefore, try to parse 8 digits at a time, and multiply by the largest
+ 257 + + // scalar value (9 or 19 digits) for each step.
+ 258 + +2986 size_t counter = 0;
+ 259 + +2986 digits = 0;
+ 260 + +2986 limb value = 0;
+ 261 + + #ifdef BOOST_JSON_FASTFLOAT_64BIT_LIMB
+ 262 + +2986 constexpr size_t step = 19;
+ 263 + + #else
+ 264 + + constexpr size_t step = 9;
+ 265 + + #endif
+ 266 + +
+ 267 + + // process all integer digits.
+ 268 + +2986 UC const * p = num.integer.ptr;
+ 269 + +2986 UC const * pend = p + num.integer.len();
+ 270 + + skip_zeros(p, pend);
+ 271 + + // process all digits, in increments of step per loop
+ 272 + +8073 while (p != pend) {
+ 273 + + if (std::is_same<UC,char>::value) {
+ 274 + +22118 while ((std::distance(p, pend) >= 8) && (step - counter >= 8) && (max_digits - digits >= 8)) {
+ 275 + + parse_eight_digits(p, value, counter, digits);
+ 276 + + }
+ 277 + + }
+ 278 + +16053 while (counter < step && p != pend && digits < max_digits) {
+ 279 + + parse_one_digit(p, value, counter, digits);
+ 280 + + }
+ 281 + +5087 if (digits == max_digits) {
+ 282 + + // add the temporary value, then check if we've truncated any digits
+ 283 + + add_native(result, limb(powers_of_ten_uint64[counter]), value);
+ 284 + + bool truncated = is_truncated(p, pend);
+ 285 + + if (num.fraction.ptr != nullptr) {
+ 286 + + truncated |= is_truncated(num.fraction);
+ 287 + + }
+ 288 + + if (truncated) {
+ 289 + + round_up_bigint(result, digits);
+ 290 + + }
+ 291 + + return;
+ 292 + + } else {
+ 293 + +5087 add_native(result, limb(powers_of_ten_uint64[counter]), value);
+ 294 + +5087 counter = 0;
+ 295 + +5087 value = 0;
+ 296 + + }
+ 297 + + }
+ 298 + +
+ 299 + + // add our fraction digits, if they're available.
+ 300 + +2986 if (num.fraction.ptr != nullptr) {
+ 301 + +2980 p = num.fraction.ptr;
+ 302 + +2980 pend = p + num.fraction.len();
+ 303 + +2980 if (digits == 0) {
+ 304 + + skip_zeros(p, pend);
+ 305 + + }
+ 306 + + // process all digits, in increments of step per loop
+ 307 + +7330 while (p != pend) {
+ 308 + + if (std::is_same<UC,char>::value) {
+ 309 + +20620 while ((std::distance(p, pend) >= 8) && (step - counter >= 8) && (max_digits - digits >= 8)) {
+ 310 + + parse_eight_digits(p, value, counter, digits);
+ 311 + + }
+ 312 + + }
+ 313 + +14509 while (counter < step && p != pend && digits < max_digits) {
+ 314 + + parse_one_digit(p, value, counter, digits);
+ 315 + + }
+ 316 + +4350 if (digits == max_digits) {
+ 317 + + // add the temporary value, then check if we've truncated any digits
+ 318 + + add_native(result, limb(powers_of_ten_uint64[counter]), value);
+ 319 + + bool truncated = is_truncated(p, pend);
+ 320 + + if (truncated) {
+ 321 + + round_up_bigint(result, digits);
+ 322 + + }
+ 323 + + return;
+ 324 + + } else {
+ 325 + +4350 add_native(result, limb(powers_of_ten_uint64[counter]), value);
+ 326 + +4350 counter = 0;
+ 327 + +4350 value = 0;
+ 328 + + }
+ 329 + + }
+ 330 + + }
+ 331 + +
+ 332 + +2986 if (counter != 0) {
+ 333 + + add_native(result, limb(powers_of_ten_uint64[counter]), value);
+ 334 + + }
+ 335 + + }
+ 336 + +
+ 337 + + template <typename T>
+ 338 + + inline BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 339 + +1375 adjusted_mantissa positive_digit_comp(bigint& bigmant, int32_t exponent) noexcept {
+ 340 + +1375 bigmant.pow10(uint32_t(exponent));
+ 341 + +1375 adjusted_mantissa answer;
+ 342 + + bool truncated;
+ 343 + +1375 answer.mantissa = bigmant.hi64(truncated);
+ 344 + +1375 int bias = binary_format<T>::mantissa_explicit_bits() - binary_format<T>::minimum_exponent();
+ 345 + +1375 answer.power2 = bigmant.bit_length() - 64 + bias;
+ 346 + +
+ 347 + +1375 round<T>(answer, [truncated](adjusted_mantissa& a, int32_t shift) {
+ 348 + +1375 round_nearest_tie_even(a, shift, [truncated](bool is_odd, bool is_halfway, bool is_above) -> bool {
+ 349 + +1375 return is_above || (is_halfway && truncated) || (is_odd && is_halfway);
+ 350 + + });
+ 351 + + });
+ 352 + +
+ 353 + +1375 return answer;
+ 354 + + }
+ 355 + +
+ 356 + + // the scaling here is quite simple: we have, for the real digits `m * 10^e`,
+ 357 + + // and for the theoretical digits `n * 2^f`. Since `e` is always negative,
+ 358 + + // to scale them identically, we do `n * 2^f * 5^-f`, so we now have `m * 2^e`.
+ 359 + + // we then need to scale by `2^(f- e)`, and then the two significant digits
+ 360 + + // are of the same magnitude.
+ 361 + + template <typename T>
+ 362 + + inline BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 363 + +1611 adjusted_mantissa negative_digit_comp(bigint& bigmant, adjusted_mantissa am, int32_t exponent) noexcept {
+ 364 + +1611 bigint& real_digits = bigmant;
+ 365 + +1611 int32_t real_exp = exponent;
+ 366 + +
+ 367 + + // get the value of `b`, rounded down, and get a bigint representation of b+h
+ 368 + +1611 adjusted_mantissa am_b = am;
+ 369 + + // gcc7 buf: use a lambda to remove the noexcept qualifier bug with -Wnoexcept-type.
+ 370 + +3222 round<T>(am_b, [](adjusted_mantissa&a, int32_t shift) { round_down(a, shift); });
+ 371 + + T b;
+ 372 + +1611 to_float(false, am_b, b);
+ 373 + +1611 adjusted_mantissa theor = to_extended_halfway(b);
+ 374 + +1611 bigint theor_digits(theor.mantissa);
+ 375 + +1611 int32_t theor_exp = theor.power2;
+ 376 + +
+ 377 + + // scale real digits and theor digits to be same power.
+ 378 + +1611 int32_t pow2_exp = theor_exp - real_exp;
+ 379 + +1611 uint32_t pow5_exp = uint32_t(-real_exp);
+ 380 + +1611 if (pow5_exp != 0) {
+ 381 + +1611 theor_digits.pow5(pow5_exp);
+ 382 + + }
+ 383 + +1611 if (pow2_exp > 0) {
+ 384 + +140 theor_digits.pow2(uint32_t(pow2_exp));
+ 385 + +1471 } else if (pow2_exp < 0) {
+ 386 + +1469 real_digits.pow2(uint32_t(-pow2_exp));
+ 387 + + }
+ 388 + +
+ 389 + + // compare digits, and use it to director rounding
+ 390 + +1611 int ord = real_digits.compare(theor_digits);
+ 391 + +1611 adjusted_mantissa answer = am;
+ 392 + +1611 round<T>(answer, [ord](adjusted_mantissa& a, int32_t shift) {
+ 393 + +1611 round_nearest_tie_even(a, shift, [ord](bool is_odd, bool, bool) -> bool {
+ 394 + +1611 if (ord > 0) {
+ 395 + +767 return true;
+ 396 + +844 } else if (ord < 0) {
+ 397 + +844 return false;
+ 398 + + } else {
+ 399 + + return is_odd;
+ 400 + + }
+ 401 + + });
+ 402 + + });
+ 403 + +
+ 404 + +1611 return answer;
+ 405 + + }
+ 406 + +
+ 407 + + // parse the significant digits as a big integer to unambiguously round
+ 408 + + // the significant digits. here, we are trying to determine how to round
+ 409 + + // an extended float representation close to `b+h`, halfway between `b`
+ 410 + + // (the float rounded-down) and `b+u`, the next positive float. this
+ 411 + + // algorithm is always correct, and uses one of two approaches. when
+ 412 + + // the exponent is positive relative to the significant digits (such as
+ 413 + + // 1234), we create a big-integer representation, get the high 64-bits,
+ 414 + + // determine if any lower bits are truncated, and use that to direct
+ 415 + + // rounding. in case of a negative exponent relative to the significant
+ 416 + + // digits (such as 1.2345), we create a theoretical representation of
+ 417 + + // `b` as a big-integer type, scaled to the same binary exponent as
+ 418 + + // the actual digits. we then compare the big integer representations
+ 419 + + // of both, and use that to direct rounding.
+ 420 + + template <typename T, typename UC>
+ 421 + + inline BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 422 + +2986 adjusted_mantissa digit_comp(parsed_number_string_t<UC>& num, adjusted_mantissa am) noexcept {
+ 423 + + // remove the invalid exponent bias
+ 424 + +2986 am.power2 -= invalid_am_bias;
+ 425 + +
+ 426 + +2986 int32_t sci_exp = scientific_exponent(num);
+ 427 + +2986 size_t max_digits = binary_format<T>::max_digits();
+ 428 + +2986 size_t digits = 0;
+ 429 + +2986 bigint bigmant;
+ 430 + +2986 parse_mantissa(bigmant, num, max_digits, digits);
+ 431 + + // can't underflow, since digits is at most max_digits.
+ 432 + +2986 int32_t exponent = sci_exp + 1 - int32_t(digits);
+ 433 + +2986 if (exponent >= 0) {
+ 434 + +1375 return positive_digit_comp<T>(bigmant, exponent);
+ 435 + + } else {
+ 436 + +1611 return negative_digit_comp<T>(bigmant, am, exponent);
+ 437 + + }
+ 438 + + }
+ 439 + +
+ 440 + + }}}}}} // namespace fast_float
+ 441 + +
+ 442 + + #endif
+ 443 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.digit_table.hpp.54cb42fce758b96305314c836f5822d5.html b/json/gcovr/index.digit_table.hpp.54cb42fce758b96305314c836f5822d5.html new file mode 100644 index 00000000..c1195f32 --- /dev/null +++ b/json/gcovr/index.digit_table.hpp.54cb42fce758b96305314c836f5822d5.html @@ -0,0 +1,2598 @@ + + + + + + detail/ryu/detail/digit_table.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/ryu/detail/digit_table.hpp

+
+ + 100.0% Lines (2/2) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/ryu/detail/digit_table.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2018 Ulf Adams
+ 2 + + //
+ 3 + + // The contents of this file may be used under the terms of the Apache License,
+ 4 + + // Version 2.0.
+ 5 + + //
+ 6 + + // (See accompanying file LICENSE-Apache or copy at
+ 7 + + // http://www.apache.org/licenses/LICENSE-2.0)
+ 8 + + //
+ 9 + + // Alternatively, the contents of this file may be used under the terms of
+ 10 + + // the Boost Software License, Version 1.0.
+ 11 + + // (See accompanying file LICENSE-Boost or copy at
+ 12 + + // https://www.boost.org/LICENSE_1_0.txt)
+ 13 + + //
+ 14 + + // Unless required by applicable law or agreed to in writing, this software
+ 15 + + // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ 16 + + // KIND, either express or implied.
+ 17 + +
+ 18 + + /*
+ 19 + + This is a derivative work
+ 20 + + */
+ 21 + +
+ 22 + + #ifndef BOOST_JSON_DETAIL_RYU_DETAIL_DIGIT_TABLE_HPP
+ 23 + + #define BOOST_JSON_DETAIL_RYU_DETAIL_DIGIT_TABLE_HPP
+ 24 + +
+ 25 + + #include <boost/json/detail/config.hpp>
+ 26 + +
+ 27 + + namespace boost {
+ 28 + + namespace json {
+ 29 + + namespace detail {
+ 30 + +
+ 31 + + namespace ryu {
+ 32 + + namespace detail {
+ 33 + +
+ 34 + + // A table of all two-digit numbers. This is used to speed up decimal digit
+ 35 + + // generation by copying pairs of digits into the final output.
+ 36 + + inline
+ 37 + + char const
+ 38 + +842 (&DIGIT_TABLE() noexcept)[200]
+ 39 + + {
+ 40 + + static constexpr char arr[200] = {
+ 41 + + '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
+ 42 + + '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
+ 43 + + '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
+ 44 + + '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',
+ 45 + + '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',
+ 46 + + '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',
+ 47 + + '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',
+ 48 + + '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',
+ 49 + + '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',
+ 50 + + '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' };
+ 51 + +842 return arr;
+ 52 + + }
+ 53 + +
+ 54 + + } // detail
+ 55 + + } // ryu
+ 56 + +
+ 57 + + } // detail
+ 58 + + } // namespace json
+ 59 + + } // namespace boost
+ 60 + +
+ 61 + + #endif
+ 62 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.emulated128.hpp.0ceaaed8d203e80b297f0b1456573326.html b/json/gcovr/index.emulated128.hpp.0ceaaed8d203e80b297f0b1456573326.html new file mode 100644 index 00000000..65a14e77 --- /dev/null +++ b/json/gcovr/index.emulated128.hpp.0ceaaed8d203e80b297f0b1456573326.html @@ -0,0 +1,3638 @@ + + + + + + detail/charconv/detail/emulated128.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/emulated128.hpp

+
+ + 0.0% Lines (0/3) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/emulated128.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2020-2023 Daniel Lemire
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + +
+ 6 + + // If the architecture (e.g. ARM) does not have __int128 we need to emulate it
+ 7 + +
+ 8 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_EMULATED128_HPP
+ 9 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_EMULATED128_HPP
+ 10 + +
+ 11 + + #include <boost/json/detail/charconv/detail/config.hpp>
+ 12 + + #include <cstdint>
+ 13 + + #include <cassert>
+ 14 + +
+ 15 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail {
+ 16 + +
+ 17 + + // Compilers might support built-in 128-bit integer types. However, it seems that
+ 18 + + // emulating them with a pair of 64-bit integers actually produces a better code,
+ 19 + + // so we avoid using those built-ins. That said, they are still useful for
+ 20 + + // implementing 64-bit x 64-bit -> 128-bit multiplication.
+ 21 + +
+ 22 + + struct uint128
+ 23 + + {
+ 24 + + std::uint64_t high;
+ 25 + + std::uint64_t low;
+ 26 + +
+ 27 + + uint128& operator+=(std::uint64_t n) & noexcept
+ 28 + + {
+ 29 + + #if BOOST_JSON_HAS_BUILTIN(__builtin_addcll)
+ 30 + +
+ 31 + + unsigned long long carry;
+ 32 + + low = __builtin_addcll(low, n, 0, &carry);
+ 33 + + high = __builtin_addcll(high, 0, carry, &carry);
+ 34 + +
+ 35 + + #elif BOOST_JSON_HAS_BUILTIN(__builtin_ia32_addcarryx_u64)
+ 36 + +
+ 37 + + unsigned long long result;
+ 38 + + auto carry = __builtin_ia32_addcarryx_u64(0, low, n, &result);
+ 39 + + low = result;
+ 40 + + __builtin_ia32_addcarryx_u64(carry, high, 0, &result);
+ 41 + + high = result;
+ 42 + +
+ 43 + + #elif defined(BOOST_MSVC) && defined(_M_X64)
+ 44 + +
+ 45 + + auto carry = _addcarry_u64(0, low, n, &low);
+ 46 + + _addcarry_u64(carry, high, 0, &high);
+ 47 + +
+ 48 + + #else
+ 49 + +
+ 50 + + auto sum = low + n;
+ 51 + + high += (sum < low ? 1 : 0);
+ 52 + + low = sum;
+ 53 + +
+ 54 + + #endif
+ 55 + + return *this;
+ 56 + + }
+ 57 + + };
+ 58 + +
+ 59 + + static inline std::uint64_t umul64(std::uint32_t x, std::uint32_t y) noexcept
+ 60 + + {
+ 61 + + #if defined(BOOST_JSON_HAS_MSVC_32BIT_INTRINSICS) && !defined(_M_ARM)
+ 62 + +
+ 63 + + return __emulu(x, y);
+ 64 + +
+ 65 + + #else
+ 66 + +
+ 67 + + return x * static_cast<std::uint64_t>(y);
+ 68 + +
+ 69 + + #endif
+ 70 + + }
+ 71 + +
+ 72 + + // Get 128-bit result of multiplication of two 64-bit unsigned integers.
+ 73 + + BOOST_JSON_SAFEBUFFERS inline uint128 umul128(std::uint64_t x, std::uint64_t y) noexcept
+ 74 + + {
+ 75 + + #if defined(BOOST_HAS_INT128)
+ 76 + +
+ 77 + + auto result = static_cast<boost::uint128_type>(x) * static_cast<boost::uint128_type>(y);
+ 78 + + return {static_cast<std::uint64_t>(result >> 64), static_cast<std::uint64_t>(result)};
+ 79 + +
+ 80 + + #elif defined(BOOST_JSON_HAS_MSVC_64BIT_INTRINSICS) && !defined(_M_ARM64)
+ 81 + +
+ 82 + + std::uint64_t high;
+ 83 + + std::uint64_t low = _umul128(x, y, &high);
+ 84 + + return {high, low};
+ 85 + +
+ 86 + + // https://developer.arm.com/documentation/dui0802/a/A64-General-Instructions/UMULH
+ 87 + + #elif defined(_M_ARM64) && !defined(__MINGW32__)
+ 88 + +
+ 89 + + std::uint64_t high = __umulh(x, y);
+ 90 + + std::uint64_t low = x * y;
+ 91 + + return {high, low};
+ 92 + +
+ 93 + + #else
+ 94 + +
+ 95 + + auto a = static_cast<std::uint32_t>(x >> 32);
+ 96 + + auto b = static_cast<std::uint32_t>(x);
+ 97 + + auto c = static_cast<std::uint32_t>(y >> 32);
+ 98 + + auto d = static_cast<std::uint32_t>(y);
+ 99 + +
+ 100 + + auto ac = umul64(a, c);
+ 101 + + auto bc = umul64(b, c);
+ 102 + + auto ad = umul64(a, d);
+ 103 + + auto bd = umul64(b, d);
+ 104 + +
+ 105 + + auto intermediate = (bd >> 32) + static_cast<std::uint32_t>(ad) + static_cast<std::uint32_t>(bc);
+ 106 + +
+ 107 + + return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
+ 108 + + (intermediate << 32) + static_cast<std::uint32_t>(bd)};
+ 109 + +
+ 110 + + #endif
+ 111 + + }
+ 112 + +
+ 113 + + BOOST_JSON_SAFEBUFFERS inline std::uint64_t umul128_upper64(std::uint64_t x, std::uint64_t y) noexcept
+ 114 + + {
+ 115 + + #if defined(BOOST_HAS_INT128)
+ 116 + +
+ 117 + + auto result = static_cast<boost::uint128_type>(x) * static_cast<boost::uint128_type>(y);
+ 118 + + return static_cast<std::uint64_t>(result >> 64);
+ 119 + +
+ 120 + + #elif defined(BOOST_JSON_HAS_MSVC_64BIT_INTRINSICS)
+ 121 + +
+ 122 + + return __umulh(x, y);
+ 123 + +
+ 124 + + #else
+ 125 + +
+ 126 + + auto a = static_cast<std::uint32_t>(x >> 32);
+ 127 + + auto b = static_cast<std::uint32_t>(x);
+ 128 + + auto c = static_cast<std::uint32_t>(y >> 32);
+ 129 + + auto d = static_cast<std::uint32_t>(y);
+ 130 + +
+ 131 + + auto ac = umul64(a, c);
+ 132 + + auto bc = umul64(b, c);
+ 133 + + auto ad = umul64(a, d);
+ 134 + + auto bd = umul64(b, d);
+ 135 + +
+ 136 + + auto intermediate = (bd >> 32) + static_cast<std::uint32_t>(ad) + static_cast<std::uint32_t>(bc);
+ 137 + +
+ 138 + + return ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32);
+ 139 + +
+ 140 + + #endif
+ 141 + + }
+ 142 + +
+ 143 + + // Get upper 128-bits of multiplication of a 64-bit unsigned integer and a 128-bit
+ 144 + + // unsigned integer.
+ 145 + + BOOST_JSON_SAFEBUFFERS inline uint128 umul192_upper128(std::uint64_t x, uint128 y) noexcept
+ 146 + + {
+ 147 + + auto r = umul128(x, y.high);
+ 148 + + r += umul128_upper64(x, y.low);
+ 149 + + return r;
+ 150 + + }
+ 151 + +
+ 152 + + // Get upper 64-bits of multiplication of a 32-bit unsigned integer and a 64-bit
+ 153 + + // unsigned integer.
+ 154 + + inline std::uint64_t umul96_upper64(std::uint32_t x, std::uint64_t y) noexcept
+ 155 + + {
+ 156 + + #if defined(BOOST_HAS_INT128) || defined(BOOST_JSON_HAS_MSVC_64BIT_INTRINSICS)
+ 157 + +
+ 158 + + return umul128_upper64(static_cast<std::uint64_t>(x) << 32, y);
+ 159 + +
+ 160 + + #else
+ 161 + +
+ 162 + + auto yh = static_cast<std::uint32_t>(y >> 32);
+ 163 + + auto yl = static_cast<std::uint32_t>(y);
+ 164 + +
+ 165 + + auto xyh = umul64(x, yh);
+ 166 + + auto xyl = umul64(x, yl);
+ 167 + +
+ 168 + + return xyh + (xyl >> 32);
+ 169 + +
+ 170 + + #endif
+ 171 + + }
+ 172 + +
+ 173 + + // Get lower 128-bits of multiplication of a 64-bit unsigned integer and a 128-bit
+ 174 + + // unsigned integer.
+ 175 + + BOOST_JSON_SAFEBUFFERS inline uint128 umul192_lower128(std::uint64_t x, uint128 y) noexcept
+ 176 + + {
+ 177 + + auto high = x * y.high;
+ 178 + + auto highlow = umul128(x, y.low);
+ 179 + + return {high + highlow.high, highlow.low};
+ 180 + + }
+ 181 + +
+ 182 + + // Get lower 64-bits of multiplication of a 32-bit unsigned integer and a 64-bit
+ 183 + + // unsigned integer.
+ 184 + + inline std::uint64_t umul96_lower64(std::uint32_t x, std::uint64_t y) noexcept
+ 185 + + {
+ 186 + + return x * y;
+ 187 + + }
+ 188 + +
+ 189 + + }}}}} // Namespaces
+ 190 + +
+ 191 + + #endif // BOOST_JSON_DETAIL_CHARCONV_DETAIL_EMULATED128_HPP
+ 192 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.error.hpp.561447e3b80e5107d88e9cf24f3b9513.html b/json/gcovr/index.error.hpp.561447e3b80e5107d88e9cf24f3b9513.html new file mode 100644 index 00000000..6ae19fee --- /dev/null +++ b/json/gcovr/index.error.hpp.561447e3b80e5107d88e9cf24f3b9513.html @@ -0,0 +1,3134 @@ + + + + + + impl/error.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/error.hpp

+
+ + 100.0% Lines (5/5) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/error.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_ERROR_HPP
+ 11 + + #define BOOST_JSON_IMPL_ERROR_HPP
+ 12 + +
+ 13 + + #include <boost/system/error_category.hpp>
+ 14 + + #include <type_traits>
+ 15 + +
+ 16 + + namespace boost {
+ 17 + + namespace system {
+ 18 + + template<>
+ 19 + + struct is_error_code_enum< ::boost::json::error >
+ 20 + + {
+ 21 + + static bool const value = true;
+ 22 + + };
+ 23 + + template<>
+ 24 + + struct is_error_condition_enum< ::boost::json::condition >
+ 25 + + {
+ 26 + + static bool const value = true;
+ 27 + + };
+ 28 + + } // system
+ 29 + + } // boost
+ 30 + +
+ 31 + + namespace std {
+ 32 + + template<>
+ 33 + + struct is_error_code_enum< ::boost::json::error >
+ 34 + + {
+ 35 + + static bool const value = true;
+ 36 + + };
+ 37 + + template<>
+ 38 + + struct is_error_condition_enum< ::boost::json::condition >
+ 39 + + {
+ 40 + + static bool const value = true;
+ 41 + + };
+ 42 + + } // std
+ 43 + +
+ 44 + + namespace boost {
+ 45 + + namespace json {
+ 46 + + namespace detail {
+ 47 + +
+ 48 + + struct error_code_category_t
+ 49 + + : system::error_category
+ 50 + + {
+ 51 + + constexpr
+ 52 + + error_code_category_t()
+ 53 + + : system::error_category(0xB9A9B9922177C772)
+ 54 + + {}
+ 55 + +
+ 56 + + BOOST_JSON_DECL
+ 57 + + const char*
+ 58 + + name() const noexcept override;
+ 59 + +
+ 60 + + BOOST_JSON_DECL
+ 61 + + char const*
+ 62 + + message( int ev, char* buf, std::size_t len ) const noexcept override;
+ 63 + +
+ 64 + + BOOST_JSON_DECL
+ 65 + + std::string
+ 66 + + message( int ev ) const override;
+ 67 + +
+ 68 + + BOOST_JSON_DECL
+ 69 + + system::error_condition
+ 70 + + default_error_condition( int ev ) const noexcept override;
+ 71 + + };
+ 72 + +
+ 73 + + extern
+ 74 + + BOOST_JSON_DECL
+ 75 + + error_code_category_t error_code_category;
+ 76 + +
+ 77 + + struct error_condition_category_t
+ 78 + + : system::error_category
+ 79 + + {
+ 80 + + constexpr
+ 81 + + error_condition_category_t()
+ 82 + + : system::error_category(0x37CEF5A036D24FD1)
+ 83 + + {}
+ 84 + +
+ 85 + + BOOST_JSON_DECL
+ 86 + + const char*
+ 87 + + name() const noexcept override;
+ 88 + +
+ 89 + + BOOST_JSON_DECL
+ 90 + + char const*
+ 91 + + message( int ev, char*, std::size_t ) const noexcept override;
+ 92 + +
+ 93 + + BOOST_JSON_DECL
+ 94 + + std::string
+ 95 + + message( int cv ) const override;
+ 96 + + };
+ 97 + +
+ 98 + + extern
+ 99 + + BOOST_JSON_DECL
+ 100 + + error_condition_category_t error_condition_category;
+ 101 + +
+ 102 + + } // namespace detail
+ 103 + +
+ 104 + + inline
+ 105 + + BOOST_SYSTEM_CONSTEXPR
+ 106 + + system::error_code
+ 107 + +105190 make_error_code(error e) noexcept
+ 108 + + {
+ 109 + +
+ 110 + + return system::error_code(
+ 111 + + static_cast<std::underlying_type<error>::type>(e),
+ 112 + +105190 detail::error_code_category );
+ 113 + + }
+ 114 + +
+ 115 + + inline
+ 116 + + BOOST_SYSTEM_CONSTEXPR
+ 117 + + system::error_condition
+ 118 + +154 make_error_condition(condition c) noexcept
+ 119 + + {
+ 120 + +154 return system::error_condition(
+ 121 + + static_cast<std::underlying_type<condition>::type>(c),
+ 122 + +154 detail::error_condition_category );
+ 123 + + }
+ 124 + +
+ 125 + + } // namespace json
+ 126 + + } // namespace boost
+ 127 + +
+ 128 + + #endif
+ 129 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.error.ipp.5ffd5dbb81ff10cef7db2ed5dff0c794.html b/json/gcovr/index.error.ipp.5ffd5dbb81ff10cef7db2ed5dff0c794.html new file mode 100644 index 00000000..53b6f5b2 --- /dev/null +++ b/json/gcovr/index.error.ipp.5ffd5dbb81ff10cef7db2ed5dff0c794.html @@ -0,0 +1,3630 @@ + + + + + + impl/error.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/error.ipp

+
+ + 100.0% Lines (74/74) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/error.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_ERROR_IPP
+ 11 + + #define BOOST_JSON_IMPL_ERROR_IPP
+ 12 + +
+ 13 + + #include <boost/json/error.hpp>
+ 14 + +
+ 15 + + namespace boost {
+ 16 + + namespace json {
+ 17 + + namespace detail {
+ 18 + +
+ 19 + + // msvc 14.0 has a bug that warns about inability to use constexpr
+ 20 + + // construction here, even though there's no constexpr construction
+ 21 + + #if defined(_MSC_VER) && _MSC_VER <= 1900
+ 22 + + # pragma warning( push )
+ 23 + + # pragma warning( disable : 4592 )
+ 24 + + #endif
+ 25 + + BOOST_JSON_CONSTINIT
+ 26 + + error_code_category_t error_code_category;
+ 27 + +
+ 28 + + BOOST_JSON_CONSTINIT
+ 29 + + error_condition_category_t error_condition_category;
+ 30 + + #if defined(_MSC_VER) && _MSC_VER <= 1900
+ 31 + + # pragma warning( pop )
+ 32 + + #endif
+ 33 + +
+ 34 + + char const*
+ 35 + +465 error_code_category_t::name() const noexcept
+ 36 + + {
+ 37 + +465 return "boost.json";
+ 38 + + }
+ 39 + +
+ 40 + + char const*
+ 41 + +465 error_code_category_t::message( int ev, char*, std::size_t ) const noexcept
+ 42 + + {
+ 43 + +465 switch(static_cast<error>(ev))
+ 44 + + {
+ 45 + +12 default:
+ 46 + +12 case error::syntax: return "syntax error";
+ 47 + +7 case error::extra_data: return "extra data";
+ 48 + +17 case error::incomplete: return "incomplete JSON";
+ 49 + +1 case error::exponent_overflow: return "exponent overflow";
+ 50 + +1 case error::too_deep: return "too deep";
+ 51 + +1 case error::illegal_leading_surrogate: return "illegal leading surrogate";
+ 52 + +1 case error::illegal_trailing_surrogate: return "illegal trailing surrogate";
+ 53 + +1 case error::expected_hex_digit: return "expected hex digit";
+ 54 + +1 case error::expected_utf16_escape: return "expected utf16 escape";
+ 55 + +10 case error::object_too_large: return "object too large";
+ 56 + +5 case error::array_too_large: return "array too large";
+ 57 + +2 case error::key_too_large: return "key too large";
+ 58 + +7 case error::string_too_large: return "string too large";
+ 59 + +2 case error::number_too_large: return "number too large";
+ 60 + +2 case error::input_error: return "input error";
+ 61 + +
+ 62 + +1 case error::exception: return "got exception";
+ 63 + +25 case error::out_of_range: return "out of range";
+ 64 + +1 case error::test_failure: return "test failure";
+ 65 + +
+ 66 + +4 case error::missing_slash: return "missing slash character";
+ 67 + +3 case error::invalid_escape: return "invalid escape sequence";
+ 68 + +5 case error::token_not_number: return "token is not a number";
+ 69 + +3 case error::value_is_scalar: return "current value is scalar";
+ 70 + +3 case error::not_found: return "no referenced value";
+ 71 + +1 case error::token_overflow: return "token overflow";
+ 72 + +1 case error::past_the_end: return "past-the-end token not supported";
+ 73 + +
+ 74 + +47 case error::not_number: return "not a number";
+ 75 + +63 case error::not_exact: return "not exact";
+ 76 + +20 case error::not_null: return "value is not null";
+ 77 + +22 case error::not_bool: return "value is not boolean";
+ 78 + +40 case error::not_array: return "value is not an array";
+ 79 + +34 case error::not_object: return "value is not an object";
+ 80 + +47 case error::not_string: return "value is not a string";
+ 81 + +15 case error::not_int64: return "value is not a std::int64_t number";
+ 82 + +15 case error::not_uint64: return "value is not a std::uint64_t number";
+ 83 + +15 case error::not_double: return "value is not a double";
+ 84 + +3 case error::not_integer: return "value is not integer";
+ 85 + +25 case error::size_mismatch: return "source composite size does not match target size";
+ 86 + +1 case error::exhausted_variants: return "exhausted all variants";
+ 87 + +1 case error::unknown_name: return "unknown name";
+ 88 + + }
+ 89 + + }
+ 90 + +
+ 91 + + std::string
+ 92 + +465 error_code_category_t::message( int ev ) const
+ 93 + + {
+ 94 + +930 return message( ev, nullptr, 0 );
+ 95 + + }
+ 96 + +
+ 97 + + system::error_condition
+ 98 + +40 error_code_category_t::default_error_condition( int ev) const noexcept
+ 99 + + {
+ 100 + +40 switch(static_cast<error>(ev))
+ 101 + + {
+ 102 + +1 default:
+ 103 + +1 return {ev, *this};
+ 104 + +
+ 105 + +16 case error::syntax:
+ 106 + + case error::extra_data:
+ 107 + + case error::incomplete:
+ 108 + + case error::exponent_overflow:
+ 109 + + case error::too_deep:
+ 110 + + case error::illegal_leading_surrogate:
+ 111 + + case error::illegal_trailing_surrogate:
+ 112 + + case error::expected_hex_digit:
+ 113 + + case error::expected_utf16_escape:
+ 114 + + case error::object_too_large:
+ 115 + + case error::array_too_large:
+ 116 + + case error::key_too_large:
+ 117 + + case error::string_too_large:
+ 118 + + case error::number_too_large:
+ 119 + + case error::input_error:
+ 120 + +16 return condition::parse_error;
+ 121 + +
+ 122 + +2 case error::missing_slash:
+ 123 + + case error::invalid_escape:
+ 124 + +2 return condition::pointer_parse_error;
+ 125 + +
+ 126 + +5 case error::token_not_number:
+ 127 + + case error::value_is_scalar:
+ 128 + + case error::not_found:
+ 129 + + case error::token_overflow:
+ 130 + + case error::past_the_end:
+ 131 + +5 return condition::pointer_use_error;
+ 132 + +
+ 133 + +14 case error::not_number:
+ 134 + + case error::not_exact:
+ 135 + + case error::not_null:
+ 136 + + case error::not_bool:
+ 137 + + case error::not_array:
+ 138 + + case error::not_object:
+ 139 + + case error::not_string:
+ 140 + + case error::not_int64:
+ 141 + + case error::not_uint64:
+ 142 + + case error::not_double:
+ 143 + + case error::not_integer:
+ 144 + + case error::size_mismatch:
+ 145 + + case error::exhausted_variants:
+ 146 + + case error::unknown_name:
+ 147 + +14 return condition::conversion_error;
+ 148 + +
+ 149 + +2 case error::exception:
+ 150 + + case error::out_of_range:
+ 151 + +2 return condition::generic_error;
+ 152 + + }
+ 153 + + }
+ 154 + +
+ 155 + + char const*
+ 156 + +38 error_condition_category_t::name() const noexcept
+ 157 + + {
+ 158 + +38 return "boost.json";
+ 159 + + }
+ 160 + +
+ 161 + + char const*
+ 162 + +38 error_condition_category_t::message( int cv, char*, std::size_t ) const noexcept
+ 163 + + {
+ 164 + +38 switch(static_cast<condition>(cv))
+ 165 + + {
+ 166 + +17 default:
+ 167 + + case condition::parse_error:
+ 168 + +17 return "A JSON parse error occurred";
+ 169 + +2 case condition::pointer_parse_error:
+ 170 + +2 return "A JSON Pointer parse error occurred";
+ 171 + +5 case condition::pointer_use_error:
+ 172 + + return "An error occurred when JSON Pointer was used with"
+ 173 + +5 " a value";
+ 174 + +14 case condition::conversion_error:
+ 175 + +14 return "An error occurred during conversion";
+ 176 + + }
+ 177 + + }
+ 178 + +
+ 179 + + std::string
+ 180 + +38 error_condition_category_t::message( int cv ) const
+ 181 + + {
+ 182 + +76 return message( cv, nullptr, 0 );
+ 183 + + }
+ 184 + +
+ 185 + + } // namespace detail
+ 186 + +
+ 187 + + } // namespace json
+ 188 + + } // namespace boost
+ 189 + +
+ 190 + + #endif
+ 191 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.except.ipp.12c9aef5d4d66299103ac6024ed0063f.html b/json/gcovr/index.except.ipp.12c9aef5d4d66299103ac6024ed0063f.html new file mode 100644 index 00000000..e7e76429 --- /dev/null +++ b/json/gcovr/index.except.ipp.12c9aef5d4d66299103ac6024ed0063f.html @@ -0,0 +1,2510 @@ + + + + + + detail/impl/except.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/impl/except.ipp

+
+ + 100.0% Lines (8/8) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/impl/except.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_IMPL_EXCEPT_IPP
+ 11 + + #define BOOST_JSON_DETAIL_IMPL_EXCEPT_IPP
+ 12 + +
+ 13 + + #include <boost/json/detail/except.hpp>
+ 14 + + #include <boost/version.hpp>
+ 15 + + #include <boost/throw_exception.hpp>
+ 16 + + #include <stdexcept>
+ 17 + +
+ 18 + + namespace boost {
+ 19 + + namespace json {
+ 20 + +
+ 21 + + namespace detail {
+ 22 + +
+ 23 + + void
+ 24 + +42 throw_system_error(
+ 25 + + system::error_code const& ec,
+ 26 + + source_location const& loc)
+ 27 + + {
+ 28 + +42 throw_exception(
+ 29 + +84 system::system_error(ec),
+ 30 + + loc);
+ 31 + + }
+ 32 + +
+ 33 + + void
+ 34 + +27 throw_system_error(
+ 35 + + error e,
+ 36 + + source_location const* loc)
+ 37 + + {
+ 38 + +27 system::error_code ec;
+ 39 + +27 ec.assign(e, loc);
+ 40 + +
+ 41 + +27 throw_exception(
+ 42 + +81 system::system_error(ec),
+ 43 + + *loc);
+ 44 + + }
+ 45 + +
+ 46 + + } // detail
+ 47 + + } // namespace json
+ 48 + + } // namespace boost
+ 49 + +
+ 50 + + #endif
+ 51 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.fast_float.eccdc16b8d3a6677c41246e350f1ee5c.html b/json/gcovr/index.fast_float.eccdc16b8d3a6677c41246e350f1ee5c.html new file mode 100644 index 00000000..32aed69e --- /dev/null +++ b/json/gcovr/index.fast_float.eccdc16b8d3a6677c41246e350f1ee5c.html @@ -0,0 +1,2332 @@ + + + + + + detail/charconv/detail/fast_float/ - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+
+

Lines

+
+
+
+ + + + + 93.3% +
+
+
+ Hit + 8225 +
+
+ Total + 8811 +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+
+ +
+ High: ≥ 90.0% + Medium: ≥ 75.0% + Low: < 75.0% +
+ +
+
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+
+ +
+
+ +
+ + + + ascii_number.hpp +
+ +
+
+
+
+ 88.0% +
+ +
+ 95 + / + 108 +
+ + +
+
+ +
+ + + + bigint.hpp +
+ +
+
+
+
+ 89.9% +
+ +
+ 213 + / + 237 +
+ + +
+
+ + + +
+
+
+
+ 94.7% +
+ +
+ 54 + / + 57 +
+ + +
+
+ + + +
+
+
+
+ 76.9% +
+ +
+ 143 + / + 186 +
+ + +
+
+ +
+ + + + float_common.hpp +
+ +
+
+
+
+ 62.7% +
+ +
+ 52 + / + 83 +
+ + +
+
+ +
+ + + + parse_number.hpp +
+ +
+
+
+
+ 42.9% +
+ +
+ 27 + / + 63 +
+ + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.float_common.hpp.60c7bd470abb6c3589089cc294f360d4.html b/json/gcovr/index.float_common.hpp.60c7bd470abb6c3589089cc294f360d4.html new file mode 100644 index 00000000..f6757d93 --- /dev/null +++ b/json/gcovr/index.float_common.hpp.60c7bd470abb6c3589089cc294f360d4.html @@ -0,0 +1,6614 @@ + + + + + + detail/charconv/detail/fast_float/float_common.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/fast_float/float_common.hpp

+
+ + 62.7% Lines (52/83) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/fast_float/float_common.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2020-2023 Daniel Lemire
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + + //
+ 6 + + // Derivative of: https://github.com/fastfloat/fast_float
+ 7 + +
+ 8 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_FLOAT_COMMON_HPP
+ 9 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_FLOAT_COMMON_HPP
+ 10 + +
+ 11 + + #include <boost/json/detail/charconv/detail/fast_float/constexpr_feature_detect.hpp>
+ 12 + + #include <boost/json/detail/charconv/detail/from_chars_result.hpp>
+ 13 + + #include <boost/json/detail/charconv/detail/config.hpp>
+ 14 + + #include <boost/json/detail/charconv/chars_format.hpp>
+ 15 + + #include <cfloat>
+ 16 + + #include <cstdint>
+ 17 + + #include <cassert>
+ 18 + + #include <cstring>
+ 19 + + #include <type_traits>
+ 20 + + #include <system_error>
+ 21 + +
+ 22 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float {
+ 23 + +
+ 24 + +
+ 25 + + template <typename UC>
+ 26 + + struct parse_options_t {
+ 27 + +1009310 constexpr explicit parse_options_t(chars_format fmt = chars_format::general,
+ 28 + + UC dot = UC('.'))
+ 29 + +1009310 : format(fmt), decimal_point(dot) {}
+ 30 + +
+ 31 + + /** Which number formats are accepted */
+ 32 + + chars_format format;
+ 33 + + /** The character used as decimal point */
+ 34 + + UC decimal_point;
+ 35 + + };
+ 36 + + using parse_options = parse_options_t<char>;
+ 37 + +
+ 38 + + }}}}}}
+ 39 + +
+ 40 + + #ifdef BOOST_JSON_HAS_BIT_CAST
+ 41 + + #include <bit>
+ 42 + + #endif
+ 43 + +
+ 44 + + #if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \
+ 45 + + || defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \
+ 46 + + || defined(__MINGW64__) \
+ 47 + + || defined(__s390x__) \
+ 48 + + || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) )
+ 49 + + #define BOOST_JSON_FASTFLOAT_64BIT 1
+ 50 + + #elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) \
+ 51 + + || defined(__arm__) || defined(_M_ARM) || defined(__ppc__) \
+ 52 + + || defined(__MINGW32__) || defined(__EMSCRIPTEN__))
+ 53 + + #define BOOST_JSON_FASTFLOAT_32BIT 1
+ 54 + + #else
+ 55 + + // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow.
+ 56 + + // We can never tell the register width, but the SIZE_MAX is a good approximation.
+ 57 + + // UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max portability.
+ 58 + + #if SIZE_MAX == 0xffff
+ 59 + + #error Unknown platform (16-bit, unsupported)
+ 60 + + #elif SIZE_MAX == 0xffffffff
+ 61 + + #define BOOST_JSON_FASTFLOAT_32BIT 1
+ 62 + + #elif SIZE_MAX == 0xffffffffffffffff
+ 63 + + #define BOOST_JSON_FASTFLOAT_64BIT 1
+ 64 + + #else
+ 65 + + #error Unknown platform (not 32-bit, not 64-bit?)
+ 66 + + #endif
+ 67 + + #endif
+ 68 + +
+ 69 + + #if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__))
+ 70 + + #include <intrin.h>
+ 71 + + #endif
+ 72 + +
+ 73 + + #if defined(_MSC_VER) && !defined(__clang__)
+ 74 + + #define BOOST_JSON_FASTFLOAT_VISUAL_STUDIO 1
+ 75 + + #endif
+ 76 + +
+ 77 + + // rust style `try!()` macro, or `?` operator
+ 78 + + #define BOOST_JSON_FASTFLOAT_TRY(x) { if (!(x)) return false; }
+ 79 + +
+ 80 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float {
+ 81 + +
+ 82 + + BOOST_FORCEINLINE constexpr bool cpp20_and_in_constexpr() {
+ 83 + + #ifdef BOOST_JSON_HAS_IS_CONSTANT_EVALUATED
+ 84 + + return std::is_constant_evaluated();
+ 85 + + #else
+ 86 + +8902634 return false;
+ 87 + + #endif
+ 88 + + }
+ 89 + +
+ 90 + + // Compares two ASCII strings in a case insensitive manner.
+ 91 + + template <typename UC>
+ 92 + + inline BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE bool
+ 93 + + fastfloat_strncasecmp(UC const * input1, UC const * input2, size_t length) {
+ 94 + + char running_diff{0};
+ 95 + + for (size_t i = 0; i < length; ++i) {
+ 96 + + running_diff |= (char(input1[i]) ^ char(input2[i]));
+ 97 + + }
+ 98 + + return (running_diff == 0) || (running_diff == 32);
+ 99 + + }
+ 100 + +
+ 101 + + #ifndef FLT_EVAL_METHOD
+ 102 + + #error "FLT_EVAL_METHOD should be defined, please include cfloat."
+ 103 + + #endif
+ 104 + +
+ 105 + + // a pointer and a length to a contiguous block of memory
+ 106 + + template <typename T>
+ 107 + + struct span {
+ 108 + + const T* ptr;
+ 109 + + size_t length;
+ 110 + +2028274 constexpr span(const T* _ptr, size_t _length) : ptr(_ptr), length(_length) {}
+ 111 + + constexpr span() : ptr(nullptr), length(0) {}
+ 112 + +
+ 113 + +1155768 constexpr size_t len() const noexcept {
+ 114 + +1155768 return length;
+ 115 + + }
+ 116 + +
+ 117 + +36365 BOOST_JSON_CXX14_CONSTEXPR const T& operator[](size_t index) const noexcept {
+ 118 + +36365 BOOST_ASSERT(index < length);
+ 119 + +36365 return ptr[index];
+ 120 + + }
+ 121 + + };
+ 122 + +
+ 123 + + struct value128 {
+ 124 + + uint64_t low;
+ 125 + + uint64_t high;
+ 126 + + constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {}
+ 127 + + constexpr value128() : low(0), high(0) {}
+ 128 + + };
+ 129 + +
+ 130 + + /* Helper C++11 constexpr generic implementation of leading_zeroes */
+ 131 + + BOOST_FORCEINLINE constexpr
+ 132 + + int leading_zeroes_generic(uint64_t input_num, int last_bit = 0) {
+ 133 + + return (
+ 134 + + ((input_num & uint64_t(0xffffffff00000000)) && (input_num >>= 32, last_bit |= 32)),
+ 135 + + ((input_num & uint64_t( 0xffff0000)) && (input_num >>= 16, last_bit |= 16)),
+ 136 + + ((input_num & uint64_t( 0xff00)) && (input_num >>= 8, last_bit |= 8)),
+ 137 + + ((input_num & uint64_t( 0xf0)) && (input_num >>= 4, last_bit |= 4)),
+ 138 + + ((input_num & uint64_t( 0xc)) && (input_num >>= 2, last_bit |= 2)),
+ 139 + + ((input_num & uint64_t( 0x2)) && (input_num >>= 1, last_bit |= 1)),
+ 140 + + 63 - last_bit
+ 141 + + );
+ 142 + + }
+ 143 + +
+ 144 + + /* result might be undefined when input_num is zero */
+ 145 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 146 + + int leading_zeroes(uint64_t input_num) {
+ 147 + +2008629 assert(input_num > 0);
+ 148 + +2008629 if (cpp20_and_in_constexpr()) {
+ 149 + + return leading_zeroes_generic(input_num);
+ 150 + + }
+ 151 + + #ifdef BOOST_JSON_FASTFLOAT_VISUAL_STUDIO
+ 152 + + #if defined(_M_X64) || defined(_M_ARM64)
+ 153 + + unsigned long leading_zero = 0;
+ 154 + + // Search the mask data from most significant bit (MSB)
+ 155 + + // to least significant bit (LSB) for a set bit (1).
+ 156 + + _BitScanReverse64(&leading_zero, input_num);
+ 157 + + return (int)(63 - leading_zero);
+ 158 + + #else
+ 159 + + return leading_zeroes_generic(input_num);
+ 160 + + #endif
+ 161 + + #else
+ 162 + +2008629 return __builtin_clzll(input_num);
+ 163 + + #endif
+ 164 + + }
+ 165 + +
+ 166 + + // slow emulation routine for 32-bit
+ 167 + + BOOST_FORCEINLINE constexpr uint64_t emulu(uint32_t x, uint32_t y) {
+ 168 + + return x * (uint64_t)y;
+ 169 + + }
+ 170 + +
+ 171 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 172 + + uint64_t umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) {
+ 173 + + uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd);
+ 174 + + uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd);
+ 175 + + uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32));
+ 176 + + uint64_t adbc_carry = !!(adbc < ad);
+ 177 + + uint64_t lo = bd + (adbc << 32);
+ 178 + + *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) +
+ 179 + + (adbc_carry << 32) + !!(lo < bd);
+ 180 + + return lo;
+ 181 + + }
+ 182 + +
+ 183 + + #ifdef BOOST_JSON_FASTFLOAT_32BIT
+ 184 + +
+ 185 + + // slow emulation routine for 32-bit
+ 186 + + #if !defined(__MINGW64__)
+ 187 + + BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
+ 188 + + uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
+ 189 + + return umul128_generic(ab, cd, hi);
+ 190 + + }
+ 191 + + #endif // !__MINGW64__
+ 192 + +
+ 193 + + #endif // BOOST_JSON_FASTFLOAT_32BIT
+ 194 + +
+ 195 + +
+ 196 + + // compute 64-bit a*b
+ 197 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 198 + + value128 full_multiplication(uint64_t a, uint64_t b) {
+ 199 + +2010874 if (cpp20_and_in_constexpr()) {
+ 200 + + value128 answer;
+ 201 + + answer.low = umul128_generic(a, b, &answer.high);
+ 202 + + return answer;
+ 203 + + }
+ 204 + +2010874 value128 answer;
+ 205 + + #if defined(_M_ARM64) && !defined(__MINGW32__)
+ 206 + + // ARM64 has native support for 64-bit multiplications, no need to emulate
+ 207 + + // But MinGW on ARM64 doesn't have native support for 64-bit multiplications
+ 208 + + answer.high = __umulh(a, b);
+ 209 + + answer.low = a * b;
+ 210 + + #elif defined(BOOST_JSON_FASTFLOAT_32BIT) || \
+ 211 + + (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64))
+ 212 + + unsigned long long high;
+ 213 + + answer.low = _umul128(a, b, &high); // _umul128 not available on ARM64
+ 214 + + answer.high = static_cast<uint64_t>(high);
+ 215 + + #elif defined(BOOST_JSON_FASTFLOAT_64BIT)
+ 216 + +2010874 __uint128_t r = ((__uint128_t)a) * b;
+ 217 + +2010874 answer.low = uint64_t(r);
+ 218 + +2010874 answer.high = uint64_t(r >> 64);
+ 219 + + #else
+ 220 + + answer.low = umul128_generic(a, b, &answer.high);
+ 221 + + #endif
+ 222 + +2010874 return answer;
+ 223 + + }
+ 224 + +
+ 225 + + struct adjusted_mantissa {
+ 226 + + uint64_t mantissa{0};
+ 227 + + int32_t power2{0}; // a negative value indicates an invalid result
+ 228 + + adjusted_mantissa() = default;
+ 229 + + constexpr bool operator==(const adjusted_mantissa &o) const {
+ 230 + + return mantissa == o.mantissa && power2 == o.power2;
+ 231 + + }
+ 232 + +1000712 constexpr bool operator!=(const adjusted_mantissa &o) const {
+ 233 + +1000712 return mantissa != o.mantissa || power2 != o.power2;
+ 234 + + }
+ 235 + + };
+ 236 + +
+ 237 + + // Bias so we can get the real exponent with an invalid adjusted_mantissa.
+ 238 + + constexpr static int32_t invalid_am_bias = -0x8000;
+ 239 + +
+ 240 + + // used for binary_format_lookup_tables<T>::max_mantissa
+ 241 + + constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
+ 242 + +
+ 243 + + template <typename T, typename U = void>
+ 244 + + struct binary_format_lookup_tables;
+ 245 + +
+ 246 + + template <typename T> struct binary_format : binary_format_lookup_tables<T> {
+ 247 + + using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
+ 248 + +
+ 249 + + static inline constexpr int mantissa_explicit_bits();
+ 250 + + static inline constexpr int minimum_exponent();
+ 251 + + static inline constexpr int infinite_power();
+ 252 + + static inline constexpr int sign_index();
+ 253 + + static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
+ 254 + + static inline constexpr int max_exponent_fast_path();
+ 255 + + static inline constexpr int max_exponent_round_to_even();
+ 256 + + static inline constexpr int min_exponent_round_to_even();
+ 257 + + static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
+ 258 + + static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
+ 259 + + static inline constexpr int largest_power_of_ten();
+ 260 + + static inline constexpr int smallest_power_of_ten();
+ 261 + + static inline constexpr T exact_power_of_ten(int64_t power);
+ 262 + + static inline constexpr size_t max_digits();
+ 263 + + static inline constexpr equiv_uint exponent_mask();
+ 264 + + static inline constexpr equiv_uint mantissa_mask();
+ 265 + + static inline constexpr equiv_uint hidden_bit_mask();
+ 266 + + };
+ 267 + +
+ 268 + + template <typename U>
+ 269 + + struct binary_format_lookup_tables<double, U> {
+ 270 + + static constexpr double powers_of_ten[] = {
+ 271 + + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
+ 272 + + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
+ 273 + +
+ 274 + + // Largest integer value v so that (5**index * v) <= 1<<53.
+ 275 + + // 0x10000000000000 == 1 << 53
+ 276 + + static constexpr std::uint64_t max_mantissa[] = {
+ 277 + + UINT64_C(0x10000000000000),
+ 278 + + UINT64_C(0x10000000000000) / UINT64_C(5),
+ 279 + + UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5)),
+ 280 + + UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 281 + + UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 282 + + UINT64_C(0x10000000000000) / (constant_55555),
+ 283 + + UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5)),
+ 284 + + UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
+ 285 + + UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 286 + + UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 287 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555),
+ 288 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5)),
+ 289 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
+ 290 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 291 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555),
+ 292 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
+ 293 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
+ 294 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 295 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 296 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555),
+ 297 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
+ 298 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
+ 299 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 300 + + UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5))};
+ 301 + + };
+ 302 + +
+ 303 + + template <typename U>
+ 304 + + constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[];
+ 305 + +
+ 306 + + template <typename U>
+ 307 + + constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[];
+ 308 + +
+ 309 + + template <typename U>
+ 310 + + struct binary_format_lookup_tables<float, U> {
+ 311 + + static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
+ 312 + + 1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
+ 313 + +
+ 314 + + // Largest integer value v so that (5**index * v) <= 1<<24.
+ 315 + + // 0x1000000 == 1<<24
+ 316 + + static constexpr uint64_t max_mantissa[] = {
+ 317 + + UINT64_C(0x1000000),
+ 318 + + UINT64_C(0x1000000) / UINT64_C(5),
+ 319 + + UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5)),
+ 320 + + UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 321 + + UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 322 + + UINT64_C(0x1000000) / (constant_55555),
+ 323 + + UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5)),
+ 324 + + UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
+ 325 + + UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 326 + + UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
+ 327 + + UINT64_C(0x1000000) / (constant_55555 * constant_55555),
+ 328 + + UINT64_C(0x1000000) / (constant_55555 * constant_55555 * UINT64_C(5))};
+ 329 + + };
+ 330 + +
+ 331 + + template <typename U>
+ 332 + + constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[];
+ 333 + +
+ 334 + + template <typename U>
+ 335 + + constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[];
+ 336 + +
+ 337 + +1009310 template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
+ 338 + + #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
+ 339 + + return 0;
+ 340 + + #else
+ 341 + +1009310 return -22;
+ 342 + + #endif
+ 343 + + }
+ 344 + +
+ 345 + + template <> inline constexpr int binary_format<float>::min_exponent_fast_path() {
+ 346 + + #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
+ 347 + + return 0;
+ 348 + + #else
+ 349 + + return -10;
+ 350 + + #endif
+ 351 + + }
+ 352 + +
+ 353 + +7032865 template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() {
+ 354 + +7032865 return 52;
+ 355 + + }
+ 356 + + template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() {
+ 357 + + return 23;
+ 358 + + }
+ 359 + +
+ 360 + +8893 template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() {
+ 361 + +8893 return 23;
+ 362 + + }
+ 363 + +
+ 364 + + template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() {
+ 365 + + return 10;
+ 366 + + }
+ 367 + +
+ 368 + +9255 template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() {
+ 369 + +9255 return -4;
+ 370 + + }
+ 371 + +
+ 372 + + template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() {
+ 373 + + return -17;
+ 374 + + }
+ 375 + +
+ 376 + +2002893 template <> inline constexpr int binary_format<double>::minimum_exponent() {
+ 377 + +2002893 return -1023;
+ 378 + + }
+ 379 + + template <> inline constexpr int binary_format<float>::minimum_exponent() {
+ 380 + + return -127;
+ 381 + + }
+ 382 + +
+ 383 + +3072364 template <> inline constexpr int binary_format<double>::infinite_power() {
+ 384 + +3072364 return 0x7FF;
+ 385 + + }
+ 386 + + template <> inline constexpr int binary_format<float>::infinite_power() {
+ 387 + + return 0xFF;
+ 388 + + }
+ 389 + +
+ 390 + +1005351 template <> inline constexpr int binary_format<double>::sign_index() { return 63; }
+ 391 + + template <> inline constexpr int binary_format<float>::sign_index() { return 31; }
+ 392 + +
+ 393 + +546058 template <> inline constexpr int binary_format<double>::max_exponent_fast_path() {
+ 394 + +546058 return 22;
+ 395 + + }
+ 396 + + template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
+ 397 + + return 10;
+ 398 + + }
+ 399 + +
+ 400 + +5895 template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
+ 401 + +5895 return uint64_t(2) << mantissa_explicit_bits();
+ 402 + + }
+ 403 + + template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) {
+ 404 + + // caller is responsible to ensure that
+ 405 + + // power >= 0 && power <= 22
+ 406 + + //
+ 407 + + // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ 408 + + return (void)max_mantissa[0], max_mantissa[power];
+ 409 + + }
+ 410 + + template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
+ 411 + + return uint64_t(2) << mantissa_explicit_bits();
+ 412 + + }
+ 413 + + template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) {
+ 414 + + // caller is responsible to ensure that
+ 415 + + // power >= 0 && power <= 10
+ 416 + + //
+ 417 + + // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ 418 + + return (void)max_mantissa[0], max_mantissa[power];
+ 419 + + }
+ 420 + +
+ 421 + + template <>
+ 422 + +5570 inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
+ 423 + + // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ 424 + +5570 return (void)powers_of_ten[0], powers_of_ten[power];
+ 425 + + }
+ 426 + + template <>
+ 427 + + inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
+ 428 + + // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ 429 + + return (void)powers_of_ten[0], powers_of_ten[power];
+ 430 + + }
+ 431 + +
+ 432 + +
+ 433 + + template <>
+ 434 + +2004451 inline constexpr int binary_format<double>::largest_power_of_ten() {
+ 435 + +2004451 return 308;
+ 436 + + }
+ 437 + + template <>
+ 438 + + inline constexpr int binary_format<float>::largest_power_of_ten() {
+ 439 + + return 38;
+ 440 + + }
+ 441 + +
+ 442 + + template <>
+ 443 + +2004451 inline constexpr int binary_format<double>::smallest_power_of_ten() {
+ 444 + +2004451 return -342;
+ 445 + + }
+ 446 + + template <>
+ 447 + + inline constexpr int binary_format<float>::smallest_power_of_ten() {
+ 448 + + return -65;
+ 449 + + }
+ 450 + +
+ 451 + + template <> inline constexpr size_t binary_format<double>::max_digits() {
+ 452 + + return 769;
+ 453 + + }
+ 454 + + template <> inline constexpr size_t binary_format<float>::max_digits() {
+ 455 + + return 114;
+ 456 + + }
+ 457 + +
+ 458 + + template <> inline constexpr binary_format<float>::equiv_uint
+ 459 + + binary_format<float>::exponent_mask() {
+ 460 + + return 0x7F800000;
+ 461 + + }
+ 462 + + template <> inline constexpr binary_format<double>::equiv_uint
+ 463 + + binary_format<double>::exponent_mask() {
+ 464 + + return 0x7FF0000000000000;
+ 465 + + }
+ 466 + +
+ 467 + + template <> inline constexpr binary_format<float>::equiv_uint
+ 468 + + binary_format<float>::mantissa_mask() {
+ 469 + + return 0x007FFFFF;
+ 470 + + }
+ 471 + + template <> inline constexpr binary_format<double>::equiv_uint
+ 472 + + binary_format<double>::mantissa_mask() {
+ 473 + + return 0x000FFFFFFFFFFFFF;
+ 474 + + }
+ 475 + +
+ 476 + + template <> inline constexpr binary_format<float>::equiv_uint
+ 477 + + binary_format<float>::hidden_bit_mask() {
+ 478 + + return 0x00800000;
+ 479 + + }
+ 480 + + template <> inline constexpr binary_format<double>::equiv_uint
+ 481 + + binary_format<double>::hidden_bit_mask() {
+ 482 + + return 0x0010000000000000;
+ 483 + + }
+ 484 + +
+ 485 + + template<typename T>
+ 486 + + BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 487 + + void to_float(bool negative, adjusted_mantissa am, T &value) {
+ 488 + + using uint = typename binary_format<T>::equiv_uint;
+ 489 + +1005351 uint word = (uint)am.mantissa;
+ 490 + +1005351 word |= uint(am.power2) << binary_format<T>::mantissa_explicit_bits();
+ 491 + +1005351 word |= uint(negative) << binary_format<T>::sign_index();
+ 492 + + #ifdef BOOST_JSON_HAS_BIT_CAST
+ 493 + + value = std::bit_cast<T>(word);
+ 494 + + #else
+ 495 + +1005351 ::memcpy(&value, &word, sizeof(T));
+ 496 + + #endif
+ 497 + +1005351 }
+ 498 + +
+ 499 + + template<typename UC>
+ 500 + +2986 static constexpr uint64_t int_cmp_zeros()
+ 501 + + {
+ 502 + + static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), "Unsupported character size");
+ 503 + +2986 return (sizeof(UC) == 1) ? 0x3030303030303030 : (sizeof(UC) == 2) ? (uint64_t(UC('0')) << 48 | uint64_t(UC('0')) << 32 | uint64_t(UC('0')) << 16 | UC('0')) : (uint64_t(UC('0')) << 32 | UC('0'));
+ 504 + + }
+ 505 + + template<typename UC>
+ 506 + +2986 static constexpr int int_cmp_len()
+ 507 + + {
+ 508 + +2986 return sizeof(uint64_t) / sizeof(UC);
+ 509 + + }
+ 510 + + template<typename UC>
+ 511 + + static constexpr UC const * str_const_nan()
+ 512 + + {
+ 513 + + return nullptr;
+ 514 + + }
+ 515 + + template<>
+ 516 + + constexpr char const * str_const_nan<char>()
+ 517 + + {
+ 518 + + return "nan";
+ 519 + + }
+ 520 + + template<>
+ 521 + + constexpr wchar_t const * str_const_nan<wchar_t>()
+ 522 + + {
+ 523 + + return L"nan";
+ 524 + + }
+ 525 + + template<>
+ 526 + + constexpr char16_t const * str_const_nan<char16_t>()
+ 527 + + {
+ 528 + + return u"nan";
+ 529 + + }
+ 530 + + template<>
+ 531 + + constexpr char32_t const * str_const_nan<char32_t>()
+ 532 + + {
+ 533 + + return U"nan";
+ 534 + + }
+ 535 + + template<typename UC>
+ 536 + + static constexpr UC const * str_const_inf()
+ 537 + + {
+ 538 + + return nullptr;
+ 539 + + }
+ 540 + + template<>
+ 541 + + constexpr char const * str_const_inf<char>()
+ 542 + + {
+ 543 + + return "infinity";
+ 544 + + }
+ 545 + + template<>
+ 546 + + constexpr wchar_t const * str_const_inf<wchar_t>()
+ 547 + + {
+ 548 + + return L"infinity";
+ 549 + + }
+ 550 + + template<>
+ 551 + + constexpr char16_t const * str_const_inf<char16_t>()
+ 552 + + {
+ 553 + + return u"infinity";
+ 554 + + }
+ 555 + + template<>
+ 556 + + constexpr char32_t const * str_const_inf<char32_t>()
+ 557 + + {
+ 558 + + return U"infinity";
+ 559 + + }
+ 560 + +
+ 561 + + }}}}}} // namespaces
+ 562 + +
+ 563 + + #endif
+ 564 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.format.ipp.9ec47a71b786a54db9e57825e82a5eb7.html b/json/gcovr/index.format.ipp.9ec47a71b786a54db9e57825e82a5eb7.html new file mode 100644 index 00000000..cb23ae55 --- /dev/null +++ b/json/gcovr/index.format.ipp.9ec47a71b786a54db9e57825e82a5eb7.html @@ -0,0 +1,3110 @@ + + + + + + detail/impl/format.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/impl/format.ipp

+
+ + 100.0% Lines (40/40) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/impl/format.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Peter Dimov (pdimov at gmail dot com),
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_DETAIL_IMPL_FORMAT_IPP
+ 12 + + #define BOOST_JSON_DETAIL_IMPL_FORMAT_IPP
+ 13 + +
+ 14 + + #include <boost/json/detail/ryu/ryu.hpp>
+ 15 + + #include <cstring>
+ 16 + +
+ 17 + + namespace boost {
+ 18 + + namespace json {
+ 19 + + namespace detail {
+ 20 + +
+ 21 + + /* Reference work:
+ 22 + +
+ 23 + + https://www.ampl.com/netlib/fp/dtoa.c
+ 24 + + https://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
+ 25 + + https://kkimdev.github.io/posts/2018/06/15/IEEE-754-Floating-Point-Type-in-C++.html
+ 26 + + */
+ 27 + +
+ 28 + +4838 inline char const* digits_lut() noexcept
+ 29 + + {
+ 30 + + return
+ 31 + + "00010203040506070809"
+ 32 + + "10111213141516171819"
+ 33 + + "20212223242526272829"
+ 34 + + "30313233343536373839"
+ 35 + + "40414243444546474849"
+ 36 + + "50515253545556575859"
+ 37 + + "60616263646566676869"
+ 38 + + "70717273747576777879"
+ 39 + + "80818283848586878889"
+ 40 + +4838 "90919293949596979899";
+ 41 + + }
+ 42 + +
+ 43 + +1988 inline void format_four_digits( char * dest, unsigned v )
+ 44 + + {
+ 45 + +1988 std::memcpy( dest + 2, digits_lut() + (v % 100) * 2, 2 );
+ 46 + +1988 std::memcpy( dest , digits_lut() + (v / 100) * 2, 2 );
+ 47 + +1988 }
+ 48 + +
+ 49 + +862 inline void format_two_digits( char * dest, unsigned v )
+ 50 + + {
+ 51 + +862 std::memcpy( dest, digits_lut() + v * 2, 2 );
+ 52 + +862 }
+ 53 + +
+ 54 + +405 inline void format_digit( char * dest, unsigned v )
+ 55 + + {
+ 56 + +405 *dest = static_cast<char>( v + '0' );
+ 57 + +405 }
+ 58 + +
+ 59 + + unsigned
+ 60 + +3613 format_uint64(
+ 61 + + char* dest,
+ 62 + + std::uint64_t v) noexcept
+ 63 + + {
+ 64 + +3613 if(v < 10)
+ 65 + + {
+ 66 + +2475 *dest = static_cast<char>( '0' + v );
+ 67 + +2475 return 1;
+ 68 + + }
+ 69 + +
+ 70 + + char buffer[ 24 ];
+ 71 + +
+ 72 + +1138 char * p = buffer + 24;
+ 73 + +
+ 74 + +3126 while( v >= 1000 )
+ 75 + + {
+ 76 + +1988 p -= 4;
+ 77 + +1988 format_four_digits( p, v % 10000 );
+ 78 + +1988 v /= 10000;
+ 79 + + }
+ 80 + +
+ 81 + +1138 if( v >= 10 )
+ 82 + + {
+ 83 + +862 p -= 2;
+ 84 + +862 format_two_digits( p, v % 100 );
+ 85 + +862 v /= 100;
+ 86 + + }
+ 87 + +
+ 88 + +1138 if( v )
+ 89 + + {
+ 90 + +405 p -= 1;
+ 91 + +405 format_digit( p, static_cast<unsigned>(v) );
+ 92 + + }
+ 93 + +
+ 94 + +1138 unsigned const n = static_cast<unsigned>( buffer + 24 - p );
+ 95 + +1138 std::memcpy( dest, p, n );
+ 96 + +
+ 97 + +1138 return n;
+ 98 + + }
+ 99 + +
+ 100 + + unsigned
+ 101 + +3188 format_int64(
+ 102 + + char* dest, int64_t i) noexcept
+ 103 + + {
+ 104 + +3188 std::uint64_t ui = static_cast<
+ 105 + + std::uint64_t>(i);
+ 106 + +3188 if(i >= 0)
+ 107 + +2746 return format_uint64(dest, ui);
+ 108 + +442 *dest++ = '-';
+ 109 + +442 ui = ~ui + 1;
+ 110 + +442 return 1 + format_uint64(dest, ui);
+ 111 + + }
+ 112 + +
+ 113 + + unsigned
+ 114 + +477 format_double(
+ 115 + + char* dest, double d, bool allow_infinity_and_nan) noexcept
+ 116 + + {
+ 117 + + return static_cast<int>(
+ 118 + +477 ryu::d2s_buffered_n(d, dest, allow_infinity_and_nan));
+ 119 + + }
+ 120 + +
+ 121 + + } // detail
+ 122 + + } // namespace json
+ 123 + + } // namespace boost
+ 124 + +
+ 125 + + #endif
+ 126 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.from_chars.ipp.1f79c0e3711fd7d708dc790de46627b3.html b/json/gcovr/index.from_chars.ipp.1f79c0e3711fd7d708dc790de46627b3.html new file mode 100644 index 00000000..0d27c331 --- /dev/null +++ b/json/gcovr/index.from_chars.ipp.1f79c0e3711fd7d708dc790de46627b3.html @@ -0,0 +1,2486 @@ + + + + + + detail/charconv/impl/from_chars.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/impl/from_chars.ipp

+
+ + 25.0% Lines (3/12) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/impl/from_chars.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2022 Peter Dimov
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + +
+ 6 + + // https://stackoverflow.com/questions/38060411/visual-studio-2015-wont-suppress-error-c4996
+ 7 + + #ifndef _SCL_SECURE_NO_WARNINGS
+ 8 + + # define _SCL_SECURE_NO_WARNINGS
+ 9 + + #endif
+ 10 + + #ifndef NO_WARN_MBCS_MFC_DEPRECATION
+ 11 + + # define NO_WARN_MBCS_MFC_DEPRECATION
+ 12 + + #endif
+ 13 + +
+ 14 + + #include <boost/json/detail/charconv/detail/fast_float/fast_float.hpp>
+ 15 + + #include <boost/json/detail/charconv/detail/from_chars_float_impl.hpp>
+ 16 + + #include <boost/json/detail/charconv/from_chars.hpp>
+ 17 + + #include <system_error>
+ 18 + + #include <string>
+ 19 + + #include <cstdlib>
+ 20 + + #include <cerrno>
+ 21 + + #include <cstring>
+ 22 + +
+ 23 + + #if defined(__GNUC__) && __GNUC__ < 5
+ 24 + + # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+ 25 + + #endif
+ 26 + +
+ 27 + + std::errc boost::json::detail::charconv::detail::errno_to_errc(int errno_value) noexcept
+ 28 + + {
+ 29 + + switch (errno_value)
+ 30 + + {
+ 31 + + case EINVAL:
+ 32 + + return std::errc::invalid_argument;
+ 33 + + case ERANGE:
+ 34 + + return std::errc::result_out_of_range;
+ 35 + + default:
+ 36 + + return std::errc();
+ 37 + + }
+ 38 + + }
+ 39 + +
+ 40 + +1009310 boost::json::detail::charconv::from_chars_result boost::json::detail::charconv::from_chars(const char* first, const char* last, double& value, boost::json::detail::charconv::chars_format fmt) noexcept
+ 41 + + {
+ 42 + +1009310 if (fmt != boost::json::detail::charconv::chars_format::hex)
+ 43 + + {
+ 44 + +1009310 return boost::json::detail::charconv::detail::fast_float::from_chars(first, last, value, fmt);
+ 45 + + }
+ 46 + + return boost::json::detail::charconv::detail::from_chars_float_impl(first, last, value, fmt);
+ 47 + + }
+ 48 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.from_chars_float_impl.hpp.a4a922435f511d73baf7f630422a09ef.html b/json/gcovr/index.from_chars_float_impl.hpp.a4a922435f511d73baf7f630422a09ef.html new file mode 100644 index 00000000..502f8fbc --- /dev/null +++ b/json/gcovr/index.from_chars_float_impl.hpp.a4a922435f511d73baf7f630422a09ef.html @@ -0,0 +1,3486 @@ + + + + + + detail/charconv/detail/from_chars_float_impl.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/from_chars_float_impl.hpp

+
+ + 0.0% Lines (0/49) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/from_chars_float_impl.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2022 Peter Dimov
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + +
+ 6 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FROM_CHARS_FLOAT_IMPL_HPP
+ 7 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FROM_CHARS_FLOAT_IMPL_HPP
+ 8 + +
+ 9 + + #include <boost/json/detail/charconv/detail/config.hpp>
+ 10 + + #include <boost/json/detail/charconv/detail/from_chars_result.hpp>
+ 11 + + #include <boost/json/detail/charconv/detail/parser.hpp>
+ 12 + + #include <boost/json/detail/charconv/detail/compute_float64.hpp>
+ 13 + + #include <boost/json/detail/charconv/chars_format.hpp>
+ 14 + + #include <system_error>
+ 15 + + #include <cstdlib>
+ 16 + + #include <cmath>
+ 17 + +
+ 18 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail {
+ 19 + +
+ 20 + + #ifdef BOOST_MSVC
+ 21 + + # pragma warning(push)
+ 22 + + # pragma warning(disable: 4244) // Implict converion when BOOST_IF_CONSTEXPR expands to if
+ 23 + + #elif defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 24 + + # pragma GCC diagnostic push
+ 25 + + # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+ 26 + + #endif
+ 27 + +
+ 28 + + template <typename T>
+ 29 + + from_chars_result from_chars_strtod_impl(const char* first, const char* last, T& value, char* buffer) noexcept
+ 30 + + {
+ 31 + + // For strto(f/d)
+ 32 + + // Floating point value corresponding to the contents of str on success.
+ 33 + + // If the converted value falls out of range of corresponding return type, range error occurs and HUGE_VAL, HUGE_VALF or HUGE_VALL is returned.
+ 34 + + // If no conversion can be performed, 0 is returned and *str_end is set to str.
+ 35 + +
+ 36 + + std::memcpy(buffer, first, static_cast<std::size_t>(last - first));
+ 37 + + buffer[last - first] = '\0';
+ 38 + +
+ 39 + + char* str_end;
+ 40 + + T return_value {};
+ 41 + + BOOST_IF_CONSTEXPR (std::is_same<T, float>::value)
+ 42 + + {
+ 43 + + return_value = std::strtof(buffer, &str_end);
+ 44 + + if (return_value == HUGE_VALF)
+ 45 + + {
+ 46 + + return {last, std::errc::result_out_of_range};
+ 47 + + }
+ 48 + + }
+ 49 + + else BOOST_IF_CONSTEXPR (std::is_same<T, double>::value)
+ 50 + + {
+ 51 + + return_value = std::strtod(buffer, &str_end);
+ 52 + + if (return_value == HUGE_VAL)
+ 53 + + {
+ 54 + + return {last, std::errc::result_out_of_range};
+ 55 + + }
+ 56 + + }
+ 57 + + else
+ 58 + + {
+ 59 + + return_value = std::strtold(buffer, &str_end);
+ 60 + + if (return_value == HUGE_VALL)
+ 61 + + {
+ 62 + + return {last, std::errc::result_out_of_range};
+ 63 + + }
+ 64 + + }
+ 65 + +
+ 66 + + // Since this is a fallback routine we are safe to check for 0
+ 67 + + if (return_value == 0 && str_end == last)
+ 68 + + {
+ 69 + + return {first, std::errc::result_out_of_range};
+ 70 + + }
+ 71 + +
+ 72 + + value = return_value;
+ 73 + + return {first + (str_end - buffer), std::errc()};
+ 74 + + }
+ 75 + +
+ 76 + + template <typename T>
+ 77 + + inline from_chars_result from_chars_strtod(const char* first, const char* last, T& value) noexcept
+ 78 + + {
+ 79 + + if (last - first < 1024)
+ 80 + + {
+ 81 + + char buffer[1024];
+ 82 + + return from_chars_strtod_impl(first, last, value, buffer);
+ 83 + + }
+ 84 + +
+ 85 + + // If the string to be parsed does not fit into the 1024 byte static buffer than we have to allocate a buffer.
+ 86 + + // malloc is used here because it does not throw on allocation failure.
+ 87 + +
+ 88 + + char* buffer = static_cast<char*>(std::malloc(last - first + 1));
+ 89 + + if (buffer == nullptr)
+ 90 + + {
+ 91 + + return {first, std::errc::not_enough_memory};
+ 92 + + }
+ 93 + +
+ 94 + + auto r = from_chars_strtod_impl(first, last, value, buffer);
+ 95 + + std::free(buffer);
+ 96 + +
+ 97 + + return r;
+ 98 + + }
+ 99 + +
+ 100 + + template <typename T>
+ 101 + + from_chars_result from_chars_float_impl(const char* first, const char* last, T& value, chars_format fmt) noexcept
+ 102 + + {
+ 103 + + bool sign {};
+ 104 + + std::uint64_t significand {};
+ 105 + + std::int64_t exponent {};
+ 106 + +
+ 107 + + auto r = charconv::detail::parser(first, last, sign, significand, exponent, fmt);
+ 108 + + if (r.ec != std::errc())
+ 109 + + {
+ 110 + + return r;
+ 111 + + }
+ 112 + + else if (significand == 0)
+ 113 + + {
+ 114 + + value = sign ? static_cast<T>(-0.0L) : static_cast<T>(0.0L);
+ 115 + + return r;
+ 116 + + }
+ 117 + + else if (exponent == -1)
+ 118 + + {
+ 119 + + // A full length significand e.g. -1985444280612224 with a power of -1 sometimes
+ 120 + + // fails in compute_float64 but is trivial to calculate
+ 121 + + // Found investigating GitHub issue #47
+ 122 + + value = (sign ? -static_cast<T>(significand) : static_cast<T>(significand)) / 10;
+ 123 + + }
+ 124 + +
+ 125 + + bool success {};
+ 126 + + T return_val {};
+ 127 + + return_val = compute_float64(exponent, significand, sign, success);
+ 128 + +
+ 129 + + if (!success)
+ 130 + + {
+ 131 + + if (significand == 1 && exponent == 0)
+ 132 + + {
+ 133 + + value = 1;
+ 134 + + r.ptr = last;
+ 135 + + r.ec = std::errc();
+ 136 + + }
+ 137 + + else
+ 138 + + {
+ 139 + + if (return_val == HUGE_VAL || return_val == -HUGE_VAL)
+ 140 + + {
+ 141 + + value = return_val;
+ 142 + + r.ec = std::errc::result_out_of_range;
+ 143 + + }
+ 144 + + else if (exponent < -342)
+ 145 + + {
+ 146 + + value = sign ? -0.0 : 0.0;
+ 147 + + r.ec = std::errc::result_out_of_range;
+ 148 + + }
+ 149 + + else
+ 150 + + {
+ 151 + + r = from_chars_strtod(first, r.ptr, value);
+ 152 + + }
+ 153 + + }
+ 154 + + }
+ 155 + + else
+ 156 + + {
+ 157 + + value = return_val;
+ 158 + + }
+ 159 + +
+ 160 + + return r;
+ 161 + + }
+ 162 + +
+ 163 + +
+ 164 + + #ifdef BOOST_MSVC
+ 165 + + # pragma warning(pop)
+ 166 + + #elif defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 167 + + # pragma GCC diagnostic pop
+ 168 + + #endif
+ 169 + +
+ 170 + + }}}}} // Namespace boost::charconv::detail
+ 171 + +
+ 172 + + #endif // BOOST_JSON_DETAIL_CHARCONV_DETAIL_FROM_CHARS_FLOAT_IMPL_HPP
+ 173 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.from_chars_integer_impl.hpp.62421e671be5feb9c0f1e3df5a09b86e.html b/json/gcovr/index.from_chars_integer_impl.hpp.62421e671be5feb9c0f1e3df5a09b86e.html new file mode 100644 index 00000000..b243cbd2 --- /dev/null +++ b/json/gcovr/index.from_chars_integer_impl.hpp.62421e671be5feb9c0f1e3df5a09b86e.html @@ -0,0 +1,4126 @@ + + + + + + detail/charconv/detail/from_chars_integer_impl.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/from_chars_integer_impl.hpp

+
+ + 0.0% Lines (0/56) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/from_chars_integer_impl.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2023 Matt Borland
+ 2 + + // Distributed under the Boost Software License, Version 1.0.
+ 3 + + // https://www.boost.org/LICENSE_1_0.txt
+ 4 + +
+ 5 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FROM_CHARS_INTEGER_IMPL_HPP
+ 6 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FROM_CHARS_INTEGER_IMPL_HPP
+ 7 + +
+ 8 + + #include <boost/json/detail/charconv/detail/config.hpp>
+ 9 + + #include <boost/json/detail/charconv/detail/from_chars_result.hpp>
+ 10 + + #include <boost/config.hpp>
+ 11 + + #include <system_error>
+ 12 + + #include <type_traits>
+ 13 + + #include <limits>
+ 14 + + #include <cstdlib>
+ 15 + + #include <cerrno>
+ 16 + + #include <cstddef>
+ 17 + + #include <cstdint>
+ 18 + +
+ 19 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail {
+ 20 + +
+ 21 + + static constexpr unsigned char uchar_values[] =
+ 22 + + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 23 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 24 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 25 + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
+ 26 + + 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 27 + + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 255, 255, 255, 255, 255,
+ 28 + + 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 29 + + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 255, 255, 255, 255, 255,
+ 30 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 31 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 32 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 33 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 34 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 35 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 36 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 37 + + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
+ 38 + +
+ 39 + + static_assert(sizeof(uchar_values) == 256, "uchar_values should represent all 256 values of unsigned char");
+ 40 + +
+ 41 + + // Convert characters for 0-9, A-Z, a-z to 0-35. Anything else is 255
+ 42 + + constexpr unsigned char digit_from_char(char val) noexcept
+ 43 + + {
+ 44 + + return uchar_values[static_cast<unsigned char>(val)];
+ 45 + + }
+ 46 + +
+ 47 + + #ifdef BOOST_MSVC
+ 48 + + # pragma warning(push)
+ 49 + + # pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
+ 50 + + # pragma warning(disable: 4189) // 'is_negative': local variable is initialized but not referenced
+ 51 + +
+ 52 + + #elif defined(__clang__)
+ 53 + + # pragma clang diagnostic push
+ 54 + + # pragma clang diagnostic ignored "-Wconstant-conversion"
+ 55 + +
+ 56 + + #elif defined(__GNUC__) && (__GNUC__ < 7)
+ 57 + + # pragma GCC diagnostic push
+ 58 + + # pragma GCC diagnostic ignored "-Woverflow"
+ 59 + +
+ 60 + + #elif defined(__GNUC__) && (__GNUC__ >= 7)
+ 61 + + # pragma GCC diagnostic push
+ 62 + + # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+ 63 + +
+ 64 + + #endif
+ 65 + +
+ 66 + + template <typename Integer, typename Unsigned_Integer>
+ 67 + + BOOST_CXX14_CONSTEXPR from_chars_result from_chars_integer_impl(const char* first, const char* last, Integer& value, int base) noexcept
+ 68 + + {
+ 69 + + Unsigned_Integer result = 0;
+ 70 + + Unsigned_Integer overflow_value = 0;
+ 71 + + Unsigned_Integer max_digit = 0;
+ 72 + +
+ 73 + + // Check pre-conditions
+ 74 + + if (!((first <= last) && (base >= 2 && base <= 36)))
+ 75 + + {
+ 76 + + return {first, std::errc::invalid_argument};
+ 77 + + }
+ 78 + +
+ 79 + + Unsigned_Integer unsigned_base = static_cast<Unsigned_Integer>(base);
+ 80 + +
+ 81 + + // Strip sign if the type is signed
+ 82 + + // Negative sign will be appended at the end of parsing
+ 83 + + BOOST_ATTRIBUTE_UNUSED bool is_negative = false;
+ 84 + + auto next = first;
+ 85 + +
+ 86 + + #ifdef BOOST_HAS_INT128
+ 87 + + BOOST_IF_CONSTEXPR (std::is_same<Integer, boost::int128_type>::value || std::is_signed<Integer>::value)
+ 88 + + #else
+ 89 + + BOOST_IF_CONSTEXPR (std::is_signed<Integer>::value)
+ 90 + + #endif
+ 91 + + {
+ 92 + + if (next != last)
+ 93 + + {
+ 94 + + if (*next == '-')
+ 95 + + {
+ 96 + + is_negative = true;
+ 97 + + ++next;
+ 98 + + }
+ 99 + + else if (*next == '+')
+ 100 + + {
+ 101 + + return {next, std::errc::invalid_argument};
+ 102 + + }
+ 103 + + }
+ 104 + +
+ 105 + + #ifdef BOOST_HAS_INT128
+ 106 + + BOOST_IF_CONSTEXPR (std::is_same<Integer, boost::int128_type>::value)
+ 107 + + {
+ 108 + + overflow_value = BOOST_JSON_INT128_MAX;
+ 109 + + max_digit = BOOST_JSON_INT128_MAX;
+ 110 + + }
+ 111 + + else
+ 112 + + #endif
+ 113 + + {
+ 114 + + overflow_value = (std::numeric_limits<Integer>::max)();
+ 115 + + max_digit = (std::numeric_limits<Integer>::max)();
+ 116 + + }
+ 117 + +
+ 118 + + if (is_negative)
+ 119 + + {
+ 120 + + ++overflow_value;
+ 121 + + ++max_digit;
+ 122 + + }
+ 123 + + }
+ 124 + + else
+ 125 + + {
+ 126 + + if (next != last && (*next == '-' || *next == '+'))
+ 127 + + {
+ 128 + + return {first, std::errc::invalid_argument};
+ 129 + + }
+ 130 + +
+ 131 + + #ifdef BOOST_HAS_INT128
+ 132 + + BOOST_IF_CONSTEXPR (std::is_same<Integer, boost::uint128_type>::value)
+ 133 + + {
+ 134 + + overflow_value = BOOST_JSON_UINT128_MAX;
+ 135 + + max_digit = BOOST_JSON_UINT128_MAX;
+ 136 + + }
+ 137 + + else
+ 138 + + #endif
+ 139 + + {
+ 140 + + overflow_value = (std::numeric_limits<Unsigned_Integer>::max)();
+ 141 + + max_digit = (std::numeric_limits<Unsigned_Integer>::max)();
+ 142 + + }
+ 143 + + }
+ 144 + +
+ 145 + + #ifdef BOOST_HAS_INT128
+ 146 + + BOOST_IF_CONSTEXPR (std::is_same<Integer, boost::int128_type>::value)
+ 147 + + {
+ 148 + + overflow_value /= unsigned_base;
+ 149 + + max_digit %= unsigned_base;
+ 150 + + overflow_value *= 2; // Overflow value would cause INT128_MIN in non-base10 to fail
+ 151 + + }
+ 152 + + else
+ 153 + + #endif
+ 154 + + {
+ 155 + + overflow_value /= unsigned_base;
+ 156 + + max_digit %= unsigned_base;
+ 157 + + }
+ 158 + +
+ 159 + + // If the only character was a sign abort now
+ 160 + + if (next == last)
+ 161 + + {
+ 162 + + return {first, std::errc::invalid_argument};
+ 163 + + }
+ 164 + +
+ 165 + + bool overflowed = false;
+ 166 + +
+ 167 + + std::ptrdiff_t nc = last - next;
+ 168 + + constexpr std::ptrdiff_t nd = std::numeric_limits<Integer>::digits10;
+ 169 + +
+ 170 + + {
+ 171 + + std::ptrdiff_t i = 0;
+ 172 + +
+ 173 + + for( ; i < nd && i < nc; ++i )
+ 174 + + {
+ 175 + + // overflow is not possible in the first nd characters
+ 176 + +
+ 177 + + const unsigned char current_digit = digit_from_char(*next);
+ 178 + +
+ 179 + + if (current_digit >= unsigned_base)
+ 180 + + {
+ 181 + + break;
+ 182 + + }
+ 183 + +
+ 184 + + result = static_cast<Unsigned_Integer>(result * unsigned_base + current_digit);
+ 185 + + ++next;
+ 186 + + }
+ 187 + +
+ 188 + + for( ; i < nc; ++i )
+ 189 + + {
+ 190 + + const unsigned char current_digit = digit_from_char(*next);
+ 191 + +
+ 192 + + if (current_digit >= unsigned_base)
+ 193 + + {
+ 194 + + break;
+ 195 + + }
+ 196 + +
+ 197 + + if (result < overflow_value || (result == overflow_value && current_digit <= max_digit))
+ 198 + + {
+ 199 + + result = static_cast<Unsigned_Integer>(result * unsigned_base + current_digit);
+ 200 + + }
+ 201 + + else
+ 202 + + {
+ 203 + + // Required to keep updating the value of next, but the result is garbage
+ 204 + + overflowed = true;
+ 205 + + }
+ 206 + +
+ 207 + + ++next;
+ 208 + + }
+ 209 + + }
+ 210 + +
+ 211 + + // Return the parsed value, adding the sign back if applicable
+ 212 + + // If we have overflowed then we do not return the result
+ 213 + + if (overflowed)
+ 214 + + {
+ 215 + + return {next, std::errc::result_out_of_range};
+ 216 + + }
+ 217 + +
+ 218 + + value = static_cast<Integer>(result);
+ 219 + + #ifdef BOOST_HAS_INT128
+ 220 + + BOOST_IF_CONSTEXPR (std::is_same<Integer, boost::int128_type>::value || std::is_signed<Integer>::value)
+ 221 + + #else
+ 222 + + BOOST_IF_CONSTEXPR (std::is_signed<Integer>::value)
+ 223 + + #endif
+ 224 + + {
+ 225 + + if (is_negative)
+ 226 + + {
+ 227 + + value = -(static_cast<Unsigned_Integer>(value));
+ 228 + + }
+ 229 + + }
+ 230 + +
+ 231 + + return {next, std::errc()};
+ 232 + + }
+ 233 + +
+ 234 + + #ifdef BOOST_MSVC
+ 235 + + # pragma warning(pop)
+ 236 + + #elif defined(__clang__) && defined(__APPLE__)
+ 237 + + # pragma clang diagnostic pop
+ 238 + + #elif defined(__GNUC__) && (__GNUC__ < 7 || __GNUC__ >= 9)
+ 239 + + # pragma GCC diagnostic pop
+ 240 + + #endif
+ 241 + +
+ 242 + + // Only from_chars for integer types is constexpr (as of C++23)
+ 243 + + template <typename Integer>
+ 244 + + BOOST_JSON_GCC5_CONSTEXPR from_chars_result from_chars(const char* first, const char* last, Integer& value, int base = 10) noexcept
+ 245 + + {
+ 246 + + using Unsigned_Integer = typename std::make_unsigned<Integer>::type;
+ 247 + + return detail::from_chars_integer_impl<Integer, Unsigned_Integer>(first, last, value, base);
+ 248 + + }
+ 249 + +
+ 250 + + }}}}} // Namespaces
+ 251 + +
+ 252 + + #endif // BOOST_JSON_DETAIL_CHARCONV_DETAIL_FROM_CHARS_INTEGER_IMPL_HPP
+ 253 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.functions.html b/json/gcovr/index.functions.html new file mode 100644 index 00000000..ad1e7473 --- /dev/null +++ b/json/gcovr/index.functions.html @@ -0,0 +1,2063 @@ + + + + + + Functions - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+ Functions: + -% + (0 / 0) +
+
+ Lines: + 93.3% +
+
+ Branches: + -% +
+
+ +
+
+
+
Function
+
Calls
+
Lines
+
Branches
+
+ +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.handler.ipp.25997a61b96794a78e1e3ddeede59723.html b/json/gcovr/index.handler.ipp.25997a61b96794a78e1e3ddeede59723.html new file mode 100644 index 00000000..15fa0dcb --- /dev/null +++ b/json/gcovr/index.handler.ipp.25997a61b96794a78e1e3ddeede59723.html @@ -0,0 +1,3742 @@ + + + + + + detail/impl/handler.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/impl/handler.ipp

+
+ + 100.0% Lines (50/50) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/impl/handler.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_IMPL_HANDLER_HPP
+ 11 + + #define BOOST_JSON_DETAIL_IMPL_HANDLER_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/handler.hpp>
+ 14 + + #include <utility>
+ 15 + +
+ 16 + + namespace boost {
+ 17 + + namespace json {
+ 18 + + namespace detail {
+ 19 + +
+ 20 + + template<class... Args>
+ 21 + +2076889 handler::
+ 22 + + handler(Args&&... args)
+ 23 + +2076889 : st(std::forward<Args>(args)...)
+ 24 + + {
+ 25 + +2076889 }
+ 26 + +
+ 27 + + bool
+ 28 + +2076874 handler::
+ 29 + + on_document_begin(
+ 30 + + system::error_code&)
+ 31 + + {
+ 32 + +2076874 return true;
+ 33 + + }
+ 34 + +
+ 35 + + bool
+ 36 + +2076683 handler::
+ 37 + + on_document_end(
+ 38 + + system::error_code&)
+ 39 + + {
+ 40 + +2076683 return true;
+ 41 + + }
+ 42 + +
+ 43 + + bool
+ 44 + +34953 handler::
+ 45 + + on_object_begin(
+ 46 + + system::error_code&)
+ 47 + + {
+ 48 + +34953 return true;
+ 49 + + }
+ 50 + +
+ 51 + + bool
+ 52 + +34877 handler::
+ 53 + + on_object_end(
+ 54 + + std::size_t n,
+ 55 + + system::error_code&)
+ 56 + + {
+ 57 + +34877 st.push_object(n);
+ 58 + +34838 return true;
+ 59 + + }
+ 60 + +
+ 61 + + bool
+ 62 + +2136 handler::
+ 63 + + on_array_begin(
+ 64 + + system::error_code&)
+ 65 + + {
+ 66 + +2136 return true;
+ 67 + + }
+ 68 + +
+ 69 + + bool
+ 70 + +2119 handler::
+ 71 + + on_array_end(
+ 72 + + std::size_t n,
+ 73 + + system::error_code&)
+ 74 + + {
+ 75 + +2119 st.push_array(n);
+ 76 + +2081 return true;
+ 77 + + }
+ 78 + +
+ 79 + + bool
+ 80 + +8065 handler::
+ 81 + + on_key_part(
+ 82 + + string_view s,
+ 83 + + std::size_t,
+ 84 + + system::error_code&)
+ 85 + + {
+ 86 + +8065 st.push_chars(s);
+ 87 + +8065 return true;
+ 88 + + }
+ 89 + +
+ 90 + + bool
+ 91 + +38352 handler::
+ 92 + + on_key(
+ 93 + + string_view s,
+ 94 + + std::size_t,
+ 95 + + system::error_code&)
+ 96 + + {
+ 97 + +38352 st.push_key(s);
+ 98 + +38292 return true;
+ 99 + + }
+ 100 + +
+ 101 + + bool
+ 102 + +9080 handler::
+ 103 + + on_string_part(
+ 104 + + string_view s,
+ 105 + + std::size_t,
+ 106 + + system::error_code&)
+ 107 + + {
+ 108 + +9080 st.push_chars(s);
+ 109 + +9080 return true;
+ 110 + + }
+ 111 + +
+ 112 + + bool
+ 113 + +26107 handler::
+ 114 + + on_string(
+ 115 + + string_view s,
+ 116 + + std::size_t,
+ 117 + + system::error_code&)
+ 118 + + {
+ 119 + +26107 st.push_string(s);
+ 120 + +26103 return true;
+ 121 + + }
+ 122 + +
+ 123 + + bool
+ 124 + +30915 handler::
+ 125 + + on_number_part(
+ 126 + + string_view,
+ 127 + + system::error_code&)
+ 128 + + {
+ 129 + +30915 return true;
+ 130 + + }
+ 131 + +
+ 132 + + bool
+ 133 + +5811 handler::
+ 134 + + on_int64(
+ 135 + + std::int64_t i,
+ 136 + + string_view,
+ 137 + + system::error_code&)
+ 138 + + {
+ 139 + +5811 st.push_int64(i);
+ 140 + +5811 return true;
+ 141 + + }
+ 142 + +
+ 143 + + bool
+ 144 + +70 handler::
+ 145 + + on_uint64(
+ 146 + + std::uint64_t u,
+ 147 + + string_view,
+ 148 + + system::error_code&)
+ 149 + + {
+ 150 + +70 st.push_uint64(u);
+ 151 + +70 return true;
+ 152 + + }
+ 153 + +
+ 154 + + bool
+ 155 + +2039817 handler::
+ 156 + + on_double(
+ 157 + + double d,
+ 158 + + string_view,
+ 159 + + system::error_code&)
+ 160 + + {
+ 161 + +2039817 st.push_double(d);
+ 162 + +2039817 return true;
+ 163 + + }
+ 164 + +
+ 165 + + bool
+ 166 + +399 handler::
+ 167 + + on_bool(
+ 168 + + bool b,
+ 169 + + system::error_code&)
+ 170 + + {
+ 171 + +399 st.push_bool(b);
+ 172 + +399 return true;
+ 173 + + }
+ 174 + +
+ 175 + + bool
+ 176 + +9367 handler::
+ 177 + + on_null(system::error_code&)
+ 178 + + {
+ 179 + +9367 st.push_null();
+ 180 + +9367 return true;
+ 181 + + }
+ 182 + +
+ 183 + + bool
+ 184 + +188 handler::
+ 185 + + on_comment_part(
+ 186 + + string_view,
+ 187 + + system::error_code&)
+ 188 + + {
+ 189 + +188 return true;
+ 190 + + }
+ 191 + +
+ 192 + + bool
+ 193 + +499 handler::
+ 194 + + on_comment(
+ 195 + + string_view, system::error_code&)
+ 196 + + {
+ 197 + +499 return true;
+ 198 + + }
+ 199 + +
+ 200 + + } // detail
+ 201 + + } // namespace json
+ 202 + + } // namespace boost
+ 203 + +
+ 204 + + #endif
+ 205 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.html b/json/gcovr/index.html new file mode 100644 index 00000000..adb87fe8 --- /dev/null +++ b/json/gcovr/index.html @@ -0,0 +1,2800 @@ + + + + + + GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+
+

Lines

+
+
+
+ + + + + 93.3% +
+
+
+ Hit + 8225 +
+
+ Total + 8811 +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+
+ +
+ High: ≥ 90.0% + Medium: ≥ 75.0% + Low: < 75.0% +
+ +
+
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+
+ +
+
+ +
+ + + + array.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 29 + / + 29 +
+ + +
+
+ +
+ + + + basic_parser.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 11 + / + 11 +
+ + +
+
+ + + +
+
+
+
+ 98.3% +
+ +
+ 1253 + / + 1275 +
+ + +
+
+ +
+ + + + detail +
+ +
+
+
+
+ 83.0% +
+ +
+ 2574 + / + 3103 +
+ + +
+
+ +
+ + + + impl +
+ +
+
+
+
+ 99.2% +
+ +
+ 3371 + / + 3399 +
+ + +
+
+ + + +
+
+
+
+ 100.0% +
+ +
+ 3 + / + 3 +
+ + +
+
+ +
+ + + + object.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 37 + / + 37 +
+ + +
+
+ +
+ + + + parser.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 29 + / + 29 +
+ + +
+
+ +
+ + + + pilfer.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 7 + / + 7 +
+ + +
+
+ +
+ + + + result_for.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 3 + / + 3 +
+ + +
+
+ +
+ + + + serializer.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 4 + / + 4 +
+ + +
+
+ + + +
+
+
+
+ 100.0% +
+ +
+ 3 + / + 3 +
+ + +
+
+ +
+ + + + storage_ptr.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 68 + / + 68 +
+ + +
+
+ +
+ + + + stream_parser.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 31 + / + 31 +
+ + +
+
+ +
+ + + + string.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 151 + / + 151 +
+ + +
+
+ +
+ + + + value.hpp +
+ +
+
+
+
+ 98.9% +
+ +
+ 516 + / + 522 +
+ + +
+
+ +
+ + + + value_from.hpp +
+ +
+
+
+
+ 92.3% +
+ +
+ 12 + / + 13 +
+ + +
+
+ +
+ + + + value_ref.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 114 + / + 114 +
+ + +
+
+ +
+ + + + value_to.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 9 + / + 9 +
+ + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.impl.c82c9a65c0038782a53ba4c76e95a641.html b/json/gcovr/index.impl.c82c9a65c0038782a53ba4c76e95a641.html new file mode 100644 index 00000000..62bdc976 --- /dev/null +++ b/json/gcovr/index.impl.c82c9a65c0038782a53ba4c76e95a641.html @@ -0,0 +1,3124 @@ + + + + + + impl/ - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+
+

Lines

+
+
+
+ + + + + 93.3% +
+
+
+ Hit + 8225 +
+
+ Total + 8811 +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+
+ +
+ High: ≥ 90.0% + Medium: ≥ 75.0% + Low: < 75.0% +
+ +
+
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+
+ +
+
+ +
+ + + + array.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 163 + / + 163 +
+ + +
+
+ +
+ + + + array.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 389 + / + 389 +
+ + +
+
+ +
+ + + + conversion.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 18 + / + 18 +
+ + +
+
+ +
+ + + + error.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 5 + / + 5 +
+ + +
+
+ +
+ + + + error.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 74 + / + 74 +
+ + +
+
+ +
+ + + + kind.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 14 + / + 14 +
+ + +
+
+ + + +
+
+
+
+ 97.1% +
+ +
+ 67 + / + 69 +
+ + +
+
+ +
+ + + + null_resource.ipp +
+ +
+
+
+
+ 77.8% +
+ +
+ 7 + / + 9 +
+ + +
+
+ +
+ + + + object.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 168 + / + 168 +
+ + +
+
+ +
+ + + + object.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 435 + / + 435 +
+ + +
+
+ +
+ + + + parse.ipp +
+ +
+
+
+
+ 96.1% +
+ +
+ 49 + / + 51 +
+ + +
+
+ +
+ + + + parse_into.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 43 + / + 43 +
+ + +
+
+ +
+ + + + parser.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 59 + / + 59 +
+ + +
+
+ +
+ + + + pointer.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 244 + / + 244 +
+ + +
+
+ +
+ + + + serialize.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 8 + / + 8 +
+ + +
+
+ +
+ + + + serialize.ipp +
+ +
+
+
+
+ 96.0% +
+ +
+ 95 + / + 99 +
+ + +
+
+ +
+ + + + serializer.hpp +
+ +
+
+
+
+ 97.8% +
+ +
+ 178 + / + 182 +
+ + +
+
+ +
+ + + + serializer.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 261 + / + 261 +
+ + +
+
+ + + +
+
+
+
+ 81.8% +
+ +
+ 18 + / + 22 +
+ + +
+
+ +
+ + + + stream_parser.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 67 + / + 67 +
+ + +
+
+ +
+ + + + string.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 69 + / + 69 +
+ + +
+
+ +
+ + + + string.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 167 + / + 167 +
+ + +
+
+ +
+ + + + value.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 3 + / + 3 +
+ + +
+
+ +
+ + + + value.ipp +
+ +
+
+
+
+ 98.7% +
+ +
+ 456 + / + 462 +
+ + +
+
+ +
+ + + + value_ref.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 7 + / + 7 +
+ + +
+
+ +
+ + + + value_ref.ipp +
+ +
+
+
+
+ 96.0% +
+ +
+ 72 + / + 75 +
+ + +
+
+ +
+ + + + value_stack.ipp +
+ +
+
+
+
+ 99.5% +
+ +
+ 198 + / + 199 +
+ + +
+
+ +
+ + + + visit.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 37 + / + 37 +
+ + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.impl.cde90127c1b0418ad9f796d3477a9914.html b/json/gcovr/index.impl.cde90127c1b0418ad9f796d3477a9914.html new file mode 100644 index 00000000..3fd189d0 --- /dev/null +++ b/json/gcovr/index.impl.cde90127c1b0418ad9f796d3477a9914.html @@ -0,0 +1,2440 @@ + + + + + + detail/impl/ - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+
+

Lines

+
+
+
+ + + + + 93.3% +
+
+
+ Hit + 8225 +
+
+ Total + 8811 +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+
+ +
+ High: ≥ 90.0% + Medium: ≥ 75.0% + Low: < 75.0% +
+ +
+
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+
+ +
+
+ +
+ + + + array.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 15 + / + 15 +
+ + +
+
+ + + +
+
+
+
+ 87.5% +
+ +
+ 7 + / + 8 +
+ + +
+
+ +
+ + + + except.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 8 + / + 8 +
+ + +
+
+ +
+ + + + format.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 40 + / + 40 +
+ + +
+
+ +
+ + + + handler.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 50 + / + 50 +
+ + +
+
+ + + +
+
+
+
+ 100.0% +
+ +
+ 6 + / + 6 +
+ + +
+
+ +
+ + + + stack.hpp +
+ +
+
+
+
+ 100.0% +
+ +
+ 55 + / + 55 +
+ + +
+
+ +
+ + + + stack.ipp +
+ +
+
+
+
+ 100.0% +
+ +
+ 43 + / + 43 +
+ + +
+
+ +
+ + + + string_impl.ipp +
+ +
+
+
+
+ 99.1% +
+ +
+ 227 + / + 229 +
+ + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.integer_search_trees.hpp.4c04f6dbbc7f34b14ccd1b3f4b32318c.html b/json/gcovr/index.integer_search_trees.hpp.4c04f6dbbc7f34b14ccd1b3f4b32318c.html new file mode 100644 index 00000000..a3332dda --- /dev/null +++ b/json/gcovr/index.integer_search_trees.hpp.4c04f6dbbc7f34b14ccd1b3f4b32318c.html @@ -0,0 +1,4030 @@ + + + + + + detail/charconv/detail/integer_search_trees.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/integer_search_trees.hpp

+
+ + 0.0% Lines (0/40) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/integer_search_trees.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2023 Matt Borland
+ 2 + + // Distributed under the Boost Software License, Version 1.0.
+ 3 + + // https://www.boost.org/LICENSE_1_0.txt
+ 4 + +
+ 5 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_INTEGER_SEARCH_TREES_HPP
+ 6 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_INTEGER_SEARCH_TREES_HPP
+ 7 + +
+ 8 + + // https://stackoverflow.com/questions/1489830/efficient-way-to-determine-number-of-digits-in-an-integer?page=1&tab=scoredesc#tab-top
+ 9 + + // https://graphics.stanford.edu/~seander/bithacks.html
+ 10 + +
+ 11 + + #include <boost/json/detail/charconv/detail/config.hpp>
+ 12 + + #include <limits>
+ 13 + + #include <array>
+ 14 + + #include <cstdint>
+ 15 + +
+ 16 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail {
+ 17 + +
+ 18 + + // Generic solution
+ 19 + + template <typename T>
+ 20 + + BOOST_JSON_CXX14_CONSTEXPR int num_digits(T x) noexcept
+ 21 + + {
+ 22 + + int digits = 0;
+ 23 + +
+ 24 + + while (x)
+ 25 + + {
+ 26 + + x /= 10;
+ 27 + + ++digits;
+ 28 + + }
+ 29 + +
+ 30 + + return digits;
+ 31 + + }
+ 32 + +
+ 33 + + template <>
+ 34 + + BOOST_JSON_CXX14_CONSTEXPR int num_digits(std::uint32_t x) noexcept
+ 35 + + {
+ 36 + + if (x >= UINT32_C(10000))
+ 37 + + {
+ 38 + + if (x >= UINT32_C(10000000))
+ 39 + + {
+ 40 + + if (x >= UINT32_C(100000000))
+ 41 + + {
+ 42 + + if (x >= UINT32_C(1000000000))
+ 43 + + {
+ 44 + + return 10;
+ 45 + + }
+ 46 + + return 9;
+ 47 + + }
+ 48 + + return 8;
+ 49 + + }
+ 50 + +
+ 51 + + else if (x >= UINT32_C(100000))
+ 52 + + {
+ 53 + + if (x >= UINT32_C(1000000))
+ 54 + + {
+ 55 + + return 7;
+ 56 + + }
+ 57 + + return 6;
+ 58 + + }
+ 59 + + return 5;
+ 60 + + }
+ 61 + + else if (x >= UINT32_C(100))
+ 62 + + {
+ 63 + + if (x >= UINT32_C(1000))
+ 64 + + {
+ 65 + + return 4;
+ 66 + + }
+ 67 + + return 3;
+ 68 + + }
+ 69 + + else if (x >= UINT32_C(10))
+ 70 + + {
+ 71 + + return 2;
+ 72 + + }
+ 73 + +
+ 74 + + return 1;
+ 75 + + }
+ 76 + +
+ 77 + + template <>
+ 78 + + BOOST_JSON_CXX14_CONSTEXPR int num_digits(std::uint64_t x) noexcept
+ 79 + + {
+ 80 + + if (x >= UINT64_C(10000000000))
+ 81 + + {
+ 82 + + if (x >= UINT64_C(100000000000000))
+ 83 + + {
+ 84 + + if (x >= UINT64_C(10000000000000000))
+ 85 + + {
+ 86 + + if (x >= UINT64_C(100000000000000000))
+ 87 + + {
+ 88 + + if (x >= UINT64_C(1000000000000000000))
+ 89 + + {
+ 90 + + if (x >= UINT64_C(10000000000000000000))
+ 91 + + {
+ 92 + + return 20;
+ 93 + + }
+ 94 + + return 19;
+ 95 + + }
+ 96 + + return 18;
+ 97 + + }
+ 98 + + return 17;
+ 99 + + }
+ 100 + + else if (x >= UINT64_C(1000000000000000))
+ 101 + + {
+ 102 + + return 16;
+ 103 + + }
+ 104 + + return 15;
+ 105 + + }
+ 106 + + if (x >= UINT64_C(1000000000000))
+ 107 + + {
+ 108 + + if (x >= UINT64_C(10000000000000))
+ 109 + + {
+ 110 + + return 14;
+ 111 + + }
+ 112 + + return 13;
+ 113 + + }
+ 114 + + if (x >= UINT64_C(100000000000))
+ 115 + + {
+ 116 + + return 12;
+ 117 + + }
+ 118 + + return 11;
+ 119 + + }
+ 120 + + else if (x >= UINT64_C(100000))
+ 121 + + {
+ 122 + + if (x >= UINT64_C(10000000))
+ 123 + + {
+ 124 + + if (x >= UINT64_C(100000000))
+ 125 + + {
+ 126 + + if (x >= UINT64_C(1000000000))
+ 127 + + {
+ 128 + + return 10;
+ 129 + + }
+ 130 + + return 9;
+ 131 + + }
+ 132 + + return 8;
+ 133 + + }
+ 134 + + if (x >= UINT64_C(1000000))
+ 135 + + {
+ 136 + + return 7;
+ 137 + + }
+ 138 + + return 6;
+ 139 + + }
+ 140 + + if (x >= UINT64_C(100))
+ 141 + + {
+ 142 + + if (x >= UINT64_C(1000))
+ 143 + + {
+ 144 + + if (x >= UINT64_C(10000))
+ 145 + + {
+ 146 + + return 5;
+ 147 + + }
+ 148 + + return 4;
+ 149 + + }
+ 150 + + return 3;
+ 151 + + }
+ 152 + + if (x >= UINT64_C(10))
+ 153 + + {
+ 154 + + return 2;
+ 155 + + }
+ 156 + + return 1;
+ 157 + + }
+ 158 + +
+ 159 + + #ifdef BOOST_HAS_INT128
+ 160 + + static constexpr std::array<std::uint64_t, 20> powers_of_10 =
+ 161 + + {{
+ 162 + + UINT64_C(1), UINT64_C(10), UINT64_C(100), UINT64_C(1000), UINT64_C(10000), UINT64_C(100000), UINT64_C(1000000),
+ 163 + + UINT64_C(10000000), UINT64_C(100000000), UINT64_C(1000000000), UINT64_C(10000000000), UINT64_C(100000000000),
+ 164 + + UINT64_C(1000000000000), UINT64_C(10000000000000), UINT64_C(100000000000000), UINT64_C(1000000000000000),
+ 165 + + UINT64_C(10000000000000000), UINT64_C(100000000000000000), UINT64_C(1000000000000000000), UINT64_C(10000000000000000000)
+ 166 + + }};
+ 167 + +
+ 168 + + // Assume that if someone is using 128 bit ints they are favoring the top end of the range
+ 169 + + // Max value is 340,282,366,920,938,463,463,374,607,431,768,211,455 (39 digits)
+ 170 + + BOOST_JSON_CXX14_CONSTEXPR int num_digits(boost::uint128_type x) noexcept
+ 171 + + {
+ 172 + + // There is not literal for boost::uint128_type so we need to calculate them using the max value of the
+ 173 + + // std::uint64_t powers of 10
+ 174 + + constexpr boost::uint128_type digits_39 = static_cast<boost::uint128_type>(UINT64_C(10000000000000000000)) *
+ 175 + + static_cast<boost::uint128_type>(UINT64_C(10000000000000000000));
+ 176 + +
+ 177 + + constexpr boost::uint128_type digits_38 = digits_39 / 10;
+ 178 + + constexpr boost::uint128_type digits_37 = digits_38 / 10;
+ 179 + + constexpr boost::uint128_type digits_36 = digits_37 / 10;
+ 180 + + constexpr boost::uint128_type digits_35 = digits_36 / 10;
+ 181 + + constexpr boost::uint128_type digits_34 = digits_35 / 10;
+ 182 + + constexpr boost::uint128_type digits_33 = digits_34 / 10;
+ 183 + + constexpr boost::uint128_type digits_32 = digits_33 / 10;
+ 184 + + constexpr boost::uint128_type digits_31 = digits_32 / 10;
+ 185 + + constexpr boost::uint128_type digits_30 = digits_31 / 10;
+ 186 + + constexpr boost::uint128_type digits_29 = digits_30 / 10;
+ 187 + + constexpr boost::uint128_type digits_28 = digits_29 / 10;
+ 188 + + constexpr boost::uint128_type digits_27 = digits_28 / 10;
+ 189 + + constexpr boost::uint128_type digits_26 = digits_27 / 10;
+ 190 + + constexpr boost::uint128_type digits_25 = digits_26 / 10;
+ 191 + + constexpr boost::uint128_type digits_24 = digits_25 / 10;
+ 192 + + constexpr boost::uint128_type digits_23 = digits_24 / 10;
+ 193 + + constexpr boost::uint128_type digits_22 = digits_23 / 10;
+ 194 + + constexpr boost::uint128_type digits_21 = digits_22 / 10;
+ 195 + +
+ 196 + + return (x >= digits_39) ? 39 :
+ 197 + + (x >= digits_38) ? 38 :
+ 198 + + (x >= digits_37) ? 37 :
+ 199 + + (x >= digits_36) ? 36 :
+ 200 + + (x >= digits_35) ? 35 :
+ 201 + + (x >= digits_34) ? 34 :
+ 202 + + (x >= digits_33) ? 33 :
+ 203 + + (x >= digits_32) ? 32 :
+ 204 + + (x >= digits_31) ? 31 :
+ 205 + + (x >= digits_30) ? 30 :
+ 206 + + (x >= digits_29) ? 29 :
+ 207 + + (x >= digits_28) ? 28 :
+ 208 + + (x >= digits_27) ? 27 :
+ 209 + + (x >= digits_26) ? 26 :
+ 210 + + (x >= digits_25) ? 25 :
+ 211 + + (x >= digits_24) ? 24 :
+ 212 + + (x >= digits_23) ? 23 :
+ 213 + + (x >= digits_22) ? 22 :
+ 214 + + (x >= digits_21) ? 21 :
+ 215 + + (x >= powers_of_10[19]) ? 20 :
+ 216 + + (x >= powers_of_10[18]) ? 19 :
+ 217 + + (x >= powers_of_10[17]) ? 18 :
+ 218 + + (x >= powers_of_10[16]) ? 17 :
+ 219 + + (x >= powers_of_10[15]) ? 16 :
+ 220 + + (x >= powers_of_10[14]) ? 15 :
+ 221 + + (x >= powers_of_10[13]) ? 14 :
+ 222 + + (x >= powers_of_10[12]) ? 13 :
+ 223 + + (x >= powers_of_10[11]) ? 12 :
+ 224 + + (x >= powers_of_10[10]) ? 11 :
+ 225 + + (x >= powers_of_10[9]) ? 10 :
+ 226 + + (x >= powers_of_10[8]) ? 9 :
+ 227 + + (x >= powers_of_10[7]) ? 8 :
+ 228 + + (x >= powers_of_10[6]) ? 7 :
+ 229 + + (x >= powers_of_10[5]) ? 6 :
+ 230 + + (x >= powers_of_10[4]) ? 5 :
+ 231 + + (x >= powers_of_10[3]) ? 4 :
+ 232 + + (x >= powers_of_10[2]) ? 3 :
+ 233 + + (x >= powers_of_10[1]) ? 2 :
+ 234 + + (x >= powers_of_10[0]) ? 1 : 0;
+ 235 + + }
+ 236 + + #endif
+ 237 + +
+ 238 + + }}}}} // Namespace boost::json::detail::charconv::detail
+ 239 + +
+ 240 + + #endif // BOOST_JSON_DETAIL_CHARCONV_DETAIL_INTEGER_SEARCH_TREES_HPP
+ 241 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.js b/json/gcovr/index.js new file mode 100644 index 00000000..9844c376 --- /dev/null +++ b/json/gcovr/index.js @@ -0,0 +1,453 @@ +/* GCOVR Custom JavaScript - Tree View & Interactivity */ + +(function() { + 'use strict'; + + // Wait for DOM ready + document.addEventListener('DOMContentLoaded', function() { + initTheme(); + initSidebar(); + initFileTree(); + initBreadcrumbs(); + initSearch(); + initSorting(); + initToggleButtons(); + initTreeControls(); + }); + + // =========================================== + // Breadcrumb Links + // =========================================== + + function initBreadcrumbs() { + var currentSpan = document.querySelector('.breadcrumb .current'); + if (!currentSpan || !window.GCOVR_TREE_DATA) return; + + var pathText = currentSpan.textContent.trim(); + var segments = pathText.split(' / '); + if (segments.length <= 1) return; + + // Create linked breadcrumb by traversing tree + var fragment = document.createDocumentFragment(); + var currentNodes = window.GCOVR_TREE_DATA; + + for (var i = 0; i < segments.length; i++) { + var segment = segments[i]; + + if (i > 0) { + var sep = document.createElement('span'); + sep.className = 'separator'; + sep.textContent = '/'; + fragment.appendChild(sep); + } + + // Find this segment in current level of tree + var foundNode = null; + for (var j = 0; j < currentNodes.length; j++) { + if (currentNodes[j].name === segment) { + foundNode = currentNodes[j]; + break; + } + } + + if (foundNode && foundNode.link && i < segments.length - 1) { + // Directory segment with link - make it clickable + var a = document.createElement('a'); + a.href = foundNode.link; + a.textContent = segment; + fragment.appendChild(a); + // Move to children for next iteration + currentNodes = foundNode.children || []; + } else { + // Last segment (current file) or no link found + var span = document.createElement('span'); + span.className = 'current-file'; + span.textContent = segment; + fragment.appendChild(span); + if (foundNode && foundNode.children) { + currentNodes = foundNode.children; + } + } + } + + currentSpan.innerHTML = ''; + currentSpan.appendChild(fragment); + } + + // =========================================== + // Theme Toggle + // =========================================== + + function initTheme() { + const toggle = document.getElementById('theme-toggle'); + const savedTheme = localStorage.getItem('gcovr-theme'); + + // Apply saved theme or default to dark + if (savedTheme) { + document.documentElement.setAttribute('data-theme', savedTheme); + } + + if (toggle) { + toggle.addEventListener('click', function() { + const current = document.documentElement.getAttribute('data-theme'); + const next = current === 'light' ? 'dark' : 'light'; + document.documentElement.setAttribute('data-theme', next); + localStorage.setItem('gcovr-theme', next); + }); + } + } + + // =========================================== + // Tree Controls (Expand/Collapse All) + // =========================================== + + function initTreeControls() { + var expandBtn = document.getElementById('expand-all'); + var collapseBtn = document.getElementById('collapse-all'); + + if (expandBtn) { + expandBtn.addEventListener('click', function() { + document.querySelectorAll('.tree-item').forEach(function(item) { + if (!item.classList.contains('no-children')) { + item.classList.add('expanded'); + var toggle = item.querySelector(':scope > .tree-item-header > .tree-folder-toggle'); + if (toggle) toggle.textContent = '−'; + } + }); + }); + } + + if (collapseBtn) { + collapseBtn.addEventListener('click', function() { + document.querySelectorAll('.tree-item').forEach(function(item) { + item.classList.remove('expanded'); + var toggle = item.querySelector(':scope > .tree-item-header > .tree-folder-toggle'); + if (toggle) toggle.textContent = '+'; + }); + }); + } + } + + // =========================================== + // Sidebar Toggle + // =========================================== + + function initSidebar() { + const sidebar = document.getElementById('sidebar'); + const toggle = document.getElementById('sidebar-toggle'); + + if (!sidebar || !toggle) return; + + // Load saved state + const isCollapsed = localStorage.getItem('sidebar-collapsed') === 'true'; + if (isCollapsed) { + sidebar.classList.add('collapsed'); + } + + toggle.addEventListener('click', function() { + sidebar.classList.toggle('collapsed'); + localStorage.setItem('sidebar-collapsed', sidebar.classList.contains('collapsed')); + }); + + // Mobile: open sidebar when clicked outside should close it + document.addEventListener('click', function(e) { + if (window.innerWidth <= 1024) { + if (sidebar.classList.contains('open') && + !sidebar.contains(e.target) && + e.target !== toggle && + !toggle.contains(e.target)) { + sidebar.classList.remove('open'); + } + } + }); + + // Mobile toggle + toggle.addEventListener('click', function() { + if (window.innerWidth <= 1024) { + sidebar.classList.toggle('open'); + } + }); + } + + // =========================================== + // File Tree - Load from tree.json + // =========================================== + + function initFileTree() { + var treeContainer = document.getElementById('file-tree'); + if (!treeContainer) return; + + // Check for embedded tree data first (works for local file:// access) + if (window.GCOVR_TREE_DATA) { + renderTree(treeContainer, window.GCOVR_TREE_DATA); + return; + } + + // Fallback: try to load tree.json for full hierarchy + fetch('tree.json') + .then(function(response) { + if (!response.ok) throw new Error('No tree.json'); + return response.json(); + }) + .then(function(tree) { + renderTree(treeContainer, tree); + }) + .catch(function(err) { + console.log('tree.json not found, using static sidebar'); + // Keep existing static content from Jinja template + }); + } + + function renderTree(container, tree) { + container.innerHTML = ''; + + if (!tree || tree.length === 0) { + container.innerHTML = '
No files found
'; + return; + } + + tree.forEach(function(item) { + container.appendChild(createTreeItem(item)); + }); + + // Auto-expand to current file and highlight it + expandToCurrentFile(container); + } + + function expandToCurrentFile(container) { + // Get current page filename + var currentPage = window.location.pathname.split('/').pop() || 'index.html'; + + // Find the link matching current page + var currentLink = container.querySelector('a[href="' + currentPage + '"]'); + if (!currentLink) return; + + // Mark as active + var treeItem = currentLink.closest('.tree-item'); + if (treeItem) { + treeItem.classList.add('active'); + } + + // Expand all parent folders + var parent = currentLink.closest('.tree-children'); + while (parent) { + var parentItem = parent.closest('.tree-item'); + if (parentItem) { + parentItem.classList.add('expanded'); + var toggle = parentItem.querySelector(':scope > .tree-item-header > .tree-folder-toggle'); + if (toggle) toggle.textContent = '−'; + } + parent = parentItem ? parentItem.parentElement.closest('.tree-children') : null; + } + + // Scroll into view + if (currentLink) { + currentLink.scrollIntoView({ block: 'center', behavior: 'smooth' }); + } + } + + function createTreeItem(item) { + var hasChildren = item.children && item.children.length > 0; + var isDirectory = item.isDirectory || hasChildren; + + var div = document.createElement('div'); + div.className = 'tree-item' + (isDirectory ? ' is-folder' : '') + (hasChildren ? '' : ' no-children'); + + var header = document.createElement('div'); + header.className = 'tree-item-header'; + var toggle = null; + + // Toggle button (+/-) for folders with children + if (hasChildren) { + toggle = document.createElement('button'); + toggle.className = 'tree-folder-toggle'; + toggle.textContent = '+'; + toggle.setAttribute('aria-label', 'Toggle folder'); + toggle.addEventListener('click', function(e) { + e.stopPropagation(); + e.preventDefault(); + var isExpanded = div.classList.toggle('expanded'); + toggle.textContent = isExpanded ? '−' : '+'; + }); + header.appendChild(toggle); + + // Make entire header clickable to expand/collapse + header.style.cursor = 'pointer'; + header.addEventListener('click', function(e) { + // Don't toggle if clicking a link + if (e.target.tagName === 'A') return; + e.preventDefault(); + var isExpanded = div.classList.toggle('expanded'); + toggle.textContent = isExpanded ? '−' : '+'; + }); + } else { + var spacer = document.createElement('span'); + spacer.className = 'tree-spacer'; + header.appendChild(spacer); + } + + // Icon - different for folders vs files + var icon = document.createElement('span'); + if (isDirectory) { + icon.className = 'tree-icon tree-icon-folder'; + icon.innerHTML = ''; + } else { + icon.className = 'tree-icon tree-icon-file'; + icon.innerHTML = ''; + } + header.appendChild(icon); + + // Label (with link if available) + var label = document.createElement('span'); + label.className = 'tree-label'; + label.title = item.name; + if (item.link) { + var link = document.createElement('a'); + link.href = item.link; + link.textContent = item.name; + link.title = item.name; + label.appendChild(link); + } else { + label.textContent = item.name; + } + header.appendChild(label); + + div.appendChild(header); + + // Children container (for expand/collapse) + if (hasChildren) { + var childrenWrapper = document.createElement('div'); + childrenWrapper.className = 'tree-children'; + + var childrenInner = document.createElement('div'); + childrenInner.className = 'tree-children-inner'; + item.children.forEach(function(child) { + childrenInner.appendChild(createTreeItem(child)); + }); + + childrenWrapper.appendChild(childrenInner); + div.appendChild(childrenWrapper); + } + + return div; + } + + // =========================================== + // Search + // =========================================== + + function initSearch() { + const searchInput = document.getElementById('file-search'); + if (!searchInput) return; + + searchInput.addEventListener('input', function() { + const query = this.value.toLowerCase().trim(); + const treeItems = document.querySelectorAll('.tree-item'); + + treeItems.forEach(function(item) { + const label = item.querySelector('.tree-label'); + if (label) { + const text = label.textContent.toLowerCase(); + const matches = query === '' || text.includes(query); + item.style.display = matches ? '' : 'none'; + } + }); + }); + } + + // =========================================== + // Sorting + // =========================================== + + function initSorting() { + const headers = document.querySelectorAll('.file-list-header .sortable, .functions-header .sortable'); + + headers.forEach(function(header) { + header.addEventListener('click', function() { + const sortKey = this.dataset.sort; + const isAscending = this.classList.contains('sorted-ascending'); + + // Remove sorted class from all headers + headers.forEach(function(h) { + h.classList.remove('sorted-ascending', 'sorted-descending'); + }); + + // Toggle sort direction + this.classList.add(isAscending ? 'sorted-descending' : 'sorted-ascending'); + + // Sort the list + sortList(sortKey, !isAscending); + }); + }); + } + + function sortList(key, ascending) { + const container = document.getElementById('file-list') || document.querySelector('.functions-body'); + if (!container) return; + + const rows = Array.from(container.children); + + rows.sort(function(a, b) { + let aVal = a.dataset[key] || a.querySelector('[data-sort]')?.dataset.sort || ''; + let bVal = b.dataset[key] || b.querySelector('[data-sort]')?.dataset.sort || ''; + + // Try to parse as numbers + const aNum = parseFloat(aVal); + const bNum = parseFloat(bVal); + + if (!isNaN(aNum) && !isNaN(bNum)) { + return ascending ? aNum - bNum : bNum - aNum; + } + + // String comparison + return ascending ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal); + }); + + rows.forEach(function(row) { + container.appendChild(row); + }); + } + + // =========================================== + // Toggle Buttons (Coverage Lines) + // =========================================== + + function initToggleButtons() { + const buttons = document.querySelectorAll('.button_toggle_coveredLine, .button_toggle_uncoveredLine, .button_toggle_partialCoveredLine, .button_toggle_excludedLine'); + + buttons.forEach(function(button) { + button.addEventListener('click', function() { + const lineClass = this.value; + const showClass = 'show_' + lineClass; + + // Toggle the button state + this.classList.toggle(showClass); + + // Toggle visibility of lines + const lines = document.querySelectorAll('.' + lineClass); + lines.forEach(function(line) { + line.classList.toggle(showClass); + }); + }); + }); + + // Also handle simpler toggle buttons + const simpleToggles = document.querySelectorAll('.btn-toggle'); + simpleToggles.forEach(function(button) { + button.addEventListener('click', function() { + const classes = Array.from(this.classList); + const showClass = classes.find(function(c) { return c.startsWith('show_'); }); + + if (showClass) { + this.classList.toggle(showClass); + const lineClass = showClass.replace('show_', ''); + const lines = document.querySelectorAll('.' + lineClass); + lines.forEach(function(line) { + line.classList.toggle(showClass); + }); + } + }); + }); + } + +})(); diff --git a/json/gcovr/index.kind.ipp.944bac86090b83665f00c8cee1a3defe.html b/json/gcovr/index.kind.ipp.944bac86090b83665f00c8cee1a3defe.html new file mode 100644 index 00000000..cf8df71d --- /dev/null +++ b/json/gcovr/index.kind.ipp.944bac86090b83665f00c8cee1a3defe.html @@ -0,0 +1,2478 @@ + + + + + + impl/kind.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/kind.ipp

+
+ + 100.0% Lines (14/14) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/kind.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_KIND_IPP
+ 11 + + #define BOOST_JSON_IMPL_KIND_IPP
+ 12 + +
+ 13 + + #include <boost/json/kind.hpp>
+ 14 + + #include <ostream>
+ 15 + +
+ 16 + + namespace boost {
+ 17 + + namespace json {
+ 18 + +
+ 19 + + string_view
+ 20 + +16 to_string(kind k) noexcept
+ 21 + + {
+ 22 + +16 switch(k)
+ 23 + + {
+ 24 + +2 case kind::array: return "array";
+ 25 + +2 case kind::object: return "object";
+ 26 + +2 case kind::string: return "string";
+ 27 + +2 case kind::int64: return "int64";
+ 28 + +2 case kind::uint64: return "uint64";
+ 29 + +2 case kind::double_: return "double";
+ 30 + +2 case kind::bool_: return "bool";
+ 31 + +2 default: // satisfy warnings
+ 32 + +2 case kind::null: return "null";
+ 33 + + }
+ 34 + + }
+ 35 + +
+ 36 + + std::ostream&
+ 37 + +8 operator<<(std::ostream& os, kind k)
+ 38 + + {
+ 39 + +8 os << to_string(k);
+ 40 + +8 return os;
+ 41 + + }
+ 42 + +
+ 43 + + } // namespace json
+ 44 + + } // namespace boost
+ 45 + +
+ 46 + + #endif
+ 47 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.literals.hpp.2e722ac7a80e95232217c08e5473907a.html b/json/gcovr/index.literals.hpp.2e722ac7a80e95232217c08e5473907a.html new file mode 100644 index 00000000..872cb4fc --- /dev/null +++ b/json/gcovr/index.literals.hpp.2e722ac7a80e95232217c08e5473907a.html @@ -0,0 +1,2630 @@ + + + + + + detail/literals.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/literals.hpp

+
+ + 100.0% Lines (2/2) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/literals.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2024 Dmitry Arkhipov (grisumbras@yandex.ru)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_LITERALS_HPP
+ 11 + + #define BOOST_JSON_DETAIL_LITERALS_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/mp11/integral.hpp>
+ 15 + +
+ 16 + + namespace boost {
+ 17 + + namespace json {
+ 18 + + namespace detail {
+ 19 + +
+ 20 + + enum class literals
+ 21 + + {
+ 22 + + null = 0,
+ 23 + + true_,
+ 24 + + false_,
+ 25 + + infinity,
+ 26 + + neg_infinity,
+ 27 + + nan,
+ 28 + + resume,
+ 29 + + };
+ 30 + +
+ 31 + + constexpr char const* literal_strings[] = {
+ 32 + + "null",
+ 33 + + "true",
+ 34 + + "false",
+ 35 + + "Infinity",
+ 36 + + "-Infinity",
+ 37 + + "NaN",
+ 38 + + "",
+ 39 + + };
+ 40 + +
+ 41 + + constexpr std::size_t literal_sizes[] = {
+ 42 + + 4,
+ 43 + + 4,
+ 44 + + 5,
+ 45 + + 8,
+ 46 + + 9,
+ 47 + + 3,
+ 48 + + 0,
+ 49 + + };
+ 50 + +
+ 51 + + template<literals L>
+ 52 + + using literals_c = std::integral_constant<literals, L>;
+ 53 + +
+ 54 + + constexpr
+ 55 + + unsigned char
+ 56 + +1007 literal_index(literals l)
+ 57 + + {
+ 58 + +1007 return static_cast<unsigned char>(l);
+ 59 + + }
+ 60 + +
+ 61 + + } // namespace detail
+ 62 + + } // namespace json
+ 63 + + } // namespace boost
+ 64 + +
+ 65 + + #endif // BOOST_JSON_DETAIL_LITERALS_HPP
+ 66 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.monotonic_resource.hpp.c7901c306f139d49bdd39970ea9decfb.html b/json/gcovr/index.monotonic_resource.hpp.c7901c306f139d49bdd39970ea9decfb.html new file mode 100644 index 00000000..4b92a407 --- /dev/null +++ b/json/gcovr/index.monotonic_resource.hpp.c7901c306f139d49bdd39970ea9decfb.html @@ -0,0 +1,4558 @@ + + + + + + monotonic_resource.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

monotonic_resource.hpp

+
+ + 100.0% Lines (3/3) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
monotonic_resource.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_MONOTONIC_RESOURCE_HPP
+ 12 + + #define BOOST_JSON_MONOTONIC_RESOURCE_HPP
+ 13 + +
+ 14 + + #include <boost/container/pmr/memory_resource.hpp>
+ 15 + + #include <boost/json/detail/config.hpp>
+ 16 + + #include <boost/json/storage_ptr.hpp>
+ 17 + + #include <cstddef>
+ 18 + + #include <utility>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + +
+ 23 + + #ifdef _MSC_VER
+ 24 + + #pragma warning(push)
+ 25 + + #pragma warning(disable: 4251) // class needs to have dll-interface to be used by clients of class
+ 26 + + #pragma warning(disable: 4275) // non dll-interface class used as base for dll-interface class
+ 27 + + #endif
+ 28 + +
+ 29 + + //----------------------------------------------------------
+ 30 + +
+ 31 + + /** A dynamically allocating resource with a trivial deallocate.
+ 32 + +
+ 33 + + This memory resource is a special-purpose resource that releases allocated
+ 34 + + memory only when the resource is destroyed (or when @ref release is
+ 35 + + called). It has a trivial deallocate function; that is, the metafunction
+ 36 + + @ref is_deallocate_trivial returns `true`.
+ 37 + +
+ 38 + + The resource can be constructed with an initial buffer. If there is no
+ 39 + + initial buffer, or if the buffer is exhausted, subsequent dynamic
+ 40 + + allocations are made from the system heap. The size of buffers obtained in
+ 41 + + this fashion follow a geometric progression.
+ 42 + +
+ 43 + + The purpose of this resource is to optimize the use case for performing
+ 44 + + many allocations, followed by deallocating everything at once. This is
+ 45 + + precisely the pattern of memory allocation which occurs when parsing:
+ 46 + + allocation is performed for each parsed element, and when the the resulting
+ 47 + + @ref value is no longer needed, the entire structure is destroyed. However,
+ 48 + + it is not suited for modifying the value after parsing is complete;
+ 49 + + reallocations waste memory, since the older buffer is not reclaimed until
+ 50 + + the resource is destroyed.
+ 51 + +
+ 52 + + @par Example
+ 53 + +
+ 54 + + This parses a JSON text into a value which uses a local stack buffer, then
+ 55 + + prints the result.
+ 56 + +
+ 57 + + @code
+ 58 + + unsigned char buf[ 4000 ];
+ 59 + + monotonic_resource mr( buf );
+ 60 + +
+ 61 + + // Parse the string, using our memory resource
+ 62 + + auto const jv = parse( "[1,2,3]", &mr );
+ 63 + +
+ 64 + + // Print the JSON
+ 65 + + std::cout << jv;
+ 66 + + @endcode
+ 67 + +
+ 68 + + @note The total amount of memory dynamically allocated is monotonically
+ 69 + + increasing; That is, it never decreases.
+ 70 + +
+ 71 + + @par Thread Safety
+ 72 + + Members of the same instance may not be
+ 73 + + called concurrently.
+ 74 + +
+ 75 + + @see
+ 76 + + https://en.wikipedia.org/wiki/Region-based_memory_management
+ 77 + + */
+ 78 + + class
+ 79 + + BOOST_JSON_DECL
+ 80 + + BOOST_SYMBOL_VISIBLE
+ 81 + + monotonic_resource final
+ 82 + + : public container::pmr::memory_resource
+ 83 + + {
+ 84 + + struct block;
+ 85 + + struct block_base
+ 86 + + {
+ 87 + + void* p;
+ 88 + + std::size_t avail;
+ 89 + + std::size_t size;
+ 90 + + block_base* next;
+ 91 + + };
+ 92 + +
+ 93 + + block_base buffer_;
+ 94 + + block_base* head_ = &buffer_;
+ 95 + + std::size_t next_size_ = 1024;
+ 96 + + storage_ptr upstream_;
+ 97 + +
+ 98 + + static constexpr std::size_t min_size_ = 1024;
+ 99 + + inline static constexpr std::size_t max_size();
+ 100 + + inline static std::size_t round_pow2(
+ 101 + + std::size_t n) noexcept;
+ 102 + + inline static std::size_t next_pow2(
+ 103 + + std::size_t n) noexcept;
+ 104 + +
+ 105 + + public:
+ 106 + + /** Assignment operator.
+ 107 + +
+ 108 + + Copy assignment operator is deleted. This type is not copyable or
+ 109 + + movable.
+ 110 + + */
+ 111 + + monotonic_resource& operator=(
+ 112 + + monotonic_resource const&) = delete;
+ 113 + +
+ 114 + + /** Destructor.
+ 115 + +
+ 116 + + Deallocates all the memory owned by this resource.
+ 117 + +
+ 118 + + @par Effects
+ 119 + + @code
+ 120 + + release();
+ 121 + + @endcode
+ 122 + +
+ 123 + + @par Complexity
+ 124 + + Linear in the number of deallocations performed.
+ 125 + +
+ 126 + + @par Exception Safety
+ 127 + + No-throw guarantee.
+ 128 + + */
+ 129 + + ~monotonic_resource();
+ 130 + +
+ 131 + + /** Constructors.
+ 132 + +
+ 133 + + Construct the resource.
+ 134 + +
+ 135 + + @li **(1)** indicates that the first internal dynamic allocation shall
+ 136 + + be at least `initial_size` bytes.
+ 137 + + @li **(2)**--**(5)** indicate that subsequent allocations should use
+ 138 + + the specified caller-owned buffer. When this buffer is exhausted,
+ 139 + + dynamic allocations from the upstream resource are made.
+ 140 + + @li **(6)** copy constructor is deleted. This type is not copyable or
+ 141 + + movable.
+ 142 + +
+ 143 + + None of the constructors performs any dynamic allocations.
+ 144 + +
+ 145 + + @par Complexity
+ 146 + + Constant.
+ 147 + +
+ 148 + + @par Exception Safety
+ 149 + + No-throw guarantee.
+ 150 + +
+ 151 + + @param initial_size The size of the first internal dynamic allocation.
+ 152 + + If this is lower than the implementation-defined lower limit,
+ 153 + + then the lower limit is used instead.
+ 154 + + @param upstream An optional upstream memory resource to use for
+ 155 + + performing internal dynamic allocations. If this parameter is
+ 156 + + omitted, the \<\<default_memory_resource,default resource\>\> is
+ 157 + + used.
+ 158 + +
+ 159 + + @{
+ 160 + + */
+ 161 + + explicit
+ 162 + + monotonic_resource(
+ 163 + + std::size_t initial_size = 1024,
+ 164 + + storage_ptr upstream = {}) noexcept;
+ 165 + +
+ 166 + + /** Overload
+ 167 + +
+ 168 + + @param buffer The buffer to use. Ownership is not transferred; the
+ 169 + + caller is responsible for ensuring that the lifetime of the
+ 170 + + buffer extends until the resource is destroyed.
+ 171 + + @param size The number of valid bytes pointed to by `buffer`.
+ 172 + + @param upstream
+ 173 + + */
+ 174 + + monotonic_resource(
+ 175 + + unsigned char* buffer,
+ 176 + + std::size_t size,
+ 177 + + storage_ptr upstream = {}) noexcept;
+ 178 + +
+ 179 + + #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
+ 180 + + /// Overload
+ 181 + + monotonic_resource(
+ 182 + + std::byte* buffer,
+ 183 + + std::size_t size,
+ 184 + + storage_ptr upstream) noexcept
+ 185 + + : monotonic_resource(reinterpret_cast<
+ 186 + + unsigned char*>(buffer), size,
+ 187 + + std::move(upstream))
+ 188 + + {
+ 189 + + }
+ 190 + + #endif
+ 191 + +
+ 192 + + /// Overload
+ 193 + + template<std::size_t N>
+ 194 + + explicit
+ 195 + +2 monotonic_resource(
+ 196 + + unsigned char(&buffer)[N],
+ 197 + + storage_ptr upstream = {}) noexcept
+ 198 + + : monotonic_resource(&buffer[0],
+ 199 + +2 N, std::move(upstream))
+ 200 + + {
+ 201 + +2 }
+ 202 + +
+ 203 + + #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
+ 204 + + /// Overload
+ 205 + + template<std::size_t N>
+ 206 + + explicit
+ 207 + + monotonic_resource(
+ 208 + + std::byte(&buffer)[N],
+ 209 + + storage_ptr upstream = {}) noexcept
+ 210 + + : monotonic_resource(&buffer[0],
+ 211 + + N, std::move(upstream))
+ 212 + + {
+ 213 + + }
+ 214 + + #endif
+ 215 + +
+ 216 + + #ifndef BOOST_JSON_DOCS
+ 217 + + // Safety net for accidental buffer overflows
+ 218 + + template<std::size_t N>
+ 219 + + monotonic_resource(
+ 220 + + unsigned char(&buffer)[N],
+ 221 + + std::size_t n,
+ 222 + + storage_ptr upstream = {}) noexcept
+ 223 + + : monotonic_resource(&buffer[0],
+ 224 + + n, std::move(upstream))
+ 225 + + {
+ 226 + + // If this goes off, check your parameters
+ 227 + + // closely, chances are you passed an array
+ 228 + + // thinking it was a pointer.
+ 229 + + BOOST_ASSERT(n <= N);
+ 230 + + }
+ 231 + +
+ 232 + + #ifdef __cpp_lib_byte
+ 233 + + // Safety net for accidental buffer overflows
+ 234 + + template<std::size_t N>
+ 235 + + monotonic_resource(
+ 236 + + std::byte(&buffer)[N],
+ 237 + + std::size_t n,
+ 238 + + storage_ptr upstream = {}) noexcept
+ 239 + + : monotonic_resource(&buffer[0],
+ 240 + + n, std::move(upstream))
+ 241 + + {
+ 242 + + // If this goes off, check your parameters
+ 243 + + // closely, chances are you passed an array
+ 244 + + // thinking it was a pointer.
+ 245 + + BOOST_ASSERT(n <= N);
+ 246 + + }
+ 247 + + #endif
+ 248 + + #endif
+ 249 + +
+ 250 + + /// Overload
+ 251 + + monotonic_resource(
+ 252 + + monotonic_resource const&) = delete;
+ 253 + + /// @}
+ 254 + +
+ 255 + + /** Release all allocated memory.
+ 256 + +
+ 257 + + This function deallocates all allocated memory.
+ 258 + + If an initial buffer was provided upon construction,
+ 259 + + then all of the bytes will be available again for
+ 260 + + allocation. Allocated memory is deallocated even
+ 261 + + if deallocate has not been called for some of
+ 262 + + the allocated blocks.
+ 263 + +
+ 264 + + @par Complexity
+ 265 + + Linear in the number of deallocations performed.
+ 266 + +
+ 267 + + @par Exception Safety
+ 268 + + No-throw guarantee.
+ 269 + + */
+ 270 + + void
+ 271 + + release() noexcept;
+ 272 + +
+ 273 + + protected:
+ 274 + + #ifndef BOOST_JSON_DOCS
+ 275 + + void*
+ 276 + + do_allocate(
+ 277 + + std::size_t n,
+ 278 + + std::size_t align) override;
+ 279 + +
+ 280 + + void
+ 281 + + do_deallocate(
+ 282 + + void* p,
+ 283 + + std::size_t n,
+ 284 + + std::size_t align) override;
+ 285 + +
+ 286 + + bool
+ 287 + + do_is_equal(
+ 288 + + memory_resource const& mr) const noexcept override;
+ 289 + + #endif
+ 290 + + };
+ 291 + +
+ 292 + + #ifdef _MSC_VER
+ 293 + + #pragma warning(pop)
+ 294 + + #endif
+ 295 + +
+ 296 + + template<>
+ 297 + + struct is_deallocate_trivial<
+ 298 + + monotonic_resource>
+ 299 + + {
+ 300 + + static constexpr bool value = true;
+ 301 + + };
+ 302 + +
+ 303 + + } // namespace json
+ 304 + + } // namespace boost
+ 305 + +
+ 306 + + #endif
+ 307 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.monotonic_resource.ipp.05f2ed6d69820a792f84fc5a30acb7c6.html b/json/gcovr/index.monotonic_resource.ipp.05f2ed6d69820a792f84fc5a30acb7c6.html new file mode 100644 index 00000000..c21468df --- /dev/null +++ b/json/gcovr/index.monotonic_resource.ipp.05f2ed6d69820a792f84fc5a30acb7c6.html @@ -0,0 +1,3478 @@ + + + + + + impl/monotonic_resource.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/monotonic_resource.ipp

+
+ + 97.1% Lines (67/69) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/monotonic_resource.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_IMPL_MONOTONIC_RESOURCE_IPP
+ 12 + + #define BOOST_JSON_IMPL_MONOTONIC_RESOURCE_IPP
+ 13 + +
+ 14 + + #include <boost/json/monotonic_resource.hpp>
+ 15 + + #include <boost/json/detail/except.hpp>
+ 16 + + #include <boost/core/max_align.hpp>
+ 17 + +
+ 18 + + #include <memory>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + +
+ 23 + + struct alignas(core::max_align_t)
+ 24 + + monotonic_resource::block : block_base
+ 25 + + {
+ 26 + + };
+ 27 + +
+ 28 + + constexpr
+ 29 + + std::size_t
+ 30 + +164 monotonic_resource::
+ 31 + + max_size()
+ 32 + + {
+ 33 + +164 return std::size_t(-1) - sizeof(block);
+ 34 + + }
+ 35 + +
+ 36 + + // lowest power of 2 greater than or equal to n
+ 37 + + std::size_t
+ 38 + +39 monotonic_resource::
+ 39 + + round_pow2(
+ 40 + + std::size_t n) noexcept
+ 41 + + {
+ 42 + +39 if(n & (n - 1))
+ 43 + +7 return next_pow2(n);
+ 44 + +32 return n;
+ 45 + + }
+ 46 + +
+ 47 + + // lowest power of 2 greater than n
+ 48 + + std::size_t
+ 49 + +51 monotonic_resource::
+ 50 + + next_pow2(
+ 51 + + std::size_t n) noexcept
+ 52 + + {
+ 53 + +51 std::size_t result = min_size_;
+ 54 + +213 while(result <= n)
+ 55 + + {
+ 56 + +163 if(result >= max_size() - result)
+ 57 + + {
+ 58 + + // overflow
+ 59 + +1 result = max_size();
+ 60 + +1 break;
+ 61 + + }
+ 62 + +162 result *= 2;
+ 63 + + }
+ 64 + +51 return result;
+ 65 + + }
+ 66 + +
+ 67 + + //----------------------------------------------------------
+ 68 + +
+ 69 + +47 monotonic_resource::
+ 70 + +47 ~monotonic_resource()
+ 71 + + {
+ 72 + +47 release();
+ 73 + +47 }
+ 74 + +
+ 75 + +37 monotonic_resource::
+ 76 + + monotonic_resource(
+ 77 + + std::size_t initial_size,
+ 78 + +37 storage_ptr upstream) noexcept
+ 79 + +37 : buffer_{
+ 80 + + nullptr, 0, 0, nullptr}
+ 81 + +74 , next_size_(round_pow2(initial_size))
+ 82 + +37 , upstream_(std::move(upstream))
+ 83 + + {
+ 84 + +37 }
+ 85 + +
+ 86 + +10 monotonic_resource::
+ 87 + + monotonic_resource(
+ 88 + + unsigned char* buffer,
+ 89 + + std::size_t size,
+ 90 + +10 storage_ptr upstream) noexcept
+ 91 + +10 : buffer_{
+ 92 + + buffer, size, size, nullptr}
+ 93 + +20 , next_size_(next_pow2(size))
+ 94 + +10 , upstream_(std::move(upstream))
+ 95 + + {
+ 96 + +10 }
+ 97 + +
+ 98 + + void
+ 99 + +48 monotonic_resource::
+ 100 + + release() noexcept
+ 101 + + {
+ 102 + +48 auto p = head_;
+ 103 + +82 while(p != &buffer_)
+ 104 + + {
+ 105 + +34 auto next = p->next;
+ 106 + +34 upstream_->deallocate(p, p->size);
+ 107 + +34 p = next;
+ 108 + + }
+ 109 + +48 buffer_.p = reinterpret_cast<
+ 110 + +48 unsigned char*>(buffer_.p) - (
+ 111 + +48 buffer_.size - buffer_.avail);
+ 112 + +48 buffer_.avail = buffer_.size;
+ 113 + +48 head_ = &buffer_;
+ 114 + +48 }
+ 115 + +
+ 116 + + void*
+ 117 + +129498 monotonic_resource::
+ 118 + + do_allocate(
+ 119 + + std::size_t n,
+ 120 + + std::size_t align)
+ 121 + + {
+ 122 + +129498 auto p = std::align(align, n, head_->p, head_->avail);
+ 123 + +129498 if(p)
+ 124 + + {
+ 125 + +129464 head_->p = reinterpret_cast<
+ 126 + +129464 unsigned char*>(p) + n;
+ 127 + +129464 head_->avail -= n;
+ 128 + +129464 return p;
+ 129 + + }
+ 130 + +
+ 131 + +34 if(next_size_ < n)
+ 132 + +2 next_size_ = round_pow2(n);
+ 133 + +34 auto b = ::new(upstream_->allocate(
+ 134 + +34 sizeof(block) + next_size_)) block;
+ 135 + +34 b->p = b + 1;
+ 136 + +34 b->avail = next_size_;
+ 137 + +34 b->size = next_size_;
+ 138 + +34 b->next = head_;
+ 139 + +34 head_ = b;
+ 140 + +34 next_size_ = next_pow2(next_size_);
+ 141 + +
+ 142 + +34 p = std::align(align, n, head_->p, head_->avail);
+ 143 + +34 BOOST_ASSERT(p);
+ 144 + +34 head_->p = reinterpret_cast<
+ 145 + +34 unsigned char*>(p) + n;
+ 146 + +34 head_->avail -= n;
+ 147 + +34 return p;
+ 148 + + }
+ 149 + +
+ 150 + + void
+ 151 + +29 monotonic_resource::
+ 152 + + do_deallocate(
+ 153 + + void*,
+ 154 + + std::size_t,
+ 155 + + std::size_t)
+ 156 + + {
+ 157 + + // do nothing
+ 158 + +29 }
+ 159 + +
+ 160 + + bool
+ 161 + + monotonic_resource::
+ 162 + + do_is_equal(
+ 163 + + memory_resource const& mr) const noexcept
+ 164 + + {
+ 165 + + return this == &mr;
+ 166 + + }
+ 167 + +
+ 168 + + } // namespace json
+ 169 + + } // namespace boost
+ 170 + +
+ 171 + + #endif
+ 172 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.null_resource.ipp.a960c79e90c931af68e459ac2d12d5fe.html b/json/gcovr/index.null_resource.ipp.a960c79e90c931af68e459ac2d12d5fe.html new file mode 100644 index 00000000..b22c56d9 --- /dev/null +++ b/json/gcovr/index.null_resource.ipp.a960c79e90c931af68e459ac2d12d5fe.html @@ -0,0 +1,2830 @@ + + + + + + impl/null_resource.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/null_resource.ipp

+
+ + 77.8% Lines (7/9) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/null_resource.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_NULL_RESOURCE_IPP
+ 11 + + #define BOOST_JSON_IMPL_NULL_RESOURCE_IPP
+ 12 + +
+ 13 + + #include <boost/json/null_resource.hpp>
+ 14 + + #include <boost/throw_exception.hpp>
+ 15 + +
+ 16 + + namespace boost {
+ 17 + + namespace json {
+ 18 + +
+ 19 + + namespace detail {
+ 20 + +
+ 21 + + /** A resource which always fails.
+ 22 + +
+ 23 + + This memory resource always throws the exception
+ 24 + + `std::bad_alloc` in calls to `allocate`.
+ 25 + + */
+ 26 + + class null_resource final
+ 27 + + : public container::pmr::memory_resource
+ 28 + + {
+ 29 + + public:
+ 30 + + /// Copy constructor (deleted)
+ 31 + + null_resource(
+ 32 + + null_resource const&) = delete;
+ 33 + +
+ 34 + + /// Copy assignment (deleted)
+ 35 + + null_resource& operator=(
+ 36 + + null_resource const&) = delete;
+ 37 + +
+ 38 + + /** Constructor
+ 39 + +
+ 40 + + This constructs the resource.
+ 41 + +
+ 42 + + @par Complexity
+ 43 + + Constant.
+ 44 + +
+ 45 + + @par Exception Safety
+ 46 + + No-throw guarantee.
+ 47 + + */
+ 48 + + /** @{ */
+ 49 + + null_resource() noexcept = default;
+ 50 + +
+ 51 + + protected:
+ 52 + + void*
+ 53 + +3 do_allocate(
+ 54 + + std::size_t,
+ 55 + + std::size_t) override
+ 56 + + {
+ 57 + +6 throw_exception( std::bad_alloc(), BOOST_CURRENT_LOCATION );
+ 58 + + }
+ 59 + +
+ 60 + + void
+ 61 + +1 do_deallocate(
+ 62 + + void*,
+ 63 + + std::size_t,
+ 64 + + std::size_t) override
+ 65 + + {
+ 66 + + // do nothing
+ 67 + +1 }
+ 68 + +
+ 69 + + bool
+ 70 + + do_is_equal(
+ 71 + + memory_resource const& mr
+ 72 + + ) const noexcept override
+ 73 + + {
+ 74 + + return this == &mr;
+ 75 + + }
+ 76 + + };
+ 77 + +
+ 78 + + } // detail
+ 79 + +
+ 80 + + container::pmr::memory_resource*
+ 81 + +10 get_null_resource() noexcept
+ 82 + + {
+ 83 + +10 static detail::null_resource mr;
+ 84 + +10 return &mr;
+ 85 + + }
+ 86 + +
+ 87 + + } // namespace json
+ 88 + + } // namespace boost
+ 89 + +
+ 90 + + #endif
+ 91 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.object.hpp.4af583e26a117226f5f096905dacf35c.html b/json/gcovr/index.object.hpp.4af583e26a117226f5f096905dacf35c.html new file mode 100644 index 00000000..c77b19a4 --- /dev/null +++ b/json/gcovr/index.object.hpp.4af583e26a117226f5f096905dacf35c.html @@ -0,0 +1,13566 @@ + + + + + + object.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

object.hpp

+
+ + 100.0% Lines (37/37) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
object.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_OBJECT_HPP
+ 11 + + #define BOOST_JSON_OBJECT_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/json/detail/object.hpp>
+ 15 + + #include <boost/json/detail/value.hpp>
+ 16 + + #include <boost/json/kind.hpp>
+ 17 + + #include <boost/json/pilfer.hpp>
+ 18 + + #include <boost/system/result.hpp>
+ 19 + + #include <boost/json/storage_ptr.hpp>
+ 20 + + #include <boost/json/string_view.hpp>
+ 21 + + #include <cstdlib>
+ 22 + + #include <initializer_list>
+ 23 + + #include <iterator>
+ 24 + + #include <type_traits>
+ 25 + + #include <utility>
+ 26 + +
+ 27 + + namespace boost {
+ 28 + + namespace json {
+ 29 + +
+ 30 + + class value;
+ 31 + + class value_ref;
+ 32 + + class key_value_pair;
+ 33 + +
+ 34 + + /** A dynamically sized associative container of JSON key/value pairs.
+ 35 + +
+ 36 + + This is an associative container whose elements are key/value pairs with
+ 37 + + unique keys.
+ 38 + +
+ 39 + + The elements are stored contiguously; iterators are ordinary pointers,
+ 40 + + allowing random access pointer arithmetic for retrieving elements. In
+ 41 + + addition, the container maintains an internal index to speed up find
+ 42 + + operations, reducing the average complexity for most lookups and
+ 43 + + insertions.
+ 44 + +
+ 45 + + Reallocations are usually costly operations in terms of performance, as
+ 46 + + elements are copied and the internal index must be rebuilt. The @ref
+ 47 + + reserve function can be used to eliminate reallocations if the number of
+ 48 + + elements is known beforehand.
+ 49 + +
+ 50 + + @par Allocators
+ 51 + + All elements stored in the container, and their children if any, will use
+ 52 + + the same memory resource that was used to construct the container.
+ 53 + +
+ 54 + + @par Thread Safety
+ 55 + + Non-const member functions may not be called concurrently with any other
+ 56 + + member functions.
+ 57 + +
+ 58 + + @par Satisfies
+ 59 + + [ContiguousContainer](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
+ 60 + + [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer), and
+ 61 + + {req_SequenceContainer}.
+ 62 + + */
+ 63 + + class object
+ 64 + + {
+ 65 + + struct table;
+ 66 + + class revert_construct;
+ 67 + + class revert_insert;
+ 68 + + friend class value;
+ 69 + + friend class object_test;
+ 70 + + using access = detail::access;
+ 71 + + using index_t = std::uint32_t;
+ 72 + + static index_t constexpr null_index_ =
+ 73 + + std::uint32_t(-1);
+ 74 + +
+ 75 + + storage_ptr sp_; // must come first
+ 76 + + kind k_ = kind::object; // must come second
+ 77 + + table* t_;
+ 78 + +
+ 79 + + BOOST_JSON_DECL
+ 80 + + static table empty_;
+ 81 + +
+ 82 + + template<class T>
+ 83 + + using is_inputit = typename std::enable_if<
+ 84 + + std::is_constructible<key_value_pair,
+ 85 + + typename std::iterator_traits<T>::reference
+ 86 + + >::value>::type;
+ 87 + +
+ 88 + + BOOST_JSON_DECL
+ 89 + + explicit
+ 90 + + object(detail::unchecked_object&& uo);
+ 91 + +
+ 92 + + public:
+ 93 + + /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
+ 94 + + using allocator_type = container::pmr::polymorphic_allocator<value>;
+ 95 + +
+ 96 + + /** The type of keys.
+ 97 + +
+ 98 + + The function @ref string::max_size returns the
+ 99 + + maximum allowed size of strings used as keys.
+ 100 + + */
+ 101 + + using key_type = string_view;
+ 102 + +
+ 103 + + /// The type of mapped values
+ 104 + + using mapped_type = value;
+ 105 + +
+ 106 + + /// The element type
+ 107 + + using value_type = key_value_pair;
+ 108 + +
+ 109 + + /// The type used to represent unsigned integers
+ 110 + + using size_type = std::size_t;
+ 111 + +
+ 112 + + /// The type used to represent signed integers
+ 113 + + using difference_type = std::ptrdiff_t;
+ 114 + +
+ 115 + + /// A reference to an element
+ 116 + + using reference = value_type&;
+ 117 + +
+ 118 + + /// A const reference to an element
+ 119 + + using const_reference = value_type const&;
+ 120 + +
+ 121 + + /// A pointer to an element
+ 122 + + using pointer = value_type*;
+ 123 + +
+ 124 + + /// A const pointer to an element
+ 125 + + using const_pointer = value_type const*;
+ 126 + +
+ 127 + + /// A random access iterator to an element
+ 128 + + using iterator = value_type*;
+ 129 + +
+ 130 + + /// A const random access iterator to an element
+ 131 + + using const_iterator = value_type const*;
+ 132 + +
+ 133 + + /// A reverse random access iterator to an element
+ 134 + + using reverse_iterator =
+ 135 + + std::reverse_iterator<iterator>;
+ 136 + +
+ 137 + + /// A const reverse random access iterator to an element
+ 138 + + using const_reverse_iterator =
+ 139 + + std::reverse_iterator<const_iterator>;
+ 140 + +
+ 141 + + //------------------------------------------------------
+ 142 + +
+ 143 + + /** Destructor.
+ 144 + +
+ 145 + + The destructor for each element is called if needed, any used memory is
+ 146 + + deallocated, and shared ownership of the
+ 147 + + @ref boost::container::pmr::memory_resource is released.
+ 148 + +
+ 149 + + @par Complexity
+ 150 + + Constant, or linear in @ref size().
+ 151 + +
+ 152 + + @par Exception Safety
+ 153 + + No-throw guarantee.
+ 154 + + */
+ 155 + + BOOST_JSON_DECL
+ 156 + + ~object() noexcept;
+ 157 + +
+ 158 + + //------------------------------------------------------
+ 159 + +
+ 160 + + /** Constructors.
+ 161 + +
+ 162 + + Constructs an object.
+ 163 + +
+ 164 + + @li **(1)**--**(3)** the object is empty.
+ 165 + +
+ 166 + + @li **(4)** the object is filled with values in the range
+ 167 + + `[first, last)`.
+ 168 + +
+ 169 + + @li **(5)**, **(6)** the object is filled with copies of the values in
+ 170 + + `init`.
+ 171 + +
+ 172 + + @li **(7)**, **(8)** the object is filled with copies of the elements
+ 173 + + of `other`.
+ 174 + +
+ 175 + + @li **(9)** the object acquires ownership of the contents of `other`.
+ 176 + +
+ 177 + + @li **(10)** equivalent to **(9)** if `*sp == *other.storage()`;
+ 178 + + otherwise equivalent to **(8)**.
+ 179 + +
+ 180 + + @li **(11)** the object acquires ownership of the contents of `other`
+ 181 + + using pilfer semantics. This is more efficient than move
+ 182 + + construction, when it is known that the moved-from object will be
+ 183 + + immediately destroyed afterwards.
+ 184 + +
+ 185 + + Upon construction, @ref capacity() will be large enough to store the
+ 186 + + object's elements. In addition, with **(3)**, **(4)**, and **(6)** the
+ 187 + + capacity will not be smaller than `min_capacity`.
+ 188 + +
+ 189 + + With **(2)**--**(6)**, **(8)**, **(10)** the constructed object uses
+ 190 + + memory resource of `sp`. With **(7)**, **(9)**, **(11)** it uses
+ 191 + + `other`'s memory resource. In either case the object will share the
+ 192 + + ownership of the memory resource. With **(1)** it uses the
+ 193 + + \<\<default_memory_resource,default memory resource\>\>.
+ 194 + +
+ 195 + + After **(9)** `other` behaves as if newly constructed with its current
+ 196 + + storage pointer.
+ 197 + +
+ 198 + + After **(11)** `other` is not in a usable state and may only be
+ 199 + + destroyed.
+ 200 + +
+ 201 + + If `init` or `[first, last)` have elements with duplicate keys, only
+ 202 + + the first of those equivalent elements will be inserted.
+ 203 + +
+ 204 + + @par Constraints
+ 205 + + @code
+ 206 + + std::is_constructible_v<
+ 207 + + key_value_pair,
+ 208 + + std::iterator_traits<InputIt>::reference>
+ 209 + + @endcode
+ 210 + +
+ 211 + + @par Complexity
+ 212 + + @li **(1)**--**(3)**, **(9)**, **(11)** constant.
+ 213 + + @li **(4)** linear in `std::distance(first, last)`.
+ 214 + + @li **(5)**, **(6)** linear in `init.size()`.
+ 215 + + @li **(7)**, **(8)** linear in `other.size()`.
+ 216 + + @li **(10)** constant if `*sp == *other.storage()`; otherwise linear in
+ 217 + + `other.size()`.
+ 218 + +
+ 219 + + @par Exception Safety
+ 220 + + @li **(1)**, **(2)**, **(9)**, **(11)** no-throw guarantee.
+ 221 + + @li **(3)**, **(5)**, **(6)**--**(8)**, **(10)** strong guarantee.
+ 222 + + @li **(4)** strong guarantee if `InputIt` satisfies
+ 223 + + {req_ForwardIterator}, basic guarantee otherwise.
+ 224 + +
+ 225 + + Calls to `memory_resource::allocate` may throw.
+ 226 + +
+ 227 + + @see @ref pilfer,
+ 228 + + [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
+ 229 + +
+ 230 + + @{
+ 231 + + */
+ 232 + +77 object() noexcept
+ 233 + +77 : t_(&empty_)
+ 234 + + {
+ 235 + +77 }
+ 236 + +
+ 237 + + /** Overload
+ 238 + +
+ 239 + + @param sp A pointer to the @ref boost::container::pmr::memory_resource
+ 240 + + to use.
+ 241 + + */
+ 242 + + explicit
+ 243 + +485 object(storage_ptr sp) noexcept
+ 244 + +485 : sp_(std::move(sp))
+ 245 + +485 , t_(&empty_)
+ 246 + + {
+ 247 + +485 }
+ 248 + +
+ 249 + + /** Overload
+ 250 + +
+ 251 + + @param min_capacity The minimum number of elements for which capacity
+ 252 + + is guaranteed without a subsequent reallocation.
+ 253 + + @param sp
+ 254 + + */
+ 255 + + BOOST_JSON_DECL
+ 256 + + object(
+ 257 + + std::size_t min_capacity,
+ 258 + + storage_ptr sp = {});
+ 259 + +
+ 260 + + /** Overload
+ 261 + +
+ 262 + + @param first An input iterator pointing to the first element to insert,
+ 263 + + or pointing to the end of the range.
+ 264 + + @param last An input iterator pointing to the end of the range.
+ 265 + + @param min_capacity
+ 266 + + @param sp
+ 267 + +
+ 268 + + @tparam InputIt a type satisfying the requirements of
+ 269 + + {req_InputIterator}.
+ 270 + + */
+ 271 + + template<
+ 272 + + class InputIt
+ 273 + + #ifndef BOOST_JSON_DOCS
+ 274 + + ,class = is_inputit<InputIt>
+ 275 + + #endif
+ 276 + + >
+ 277 + +160 object(
+ 278 + + InputIt first,
+ 279 + + InputIt last,
+ 280 + + std::size_t min_capacity = 0,
+ 281 + + storage_ptr sp = {})
+ 282 + +160 : sp_(std::move(sp))
+ 283 + +160 , t_(&empty_)
+ 284 + + {
+ 285 + +160 construct(
+ 286 + + first, last,
+ 287 + + min_capacity,
+ 288 + + typename std::iterator_traits<
+ 289 + + InputIt>::iterator_category{});
+ 290 + +160 }
+ 291 + +
+ 292 + + /** Overload
+ 293 + +
+ 294 + + @param init The initializer list to insert.
+ 295 + + @param sp
+ 296 + + */
+ 297 + +339 object(
+ 298 + + std::initializer_list<
+ 299 + + std::pair<string_view, value_ref>> init,
+ 300 + + storage_ptr sp = {})
+ 301 + +339 : object(init, 0, std::move(sp))
+ 302 + + {
+ 303 + +246 }
+ 304 + +
+ 305 + + /** Overload
+ 306 + +
+ 307 + + @param init
+ 308 + + @param min_capacity
+ 309 + + @param sp
+ 310 + + */
+ 311 + + BOOST_JSON_DECL
+ 312 + + object(
+ 313 + + std::initializer_list<
+ 314 + + std::pair<string_view, value_ref>> init,
+ 315 + + std::size_t min_capacity,
+ 316 + + storage_ptr sp = {});
+ 317 + +
+ 318 + + /** Overload
+ 319 + +
+ 320 + + @param other Another object.
+ 321 + + */
+ 322 + +13 object(
+ 323 + + object const& other)
+ 324 + +13 : object(other, other.sp_)
+ 325 + + {
+ 326 + +13 }
+ 327 + +
+ 328 + + /** Overload
+ 329 + +
+ 330 + + @param other
+ 331 + + @param sp
+ 332 + + */
+ 333 + + BOOST_JSON_DECL
+ 334 + + object(
+ 335 + + object const& other,
+ 336 + + storage_ptr sp);
+ 337 + +
+ 338 + + /** Overload
+ 339 + +
+ 340 + + @param other
+ 341 + + */
+ 342 + + BOOST_JSON_DECL
+ 343 + + object(object&& other) noexcept;
+ 344 + +
+ 345 + + /** Overload
+ 346 + +
+ 347 + + @param other
+ 348 + + @param sp
+ 349 + + */
+ 350 + + BOOST_JSON_DECL
+ 351 + + object(
+ 352 + + object&& other,
+ 353 + + storage_ptr sp);
+ 354 + +
+ 355 + + /** Overload
+ 356 + +
+ 357 + + @param other
+ 358 + + */
+ 359 + +17 object(pilfered<object> other) noexcept
+ 360 + +17 : sp_(std::move(other.get().sp_))
+ 361 + +34 , t_(detail::exchange(
+ 362 + +17 other.get().t_, &empty_))
+ 363 + + {
+ 364 + +17 }
+ 365 + + /// @}
+ 366 + +
+ 367 + + //------------------------------------------------------
+ 368 + + //
+ 369 + + // Assignment
+ 370 + + //
+ 371 + + //------------------------------------------------------
+ 372 + +
+ 373 + + /** Assignment operators.
+ 374 + +
+ 375 + + Replaces the contents of this object.
+ 376 + +
+ 377 + + @li **(1)** replaces with the copies of the elements of `other`.
+ 378 + + @li **(2)** takes ownership of `other`'s element storage if
+ 379 + + `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
+ 380 + + @li **(3)** replaces with the elements of `init`.
+ 381 + +
+ 382 + + @par Complexity
+ 383 + + @li **(1)** linear in `size() + other.size()`.
+ 384 + + @li **(2)** constant if `*storage() == *other.storage()`; otherwise
+ 385 + + linear in `size() + other.size()`.
+ 386 + + @li **(3)** average case linear in `size() + init.size()`, worst case
+ 387 + + quadratic in `init.size()`.
+ 388 + +
+ 389 + + @par Exception Safety
+ 390 + + @li **(1)**, **(3)** strong guarantee.
+ 391 + + @li **(2)** no-throw guarantee if `*storage() == *other.storage()`;
+ 392 + + otherwise strong guarantee.
+ 393 + +
+ 394 + + Calls to `memory_resource::allocate` may throw.
+ 395 + +
+ 396 + + @par Complexity
+ 397 + +
+ 398 + + @param other Another object.
+ 399 + +
+ 400 + + @{
+ 401 + + */
+ 402 + + BOOST_JSON_DECL
+ 403 + + object&
+ 404 + + operator=(object const& other);
+ 405 + +
+ 406 + + BOOST_JSON_DECL
+ 407 + + object&
+ 408 + + operator=(object&& other);
+ 409 + +
+ 410 + + /** Overload
+ 411 + +
+ 412 + + @param init The initializer list to copy.
+ 413 + + */
+ 414 + + BOOST_JSON_DECL
+ 415 + + object&
+ 416 + + operator=(std::initializer_list<
+ 417 + + std::pair<string_view, value_ref>> init);
+ 418 + + /// @}
+ 419 + +
+ 420 + + //------------------------------------------------------
+ 421 + +
+ 422 + + /** Return the associated memory resource.
+ 423 + +
+ 424 + + This function returns a smart pointer to the
+ 425 + + @ref boost::container::pmr::memory_resource used by the container.
+ 426 + +
+ 427 + + @par Complexity
+ 428 + + Constant.
+ 429 + +
+ 430 + + @par Exception Safety
+ 431 + + No-throw guarantee.
+ 432 + + */
+ 433 + + storage_ptr const&
+ 434 + +680 storage() const noexcept
+ 435 + + {
+ 436 + +680 return sp_;
+ 437 + + }
+ 438 + +
+ 439 + + /** Return the associated allocator.
+ 440 + +
+ 441 + + This function returns an instance of @ref allocator_type constructed
+ 442 + + from the associated @ref boost::container::pmr::memory_resource.
+ 443 + +
+ 444 + + @par Complexity
+ 445 + + Constant.
+ 446 + +
+ 447 + + @par Exception Safety
+ 448 + + No-throw guarantee.
+ 449 + + */
+ 450 + + allocator_type
+ 451 + +1 get_allocator() const noexcept
+ 452 + + {
+ 453 + +1 return sp_.get();
+ 454 + + }
+ 455 + +
+ 456 + + //------------------------------------------------------
+ 457 + + //
+ 458 + + // Iterators
+ 459 + + //
+ 460 + + //------------------------------------------------------
+ 461 + +
+ 462 + + /** Return an iterator to the first element.
+ 463 + +
+ 464 + + If the container is empty, @ref end() is returned.
+ 465 + +
+ 466 + + @par Complexity
+ 467 + + Constant.
+ 468 + +
+ 469 + + @par Exception Safety
+ 470 + + No-throw guarantee.
+ 471 + +
+ 472 + + @{
+ 473 + + */
+ 474 + + inline
+ 475 + + iterator
+ 476 + + begin() noexcept;
+ 477 + +
+ 478 + + inline
+ 479 + + const_iterator
+ 480 + + begin() const noexcept;
+ 481 + + /// @}
+ 482 + +
+ 483 + + /** Return a const iterator to the first element.
+ 484 + +
+ 485 + + If the container is empty, @ref cend() is returned.
+ 486 + +
+ 487 + + @par Complexity
+ 488 + + Constant.
+ 489 + +
+ 490 + + @par Exception Safety
+ 491 + + No-throw guarantee.
+ 492 + + */
+ 493 + + inline
+ 494 + + const_iterator
+ 495 + + cbegin() const noexcept;
+ 496 + +
+ 497 + + /** Return an iterator to the element following the last element.
+ 498 + +
+ 499 + + The element acts as a placeholder; attempting
+ 500 + + to access it results in undefined behavior.
+ 501 + +
+ 502 + + @par Complexity
+ 503 + + Constant.
+ 504 + +
+ 505 + + @par Exception Safety
+ 506 + + No-throw guarantee.
+ 507 + +
+ 508 + + @{
+ 509 + + */
+ 510 + + inline
+ 511 + + iterator
+ 512 + + end() noexcept;
+ 513 + +
+ 514 + + inline
+ 515 + + const_iterator
+ 516 + + end() const noexcept;
+ 517 + + /// @}
+ 518 + +
+ 519 + + /** Return a const iterator to the element following the last element.
+ 520 + +
+ 521 + + The element acts as a placeholder; attempting
+ 522 + + to access it results in undefined behavior.
+ 523 + +
+ 524 + + @par Complexity
+ 525 + + Constant.
+ 526 + +
+ 527 + + @par Exception Safety
+ 528 + + No-throw guarantee.
+ 529 + + */
+ 530 + + inline
+ 531 + + const_iterator
+ 532 + + cend() const noexcept;
+ 533 + +
+ 534 + + /** Return a reverse iterator to the first element of the reversed container.
+ 535 + +
+ 536 + + The pointed-to element corresponds to the last element of the
+ 537 + + non-reversed container. If the container is empty, @ref rend() is
+ 538 + + returned.
+ 539 + +
+ 540 + + @par Complexity
+ 541 + + Constant.
+ 542 + +
+ 543 + + @par Exception Safety
+ 544 + + No-throw guarantee.
+ 545 + +
+ 546 + + @{
+ 547 + + */
+ 548 + + inline
+ 549 + + reverse_iterator
+ 550 + + rbegin() noexcept;
+ 551 + +
+ 552 + + inline
+ 553 + + const_reverse_iterator
+ 554 + + rbegin() const noexcept;
+ 555 + + /// @}
+ 556 + +
+ 557 + + /** Return a const reverse iterator to the first element of the reversed container.
+ 558 + +
+ 559 + + The pointed-to element corresponds to the
+ 560 + + last element of the non-reversed container.
+ 561 + + If the container is empty, @ref crend() is returned.
+ 562 + +
+ 563 + + @par Complexity
+ 564 + + Constant.
+ 565 + +
+ 566 + + @par Exception Safety
+ 567 + + No-throw guarantee.
+ 568 + + */
+ 569 + + inline
+ 570 + + const_reverse_iterator
+ 571 + + crbegin() const noexcept;
+ 572 + +
+ 573 + + /** Return a reverse iterator to the element following the last element of the reversed container.
+ 574 + +
+ 575 + + The pointed-to element corresponds to the element preceding the first
+ 576 + + element of the non-reversed container. The returned iterator only acts
+ 577 + + as a sentinel. Dereferencing it results in undefined behavior.
+ 578 + +
+ 579 + + @par Complexity
+ 580 + + Constant.
+ 581 + +
+ 582 + + @par Exception Safety
+ 583 + + No-throw guarantee.
+ 584 + +
+ 585 + + @{
+ 586 + + */
+ 587 + + inline
+ 588 + + reverse_iterator
+ 589 + + rend() noexcept;
+ 590 + +
+ 591 + + inline
+ 592 + + const_reverse_iterator
+ 593 + + rend() const noexcept;
+ 594 + + /// @}
+ 595 + +
+ 596 + + /** Return a const reverse iterator to the element following the last element of the reversed container.
+ 597 + +
+ 598 + + The pointed-to element corresponds to the element preceding the first
+ 599 + + element of the non-reversed container. The returned iterator only acts
+ 600 + + as a sentinel. Dereferencing it results in undefined behavior.
+ 601 + +
+ 602 + + @par Complexity
+ 603 + + Constant.
+ 604 + +
+ 605 + + @par Exception Safety
+ 606 + + No-throw guarantee.
+ 607 + + */
+ 608 + + inline
+ 609 + + const_reverse_iterator
+ 610 + + crend() const noexcept;
+ 611 + +
+ 612 + + //------------------------------------------------------
+ 613 + + //
+ 614 + + // Capacity
+ 615 + + //
+ 616 + + //------------------------------------------------------
+ 617 + +
+ 618 + + /** Return whether there are no elements.
+ 619 + +
+ 620 + + Returns `true` if there are no elements in
+ 621 + + the container, i.e. @ref size() returns 0.
+ 622 + +
+ 623 + + @par Complexity
+ 624 + + Constant.
+ 625 + +
+ 626 + + @par Exception Safety
+ 627 + + No-throw guarantee.
+ 628 + + */
+ 629 + + inline
+ 630 + + bool
+ 631 + + empty() const noexcept;
+ 632 + +
+ 633 + + /** Return the number of elements.
+ 634 + +
+ 635 + + This returns the number of elements in the container.
+ 636 + +
+ 637 + + @par Complexity
+ 638 + + Constant.
+ 639 + +
+ 640 + + @par Exception Safety
+ 641 + + No-throw guarantee.
+ 642 + + */
+ 643 + + inline
+ 644 + + std::size_t
+ 645 + + size() const noexcept;
+ 646 + +
+ 647 + + /** The maximum number of elements an object can hold.
+ 648 + +
+ 649 + + The maximum is an implementation-defined number dependent on system or
+ 650 + + library implementation. This value is a theoretical limit; at runtime,
+ 651 + + the actual maximum size may be less due to resource limits.
+ 652 + +
+ 653 + + @par Complexity
+ 654 + + Constant.
+ 655 + +
+ 656 + + @par Exception Safety
+ 657 + + No-throw guarantee.
+ 658 + + */
+ 659 + + static
+ 660 + + constexpr
+ 661 + + std::size_t
+ 662 + + max_size() noexcept;
+ 663 + +
+ 664 + + /** Return the number of elements that can be held in currently allocated memory.
+ 665 + +
+ 666 + + Returns the number of elements that the container has currently
+ 667 + + allocated space for. This number is never smaller than the value
+ 668 + + returned by @ref size().
+ 669 + +
+ 670 + + @par Complexity
+ 671 + + Constant.
+ 672 + +
+ 673 + + @par Exception Safety
+ 674 + + No-throw guarantee.
+ 675 + + */
+ 676 + + inline
+ 677 + + std::size_t
+ 678 + + capacity() const noexcept;
+ 679 + +
+ 680 + + /** Increase the capacity to at least a certain amount.
+ 681 + +
+ 682 + + This increases the @ref capacity() to a value that is greater than or
+ 683 + + equal to `new_capacity`. If `new_capacity > capacity()`, new memory is
+ 684 + + allocated. Otherwise, the call has no effect. The number of elements
+ 685 + + and therefore the @ref size() of the container is not changed.
+ 686 + +
+ 687 + + If new memory is allocated, all iterators including any past-the-end
+ 688 + + iterators, and all references to the elements are invalidated.
+ 689 + + Otherwise, no iterators or references are invalidated.
+ 690 + +
+ 691 + + @par Complexity
+ 692 + + Constant if no reallocation occurs. Otherwise, average case linear in
+ 693 + + @ref size(), worst case quadratic in @ref size().
+ 694 + +
+ 695 + + @par Exception Safety
+ 696 + + Strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 697 + +
+ 698 + + @param new_capacity The new minimum capacity.
+ 699 + +
+ 700 + + @throw boost::system::system_error `new_capacity >` @ref max_size().
+ 701 + + */
+ 702 + + inline
+ 703 + + void
+ 704 + + reserve(std::size_t new_capacity);
+ 705 + +
+ 706 + + //------------------------------------------------------
+ 707 + + //
+ 708 + + // Modifiers
+ 709 + + //
+ 710 + + //------------------------------------------------------
+ 711 + +
+ 712 + + /** Erase all elements.
+ 713 + +
+ 714 + + Erases all elements from the container. After this call, @ref size()
+ 715 + + returns zero but @ref capacity() is unchanged. All references,
+ 716 + + pointers, and iterators are invalidated.
+ 717 + +
+ 718 + + @par Complexity
+ 719 + + Linear in @ref size().
+ 720 + +
+ 721 + + @par Exception Safety
+ 722 + + No-throw guarantee.
+ 723 + + */
+ 724 + + BOOST_JSON_DECL
+ 725 + + void
+ 726 + + clear() noexcept;
+ 727 + +
+ 728 + + /** Insert elements.
+ 729 + +
+ 730 + + @li **(1)** inserts a new element constructed as if via
+ 731 + + `value_type( std::forward<P>(p) )`.
+ 732 + + @li **(2)** the elements in the range `[first, last)` are inserted one
+ 733 + + at a time, in order.
+ 734 + + @li **(3)** the elements in the initializer list are inserted one at a
+ 735 + + time, in order.
+ 736 + +
+ 737 + + Any element with key that is a duplicate of a key already present in
+ 738 + + container will be skipped. This also means, that if there are two keys
+ 739 + + within the inserted range that are equal to each other, only the
+ 740 + + first will be inserted.
+ 741 + +
+ 742 + + If an insertion would result in the new number of elements exceeding
+ 743 + + @ref capacity(), a reallocation and a rehashing occur. In that case all
+ 744 + + iterators and references are invalidated. Otherwise, they are not
+ 745 + + affected.
+ 746 + +
+ 747 + + @pre
+ 748 + + `first` and `last` are not iterators into `*this`. `first` and `last`
+ 749 + + form a valid range.
+ 750 + +
+ 751 + + @par Constraints
+ 752 + + @code
+ 753 + + std::is_constructible_v<value_type, P>
+ 754 + + std::is_constructible_v<value_type, std::iterator_traits<InputIt>::reference>
+ 755 + + @endcode
+ 756 + +
+ 757 + + @par Complexity
+ 758 + + @li **(1)** constant on average, worst case linear in @ref size().
+ 759 + + @li **(2)** linear in `std::distance(first, last)`.
+ 760 + + @li **(3)** linear in `init.size()`.
+ 761 + +
+ 762 + + @par Exception Safety
+ 763 + + @li **(1)** strong guarantee.
+ 764 + + @li **(2)** strong guarantee if `InputIt` satisfies
+ 765 + + {req_ForwardIterator}, basic guarantee otherwise.
+ 766 + + @li **(3)** basic guarantee.
+ 767 + +
+ 768 + + Calls to `memory_resource::allocate` may throw.
+ 769 + +
+ 770 + + @param p The value to insert.
+ 771 + +
+ 772 + + @throw boost::system::system_error The size of a key would exceed
+ 773 + + @ref string::max_size.
+ 774 + + @throw `boost::system::system_error` @ref size() >= @ref max_size().
+ 775 + +
+ 776 + + @return **(1)** returns a @ref std::pair where `first` is an iterator
+ 777 + + to the existing or inserted element, and `second` is `true` if the
+ 778 + + insertion took place or `false` otherwise. **(2)** returns `void`.
+ 779 + +
+ 780 + + @{
+ 781 + + */
+ 782 + + template<class P
+ 783 + + #ifndef BOOST_JSON_DOCS
+ 784 + + ,class = typename std::enable_if<
+ 785 + + std::is_constructible<key_value_pair,
+ 786 + + P, storage_ptr>::value>::type
+ 787 + + #endif
+ 788 + + >
+ 789 + + std::pair<iterator, bool>
+ 790 + + insert(P&& p);
+ 791 + +
+ 792 + + /** Overload
+ 793 + +
+ 794 + + @param first An input iterator pointing to the first element to insert,
+ 795 + + or pointing to the end of the range.
+ 796 + +
+ 797 + + @param last An input iterator pointing to the end of the range.
+ 798 + +
+ 799 + + @tparam InputIt a type satisfying the requirements
+ 800 + + of {req_InputIterator}.
+ 801 + + */
+ 802 + + template<
+ 803 + + class InputIt
+ 804 + + #ifndef BOOST_JSON_DOCS
+ 805 + + ,class = is_inputit<InputIt>
+ 806 + + #endif
+ 807 + + >
+ 808 + + void
+ 809 + +174 insert(InputIt first, InputIt last)
+ 810 + + {
+ 811 + +174 insert(first, last, typename
+ 812 + + std::iterator_traits<InputIt
+ 813 + + >::iterator_category{});
+ 814 + +8 }
+ 815 + +
+ 816 + + /** Overload
+ 817 + +
+ 818 + + @param init The initializer list to insert.
+ 819 + + */
+ 820 + + BOOST_JSON_DECL
+ 821 + + void
+ 822 + + insert(std::initializer_list<
+ 823 + + std::pair<string_view, value_ref>> init);
+ 824 + + /// @}
+ 825 + +
+ 826 + + /** Insert an element or assign to an existing element.
+ 827 + +
+ 828 + + If the key equal to `key` already exists in the container, assigns
+ 829 + + `std::forward<M>(m)` to the @ref mapped_type corresponding to that key.
+ 830 + + Otherwise, inserts the as if by @ref insert, constructing it using
+ 831 + + `value_type(key, std::forward<M>(m))`.
+ 832 + +
+ 833 + + If insertion would result in the new number of elements exceeding
+ 834 + + @ref capacity(), a reallocation and a rehashing occur. In that case all
+ 835 + + iterators and references are invalidated. Otherwise, they are not
+ 836 + + affected.
+ 837 + +
+ 838 + + @par Complexity
+ 839 + + Constant on average, worst case linear in @ref size().
+ 840 + +
+ 841 + + @par Exception Safety
+ 842 + + Strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 843 + +
+ 844 + + @return A @ref std::pair where `first` is an iterator to the existing
+ 845 + + or inserted element, and `second` is `true` if the insertion took place
+ 846 + + or `false` if the assignment took place.
+ 847 + +
+ 848 + + @param key The key used for lookup and insertion.
+ 849 + + @param m The value to insert or assign.
+ 850 + +
+ 851 + + @throw boost::system::system_error The size of a key would exceed
+ 852 + + @ref string::max_size.
+ 853 + + */
+ 854 + + template<class M>
+ 855 + + std::pair<iterator, bool>
+ 856 + + insert_or_assign(
+ 857 + + string_view key, M&& m);
+ 858 + +
+ 859 + + /** Construct an element in-place.
+ 860 + +
+ 861 + + Inserts a new element into the container constructed
+ 862 + + in-place with the given argument if there is no
+ 863 + + element with the `key` in the container.
+ 864 + +
+ 865 + + If the insertion occurs and results in a rehashing of the container,
+ 866 + + all iterators and references are invalidated. Otherwise, they are not
+ 867 + + affected. Rehashing occurs only if the new number of elements is
+ 868 + + greater than @ref capacity().
+ 869 + +
+ 870 + + @par Complexity
+ 871 + + Constant on average, worst case linear in @ref size().
+ 872 + +
+ 873 + + @par Exception Safety
+ 874 + + Strong guarantee.
+ 875 + + Calls to `memory_resource::allocate` may throw.
+ 876 + +
+ 877 + + @return A @ref std::pair where `first` is an iterator
+ 878 + + to the existing or inserted element, and `second`
+ 879 + + is `true` if the insertion took place or `false` otherwise.
+ 880 + +
+ 881 + + @param key The key used for lookup and insertion.
+ 882 + +
+ 883 + + @param arg The argument used to construct the value.
+ 884 + + This will be passed as `std::forward<Arg>(arg)` to
+ 885 + + the @ref value constructor.
+ 886 + +
+ 887 + + @throw boost::system::system_error The size of the key would exceed
+ 888 + + @ref string::max_size.
+ 889 + +
+ 890 + + */
+ 891 + + template<class Arg>
+ 892 + + std::pair<iterator, bool>
+ 893 + + emplace(string_view key, Arg&& arg);
+ 894 + +
+ 895 + + /** Remove an element.
+ 896 + +
+ 897 + + @li **(1)** the element at `pos` is removed.
+ 898 + + @li **(2)** the element with the key `key` is removed, if it exists.
+ 899 + +
+ 900 + + `pos` must be valid and dereferenceable. References and iterators to
+ 901 + + the erased element are invalidated. Other iterators and references are
+ 902 + + not invalidated.
+ 903 + +
+ 904 + + @attention The @ref end() iterator (which is valid but cannot be
+ 905 + + dereferenced) cannot be used as a value for `pos`.
+ 906 + +
+ 907 + + @par Complexity
+ 908 + + Constant on average, worst case linear in @ref size().
+ 909 + +
+ 910 + + @par Exception Safety
+ 911 + + No-throw guarantee.
+ 912 + +
+ 913 + + @return
+ 914 + + @li **(1)** an iterator following the removed element.
+ 915 + + @li **(2)** the number of elements removed, which will be either
+ 916 + + 0 or 1.
+ 917 + +
+ 918 + + @param pos An iterator pointing to the element to be removed.
+ 919 + +
+ 920 + + @{
+ 921 + + */
+ 922 + + BOOST_JSON_DECL
+ 923 + + iterator
+ 924 + + erase(const_iterator pos) noexcept;
+ 925 + +
+ 926 + + /** Overload
+ 927 + +
+ 928 + + @param key The key to match.
+ 929 + + */
+ 930 + + BOOST_JSON_DECL
+ 931 + + std::size_t
+ 932 + + erase(string_view key) noexcept;
+ 933 + + /// @}
+ 934 + +
+ 935 + + /** Erase an element preserving order.
+ 936 + +
+ 937 + + @li **(1)** Remove the element pointed to by `pos`, which must be valid
+ 938 + + and dereferenceable. References and iterators from `pos` to @ref end(),
+ 939 + + both included, are invalidated. Other iterators and references are not
+ 940 + + invalidated.
+ 941 + + @li **(2)** Remove the element which matches `key`, if it exists. All
+ 942 + + references and iterators are invalidated.
+ 943 + +
+ 944 + + The relative order of remaining elements is preserved.
+ 945 + +
+ 946 + + @attention The @ref end() iterator (which is valid but cannot be
+ 947 + + dereferenced) cannot be used as a value for `pos`.
+ 948 + +
+ 949 + + @par Complexity
+ 950 + + Linear in @ref size().
+ 951 + +
+ 952 + + @par Exception Safety
+ 953 + + No-throw guarantee.
+ 954 + +
+ 955 + + @return
+ 956 + + @li An iterator following the removed element.
+ 957 + + @li The number of elements removed, which will be either 0 or 1.
+ 958 + +
+ 959 + + @param pos An iterator pointing to the element to be
+ 960 + + removed.
+ 961 + +
+ 962 + + @{
+ 963 + + */
+ 964 + + BOOST_JSON_DECL
+ 965 + + iterator
+ 966 + + stable_erase(const_iterator pos) noexcept;
+ 967 + +
+ 968 + + /** Overload
+ 969 + +
+ 970 + + @param key The key to match.
+ 971 + + */
+ 972 + + BOOST_JSON_DECL
+ 973 + + std::size_t
+ 974 + + stable_erase(string_view key) noexcept;
+ 975 + + /// @}
+ 976 + +
+ 977 + + /** Swap two objects.
+ 978 + +
+ 979 + + Exchanges the contents of this object with another object. Ownership of
+ 980 + + the respective @ref boost::container::pmr::memory_resource objects is
+ 981 + + not transferred. If `this == &other`, this function call has no effect.
+ 982 + +
+ 983 + + @li If `*storage() == *other.storage()` all iterators and references
+ 984 + + remain valid.
+ 985 + +
+ 986 + + @li Otherwise, the contents are logically swapped by making copies,
+ 987 + + which can throw. In this case all iterators and references are
+ 988 + + invalidated.
+ 989 + +
+ 990 + + @par Complexity
+ 991 + + If `*storage() == *other.storage()`, then constant; otherwise linear in
+ 992 + + `size() + other.size()`.
+ 993 + +
+ 994 + + @par Exception Safety
+ 995 + + No-throw guarantee if `*storage() == *other.storage()`. Otherwise
+ 996 + + strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 997 + +
+ 998 + + @param other The object to swap with.
+ 999 + + */
+ 1000 + + BOOST_JSON_DECL
+ 1001 + + void
+ 1002 + + swap(object& other);
+ 1003 + +
+ 1004 + + /** Swap two objects.
+ 1005 + +
+ 1006 + + Exchanges the contents of the object `lhs` with another object `rhs`.
+ 1007 + + Ownership of the respective @ref boost::container::pmr::memory_resource
+ 1008 + + objects is not transferred. If `&lhs == &rhs`, this function call has
+ 1009 + + no effect.
+ 1010 + +
+ 1011 + + @li If `*lhs.storage() == *rhs.storage()` all iterators and references
+ 1012 + + remain valid.
+ 1013 + +
+ 1014 + + @li Otherwise, the contents are logically swapped by making copies,
+ 1015 + + which can throw. In this case all iterators and references are
+ 1016 + + invalidated.
+ 1017 + +
+ 1018 + + @par Complexity
+ 1019 + + If `*lhs.storage() == *rhs.storage()`, then constant; otherwise linear
+ 1020 + + in `lhs.size() + rhs.size()`.
+ 1021 + +
+ 1022 + + @par Exception Safety
+ 1023 + + No-throw guarantee if `*lhs.storage() == *rhs.storage()`. Otherwise
+ 1024 + + strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 1025 + +
+ 1026 + + @param lhs The object to exchange.
+ 1027 + +
+ 1028 + + @param rhs The object to exchange.
+ 1029 + +
+ 1030 + + @see @ref object::swap
+ 1031 + + */
+ 1032 + + friend
+ 1033 + + void
+ 1034 + +11 swap(object& lhs, object& rhs)
+ 1035 + + {
+ 1036 + +11 lhs.swap(rhs);
+ 1037 + +3 }
+ 1038 + +
+ 1039 + + //------------------------------------------------------
+ 1040 + + //
+ 1041 + + // Lookup
+ 1042 + + //
+ 1043 + + //------------------------------------------------------
+ 1044 + +
+ 1045 + + /** Access the specified element, with bounds checking.
+ 1046 + +
+ 1047 + + Returns @ref boost::system::result containing a reference to the
+ 1048 + + mapped value of the element that matches `key`. Otherwise the result
+ 1049 + + contains an `error_code`.
+ 1050 + +
+ 1051 + + @par Exception Safety
+ 1052 + + No-throw guarantee.
+ 1053 + +
+ 1054 + + @param key The key of the element to find.
+ 1055 + +
+ 1056 + + @par Complexity
+ 1057 + + Constant on average, worst case linear in @ref size().
+ 1058 + +
+ 1059 + + @{
+ 1060 + + */
+ 1061 + + BOOST_JSON_DECL
+ 1062 + + system::result<value&>
+ 1063 + + try_at(string_view key) noexcept;
+ 1064 + +
+ 1065 + + BOOST_JSON_DECL
+ 1066 + + system::result<value const&>
+ 1067 + + try_at(string_view key) const noexcept;
+ 1068 + + /// @}
+ 1069 + +
+ 1070 + + /** Access the specified element, with bounds checking.
+ 1071 + +
+ 1072 + + Returns a reference to the mapped value of the element that matches
+ 1073 + + `key`, otherwise throws.
+ 1074 + +
+ 1075 + + @par Complexity
+ 1076 + + Constant on average, worst case linear in @ref size().
+ 1077 + +
+ 1078 + + @par Exception Safety
+ 1079 + + Strong guarantee.
+ 1080 + +
+ 1081 + + @return A reference to the mapped value.
+ 1082 + +
+ 1083 + + @param key The key of the element to find.
+ 1084 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 1085 + + source location of the call site by default.
+ 1086 + +
+ 1087 + + @throw `boost::system::system_error` if no such element exists.
+ 1088 + +
+ 1089 + + @see @ref operator[], @ref try_at.
+ 1090 + +
+ 1091 + + @{
+ 1092 + + */
+ 1093 + + inline
+ 1094 + + value&
+ 1095 + + at(
+ 1096 + + string_view key,
+ 1097 + + source_location const& loc = BOOST_CURRENT_LOCATION) &;
+ 1098 + +
+ 1099 + + inline
+ 1100 + + value&&
+ 1101 + + at(
+ 1102 + + string_view key,
+ 1103 + + source_location const& loc = BOOST_CURRENT_LOCATION) &&;
+ 1104 + +
+ 1105 + + BOOST_JSON_DECL
+ 1106 + + value const&
+ 1107 + + at(
+ 1108 + + string_view key,
+ 1109 + + source_location const& loc = BOOST_CURRENT_LOCATION) const&;
+ 1110 + + /// @}
+ 1111 + +
+ 1112 + + /** Access or insert an element.
+ 1113 + +
+ 1114 + + Returns a reference to the value that is mapped to `key`. If such value
+ 1115 + + does not already exist, performs an insertion of a null value.
+ 1116 + +
+ 1117 + + If an insertion occurs and results in a rehashing of the container, all
+ 1118 + + iterators including any past-the-end iterators, and all references to
+ 1119 + + the elements are invalidated. Otherwise, no iterators or references are
+ 1120 + + invalidated.
+ 1121 + +
+ 1122 + + @par Complexity
+ 1123 + + Constant on average, worst case linear in @ref size().
+ 1124 + +
+ 1125 + + @par Exception Safety
+ 1126 + + Strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 1127 + +
+ 1128 + + @return A reference to the mapped value.
+ 1129 + +
+ 1130 + + @param key The key of the element to find.
+ 1131 + + */
+ 1132 + + BOOST_JSON_DECL
+ 1133 + + value&
+ 1134 + + operator[](string_view key);
+ 1135 + +
+ 1136 + + /** Count the number of elements with a specific key.
+ 1137 + +
+ 1138 + + Returns the number of elements with keys equal to `key`. The only
+ 1139 + + possible return values are 0 and 1.
+ 1140 + +
+ 1141 + + @par Complexity
+ 1142 + + Constant on average, worst case linear in @ref size().
+ 1143 + +
+ 1144 + + @par Exception Safety
+ 1145 + + No-throw guarantee.
+ 1146 + +
+ 1147 + + @param key The key of the element to find.
+ 1148 + + */
+ 1149 + + BOOST_JSON_DECL
+ 1150 + + std::size_t
+ 1151 + + count(string_view key) const noexcept;
+ 1152 + +
+ 1153 + + /** Find an element with a specific key.
+ 1154 + +
+ 1155 + + This function returns an iterator to the element
+ 1156 + + matching `key` if it exists, otherwise returns
+ 1157 + + @ref end().
+ 1158 + +
+ 1159 + + @par Complexity
+ 1160 + + Constant on average, worst case linear in @ref size().
+ 1161 + +
+ 1162 + + @par Exception Safety
+ 1163 + + No-throw guarantee.
+ 1164 + +
+ 1165 + + @param key The key of the element to find.
+ 1166 + +
+ 1167 + + @{
+ 1168 + + */
+ 1169 + + BOOST_JSON_DECL
+ 1170 + + iterator
+ 1171 + + find(string_view key) noexcept;
+ 1172 + +
+ 1173 + + BOOST_JSON_DECL
+ 1174 + + const_iterator
+ 1175 + + find(string_view key) const noexcept;
+ 1176 + + /// @}
+ 1177 + +
+ 1178 + + /** Return `true` if the key is found.
+ 1179 + +
+ 1180 + + Checks if there is an element with key equal to `key`.
+ 1181 + +
+ 1182 + + @par Effects
+ 1183 + + @code
+ 1184 + + return find(key) != end();
+ 1185 + + @endcode
+ 1186 + +
+ 1187 + + @par Complexity
+ 1188 + + Constant on average, worst case linear in @ref size().
+ 1189 + +
+ 1190 + + @par Exception Safety
+ 1191 + + No-throw guarantee.
+ 1192 + +
+ 1193 + + @param key The key of the element to find.
+ 1194 + +
+ 1195 + + @see @ref find.
+ 1196 + + */
+ 1197 + + BOOST_JSON_DECL
+ 1198 + + bool
+ 1199 + + contains(string_view key) const noexcept;
+ 1200 + +
+ 1201 + + /** Return a pointer to the value if the key is found, or null
+ 1202 + +
+ 1203 + + This function searches for a value with the given
+ 1204 + + key, and returns a pointer to it if found. Otherwise
+ 1205 + + it returns null.
+ 1206 + +
+ 1207 + + @par Example
+ 1208 + + @code
+ 1209 + + if( auto p = obj.if_contains( "key" ) )
+ 1210 + + std::cout << *p;
+ 1211 + + @endcode
+ 1212 + +
+ 1213 + + @par Complexity
+ 1214 + + Constant on average, worst case linear in @ref size().
+ 1215 + +
+ 1216 + + @par Exception Safety
+ 1217 + + No-throw guarantee.
+ 1218 + +
+ 1219 + + @param key The key of the element to find.
+ 1220 + +
+ 1221 + + @see @ref find.
+ 1222 + +
+ 1223 + + @{
+ 1224 + + */
+ 1225 + + BOOST_JSON_DECL
+ 1226 + + value const*
+ 1227 + + if_contains(string_view key) const noexcept;
+ 1228 + +
+ 1229 + + BOOST_JSON_DECL
+ 1230 + + value*
+ 1231 + + if_contains(string_view key) noexcept;
+ 1232 + + /// @}
+ 1233 + +
+ 1234 + + /** Compare two objects for equality.
+ 1235 + +
+ 1236 + + Objects are equal when their sizes are the same,
+ 1237 + + and when for each key in `lhs` there is a matching
+ 1238 + + key in `rhs` with the same value.
+ 1239 + +
+ 1240 + + @par Complexity
+ 1241 + + Average case linear and worst case quadratic in `lhs.size()`.
+ 1242 + +
+ 1243 + + @par Exception Safety
+ 1244 + + No-throw guarantee.
+ 1245 + + */
+ 1246 + + // inline friend speeds up overload resolution
+ 1247 + + friend
+ 1248 + + bool
+ 1249 + +75 operator==(
+ 1250 + + object const& lhs,
+ 1251 + + object const& rhs) noexcept
+ 1252 + + {
+ 1253 + +75 return lhs.equal(rhs);
+ 1254 + + }
+ 1255 + +
+ 1256 + + /** Compare two objects for inequality.
+ 1257 + +
+ 1258 + + Objects are equal when their sizes are the same, and when for each key
+ 1259 + + in `lhs` there is a matching key in `rhs` with the same value.
+ 1260 + +
+ 1261 + + @par Complexity
+ 1262 + + Average casee linear and worst case quadratic in `lhs.size()`.
+ 1263 + +
+ 1264 + + @par Exception Safety
+ 1265 + + No-throw guarantee.
+ 1266 + + */
+ 1267 + + // inline friend speeds up overload resolution
+ 1268 + + friend
+ 1269 + + bool
+ 1270 + +6 operator!=(
+ 1271 + + object const& lhs,
+ 1272 + + object const& rhs) noexcept
+ 1273 + + {
+ 1274 + +6 return ! (lhs == rhs);
+ 1275 + + }
+ 1276 + +
+ 1277 + + /** Serialize to an output stream.
+ 1278 + +
+ 1279 + + This function serializes an `object` as JSON into the output stream.
+ 1280 + +
+ 1281 + + @return Reference to `os`.
+ 1282 + +
+ 1283 + + @par Complexity
+ 1284 + + Constant or linear in the size of `obj`.
+ 1285 + +
+ 1286 + + @par Exception Safety
+ 1287 + + Strong guarantee.
+ 1288 + + Calls to `memory_resource::allocate` may throw.
+ 1289 + +
+ 1290 + + @param os The output stream to serialize to.
+ 1291 + +
+ 1292 + + @param obj The value to serialize.
+ 1293 + + */
+ 1294 + + BOOST_JSON_DECL
+ 1295 + + friend
+ 1296 + + std::ostream&
+ 1297 + + operator<<(
+ 1298 + + std::ostream& os,
+ 1299 + + object const& obj);
+ 1300 + + private:
+ 1301 + + #ifndef BOOST_JSON_DOCS
+ 1302 + + // VFALCO friending a detail function makes it public
+ 1303 + + template<class CharRange>
+ 1304 + + friend
+ 1305 + + std::pair<key_value_pair*, std::size_t>
+ 1306 + + detail::find_in_object(
+ 1307 + + object const& obj,
+ 1308 + + CharRange key) noexcept;
+ 1309 + + #endif
+ 1310 + +
+ 1311 + + template<class InputIt>
+ 1312 + + void
+ 1313 + + construct(
+ 1314 + + InputIt first,
+ 1315 + + InputIt last,
+ 1316 + + std::size_t min_capacity,
+ 1317 + + std::input_iterator_tag);
+ 1318 + +
+ 1319 + + template<class InputIt>
+ 1320 + + void
+ 1321 + + construct(
+ 1322 + + InputIt first,
+ 1323 + + InputIt last,
+ 1324 + + std::size_t min_capacity,
+ 1325 + + std::forward_iterator_tag);
+ 1326 + +
+ 1327 + + template<class InputIt>
+ 1328 + + void
+ 1329 + + insert(
+ 1330 + + InputIt first,
+ 1331 + + InputIt last,
+ 1332 + + std::input_iterator_tag);
+ 1333 + +
+ 1334 + + template<class InputIt>
+ 1335 + + void
+ 1336 + + insert(
+ 1337 + + InputIt first,
+ 1338 + + InputIt last,
+ 1339 + + std::forward_iterator_tag);
+ 1340 + +
+ 1341 + + template< class... Args >
+ 1342 + + std::pair<iterator, bool>
+ 1343 + + emplace_impl(string_view key, Args&& ... args );
+ 1344 + +
+ 1345 + + BOOST_JSON_DECL
+ 1346 + + key_value_pair*
+ 1347 + + insert_impl(
+ 1348 + + pilfered<key_value_pair> p,
+ 1349 + + std::size_t hash);
+ 1350 + +
+ 1351 + + BOOST_JSON_DECL
+ 1352 + + table*
+ 1353 + + reserve_impl(std::size_t new_capacity);
+ 1354 + +
+ 1355 + + BOOST_JSON_DECL
+ 1356 + + bool
+ 1357 + + equal(object const& other) const noexcept;
+ 1358 + +
+ 1359 + + inline
+ 1360 + + std::size_t
+ 1361 + + growth(
+ 1362 + + std::size_t new_size) const;
+ 1363 + +
+ 1364 + + inline
+ 1365 + + void
+ 1366 + + remove(
+ 1367 + + index_t& head,
+ 1368 + + key_value_pair& p) noexcept;
+ 1369 + +
+ 1370 + + inline
+ 1371 + + void
+ 1372 + + destroy() noexcept;
+ 1373 + +
+ 1374 + + inline
+ 1375 + + void
+ 1376 + + destroy(
+ 1377 + + key_value_pair* first,
+ 1378 + + key_value_pair* last) noexcept;
+ 1379 + +
+ 1380 + + template<class FS, class FB>
+ 1381 + + auto
+ 1382 + + do_erase(
+ 1383 + + const_iterator pos,
+ 1384 + + FS small_reloc,
+ 1385 + + FB big_reloc) noexcept
+ 1386 + + -> iterator;
+ 1387 + +
+ 1388 + + inline
+ 1389 + + void
+ 1390 + + reindex_relocate(
+ 1391 + + key_value_pair* src,
+ 1392 + + key_value_pair* dst) noexcept;
+ 1393 + + };
+ 1394 + +
+ 1395 + + } // namespace json
+ 1396 + + } // namespace boost
+ 1397 + +
+ 1398 + + #ifndef BOOST_JSON_DOCS
+ 1399 + + // boost::hash trait
+ 1400 + + namespace boost
+ 1401 + + {
+ 1402 + + namespace container_hash
+ 1403 + + {
+ 1404 + +
+ 1405 + + template< class T > struct is_unordered_range;
+ 1406 + +
+ 1407 + + template<>
+ 1408 + + struct is_unordered_range< json::object >
+ 1409 + + : std::true_type
+ 1410 + + {};
+ 1411 + +
+ 1412 + + } // namespace container_hash
+ 1413 + + } // namespace boost
+ 1414 + +
+ 1415 + + // std::hash specialization
+ 1416 + + namespace std {
+ 1417 + + template <>
+ 1418 + + struct hash< ::boost::json::object > {
+ 1419 + + BOOST_JSON_DECL
+ 1420 + + std::size_t
+ 1421 + + operator()(::boost::json::object const& jo) const noexcept;
+ 1422 + + };
+ 1423 + + } // std
+ 1424 + + #endif
+ 1425 + +
+ 1426 + +
+ 1427 + + // Must be included here for this file to stand alone
+ 1428 + + #include <boost/json/value.hpp>
+ 1429 + +
+ 1430 + + // includes are at the bottom of <boost/json/value.hpp>
+ 1431 + +
+ 1432 + + #endif
+ 1433 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.object.hpp.f7e5cc97accf7f1302ce80ea402b6373.html b/json/gcovr/index.object.hpp.f7e5cc97accf7f1302ce80ea402b6373.html new file mode 100644 index 00000000..208733f0 --- /dev/null +++ b/json/gcovr/index.object.hpp.f7e5cc97accf7f1302ce80ea402b6373.html @@ -0,0 +1,2878 @@ + + + + + + detail/object.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/object.hpp

+
+ + 100.0% Lines (13/13) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/object.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_OBJECT_HPP
+ 11 + + #define BOOST_JSON_DETAIL_OBJECT_HPP
+ 12 + +
+ 13 + + #include <boost/json/storage_ptr.hpp>
+ 14 + + #include <boost/json/string_view.hpp>
+ 15 + + #include <cstdlib>
+ 16 + +
+ 17 + + namespace boost {
+ 18 + + namespace json {
+ 19 + +
+ 20 + + class object;
+ 21 + + class value;
+ 22 + + class key_value_pair;
+ 23 + +
+ 24 + + namespace detail {
+ 25 + +
+ 26 + + class unchecked_object
+ 27 + + {
+ 28 + + // each element is two values,
+ 29 + + // first one is a string key,
+ 30 + + // second one is the value.
+ 31 + + value* data_;
+ 32 + + std::size_t size_;
+ 33 + + storage_ptr const& sp_;
+ 34 + +
+ 35 + + public:
+ 36 + + inline
+ 37 + + ~unchecked_object();
+ 38 + +
+ 39 + +34879 unchecked_object(
+ 40 + + value* data,
+ 41 + + std::size_t size, // # of kv-pairs
+ 42 + + storage_ptr const& sp) noexcept
+ 43 + +34879 : data_(data)
+ 44 + +34879 , size_(size)
+ 45 + +34879 , sp_(sp)
+ 46 + + {
+ 47 + +34879 }
+ 48 + +
+ 49 + + unchecked_object(
+ 50 + + unchecked_object&& other) noexcept
+ 51 + + : data_(other.data_)
+ 52 + + , size_(other.size_)
+ 53 + + , sp_(other.sp_)
+ 54 + + {
+ 55 + + other.data_ = nullptr;
+ 56 + + }
+ 57 + +
+ 58 + + storage_ptr const&
+ 59 + +34879 storage() const noexcept
+ 60 + + {
+ 61 + +34879 return sp_;
+ 62 + + }
+ 63 + +
+ 64 + + std::size_t
+ 65 + +136330 size() const noexcept
+ 66 + + {
+ 67 + +136330 return size_;
+ 68 + + }
+ 69 + +
+ 70 + + value*
+ 71 + +33791 release() noexcept
+ 72 + + {
+ 73 + +33791 auto const data = data_;
+ 74 + +33791 data_ = nullptr;
+ 75 + +33791 return data;
+ 76 + + }
+ 77 + + };
+ 78 + +
+ 79 + + template<class CharRange>
+ 80 + + std::pair<key_value_pair*, std::size_t>
+ 81 + + find_in_object(
+ 82 + + object const& obj,
+ 83 + + CharRange key) noexcept;
+ 84 + +
+ 85 + + extern template
+ 86 + + BOOST_JSON_DECL
+ 87 + + std::pair<key_value_pair*, std::size_t>
+ 88 + + find_in_object<string_view>(
+ 89 + + object const&,
+ 90 + + string_view key) noexcept;
+ 91 + +
+ 92 + + } // detail
+ 93 + + } // namespace json
+ 94 + + } // namespace boost
+ 95 + +
+ 96 + + #endif
+ 97 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.object.hpp.f9faeb03c62042d95f8ee35052afa9e9.html b/json/gcovr/index.object.hpp.f9faeb03c62042d95f8ee35052afa9e9.html new file mode 100644 index 00000000..6470ffef --- /dev/null +++ b/json/gcovr/index.object.hpp.f9faeb03c62042d95f8ee35052afa9e9.html @@ -0,0 +1,6670 @@ + + + + + + impl/object.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/object.hpp

+
+ + 100.0% Lines (168/168) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/object.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_OBJECT_HPP
+ 11 + + #define BOOST_JSON_IMPL_OBJECT_HPP
+ 12 + +
+ 13 + + #include <boost/core/detail/static_assert.hpp>
+ 14 + + #include <boost/json/value.hpp>
+ 15 + + #include <iterator>
+ 16 + + #include <cmath>
+ 17 + + #include <type_traits>
+ 18 + + #include <utility>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + +
+ 23 + + namespace detail {
+ 24 + +
+ 25 + + // Objects with size less than or equal
+ 26 + + // to this number will use a linear search
+ 27 + + // instead of the more expensive hash function.
+ 28 + + static
+ 29 + + constexpr
+ 30 + + std::size_t
+ 31 + + small_object_size_ = 18;
+ 32 + +
+ 33 + + BOOST_CORE_STATIC_ASSERT(
+ 34 + + small_object_size_ < BOOST_JSON_MAX_STRUCTURED_SIZE);
+ 35 + +
+ 36 + + } // detail
+ 37 + +
+ 38 + + //----------------------------------------------------------
+ 39 + +
+ 40 + + struct alignas(key_value_pair)
+ 41 + + object::table
+ 42 + + {
+ 43 + + std::uint32_t size = 0;
+ 44 + + std::uint32_t capacity = 0;
+ 45 + + std::uintptr_t salt = 0;
+ 46 + +
+ 47 + + #if defined(_MSC_VER) && BOOST_JSON_ARCH == 32
+ 48 + + // VFALCO If we make key_value_pair smaller,
+ 49 + + // then we might want to revisit this
+ 50 + + // padding.
+ 51 + + BOOST_CORE_STATIC_ASSERT( sizeof(key_value_pair) == 32 );
+ 52 + + char pad[4] = {}; // silence warnings
+ 53 + + #endif
+ 54 + +
+ 55 + + constexpr table();
+ 56 + +
+ 57 + + // returns true if we use a linear
+ 58 + + // search instead of the hash table.
+ 59 + +122172 bool is_small() const noexcept
+ 60 + + {
+ 61 + +122172 return capacity <=
+ 62 + +122172 detail::small_object_size_;
+ 63 + + }
+ 64 + +
+ 65 + + key_value_pair&
+ 66 + +293785 operator[](
+ 67 + + std::size_t pos) noexcept
+ 68 + + {
+ 69 + + return reinterpret_cast<
+ 70 + + key_value_pair*>(
+ 71 + +293785 this + 1)[pos];
+ 72 + + }
+ 73 + +
+ 74 + + // VFALCO This is exported for tests
+ 75 + + BOOST_JSON_DECL
+ 76 + + std::size_t
+ 77 + + digest(string_view key) const noexcept;
+ 78 + +
+ 79 + + inline
+ 80 + + index_t&
+ 81 + + bucket(std::size_t hash) noexcept;
+ 82 + +
+ 83 + + inline
+ 84 + + index_t&
+ 85 + + bucket(string_view key) noexcept;
+ 86 + +
+ 87 + + inline
+ 88 + + void
+ 89 + + clear() noexcept;
+ 90 + +
+ 91 + + static
+ 92 + + inline
+ 93 + + table*
+ 94 + + allocate(
+ 95 + + std::size_t capacity,
+ 96 + + std::uintptr_t salt,
+ 97 + + storage_ptr const& sp);
+ 98 + +
+ 99 + + static
+ 100 + + void
+ 101 + +36348 deallocate(
+ 102 + + table* p,
+ 103 + + storage_ptr const& sp) noexcept
+ 104 + + {
+ 105 + +36348 if(p->capacity == 0)
+ 106 + +981 return;
+ 107 + +35367 if(! p->is_small())
+ 108 + +388 sp->deallocate(p,
+ 109 + +388 sizeof(table) + p->capacity * (
+ 110 + + sizeof(key_value_pair) +
+ 111 + + sizeof(index_t)));
+ 112 + + else
+ 113 + +34979 sp->deallocate(p,
+ 114 + +34979 sizeof(table) + p->capacity *
+ 115 + + sizeof(key_value_pair));
+ 116 + + }
+ 117 + + };
+ 118 + +
+ 119 + + //----------------------------------------------------------
+ 120 + +
+ 121 + + class object::revert_construct
+ 122 + + {
+ 123 + + object* obj_;
+ 124 + +
+ 125 + + BOOST_JSON_DECL
+ 126 + + void
+ 127 + + destroy() noexcept;
+ 128 + +
+ 129 + + public:
+ 130 + + explicit
+ 131 + +705 revert_construct(
+ 132 + + object& obj) noexcept
+ 133 + +705 : obj_(&obj)
+ 134 + + {
+ 135 + +705 }
+ 136 + +
+ 137 + +705 ~revert_construct()
+ 138 + +374 {
+ 139 + +705 if(! obj_)
+ 140 + +331 return;
+ 141 + +374 destroy();
+ 142 + +705 }
+ 143 + +
+ 144 + + void
+ 145 + +331 commit() noexcept
+ 146 + + {
+ 147 + +331 obj_ = nullptr;
+ 148 + +331 }
+ 149 + + };
+ 150 + +
+ 151 + + //----------------------------------------------------------
+ 152 + +
+ 153 + + class object::revert_insert
+ 154 + + {
+ 155 + + object* obj_;
+ 156 + + table* t_ = nullptr;
+ 157 + + std::size_t size_;
+ 158 + +
+ 159 + + BOOST_JSON_DECL
+ 160 + + void
+ 161 + + destroy() noexcept;
+ 162 + +
+ 163 + + public:
+ 164 + + explicit
+ 165 + +503 revert_insert(
+ 166 + + object& obj,
+ 167 + + std::size_t capacity)
+ 168 + +503 : obj_(&obj)
+ 169 + +503 , size_(obj_->size())
+ 170 + + {
+ 171 + +503 if( capacity > obj_->capacity() )
+ 172 + +138 t_ = obj_->reserve_impl(capacity);
+ 173 + +494 }
+ 174 + +
+ 175 + +494 ~revert_insert()
+ 176 + +230 {
+ 177 + +494 if(! obj_)
+ 178 + +264 return;
+ 179 + +
+ 180 + +230 destroy();
+ 181 + +230 if( t_ )
+ 182 + + {
+ 183 + +117 table::deallocate( obj_->t_, obj_->sp_ );
+ 184 + +117 obj_->t_ = t_;
+ 185 + + }
+ 186 + + else
+ 187 + + {
+ 188 + +113 obj_->t_->size = static_cast<index_t>(size_);
+ 189 + + }
+ 190 + +494 }
+ 191 + +
+ 192 + + void
+ 193 + +264 commit() noexcept
+ 194 + + {
+ 195 + +264 BOOST_ASSERT(obj_);
+ 196 + +264 if( t_ )
+ 197 + +12 table::deallocate( t_, obj_->sp_ );
+ 198 + +264 obj_ = nullptr;
+ 199 + +264 }
+ 200 + + };
+ 201 + +
+ 202 + + //----------------------------------------------------------
+ 203 + + //
+ 204 + + // Iterators
+ 205 + + //
+ 206 + + //----------------------------------------------------------
+ 207 + +
+ 208 + + auto
+ 209 + +70786 object::
+ 210 + + begin() noexcept ->
+ 211 + + iterator
+ 212 + + {
+ 213 + +70786 return &(*t_)[0];
+ 214 + + }
+ 215 + +
+ 216 + + auto
+ 217 + +53205 object::
+ 218 + + begin() const noexcept ->
+ 219 + + const_iterator
+ 220 + + {
+ 221 + +53205 return &(*t_)[0];
+ 222 + + }
+ 223 + +
+ 224 + + auto
+ 225 + +3 object::
+ 226 + + cbegin() const noexcept ->
+ 227 + + const_iterator
+ 228 + + {
+ 229 + +3 return &(*t_)[0];
+ 230 + + }
+ 231 + +
+ 232 + + auto
+ 233 + +46088 object::
+ 234 + + end() noexcept ->
+ 235 + + iterator
+ 236 + + {
+ 237 + +46088 return &(*t_)[t_->size];
+ 238 + + }
+ 239 + +
+ 240 + + auto
+ 241 + +27785 object::
+ 242 + + end() const noexcept ->
+ 243 + + const_iterator
+ 244 + + {
+ 245 + +27785 return &(*t_)[t_->size];
+ 246 + + }
+ 247 + +
+ 248 + + auto
+ 249 + +3 object::
+ 250 + + cend() const noexcept ->
+ 251 + + const_iterator
+ 252 + + {
+ 253 + +3 return &(*t_)[t_->size];
+ 254 + + }
+ 255 + +
+ 256 + + auto
+ 257 + +2 object::
+ 258 + + rbegin() noexcept ->
+ 259 + + reverse_iterator
+ 260 + + {
+ 261 + +2 return reverse_iterator(end());
+ 262 + + }
+ 263 + +
+ 264 + + auto
+ 265 + +2 object::
+ 266 + + rbegin() const noexcept ->
+ 267 + + const_reverse_iterator
+ 268 + + {
+ 269 + +2 return const_reverse_iterator(end());
+ 270 + + }
+ 271 + +
+ 272 + + auto
+ 273 + +2 object::
+ 274 + + crbegin() const noexcept ->
+ 275 + + const_reverse_iterator
+ 276 + + {
+ 277 + +2 return const_reverse_iterator(end());
+ 278 + + }
+ 279 + +
+ 280 + + auto
+ 281 + +2 object::
+ 282 + + rend() noexcept ->
+ 283 + + reverse_iterator
+ 284 + + {
+ 285 + +2 return reverse_iterator(begin());
+ 286 + + }
+ 287 + +
+ 288 + + auto
+ 289 + +2 object::
+ 290 + + rend() const noexcept ->
+ 291 + + const_reverse_iterator
+ 292 + + {
+ 293 + +2 return const_reverse_iterator(begin());
+ 294 + + }
+ 295 + +
+ 296 + + auto
+ 297 + +2 object::
+ 298 + + crend() const noexcept ->
+ 299 + + const_reverse_iterator
+ 300 + + {
+ 301 + +2 return const_reverse_iterator(begin());
+ 302 + + }
+ 303 + +
+ 304 + + //----------------------------------------------------------
+ 305 + + //
+ 306 + + // Capacity
+ 307 + + //
+ 308 + + //----------------------------------------------------------
+ 309 + +
+ 310 + + bool
+ 311 + +10462 object::
+ 312 + + empty() const noexcept
+ 313 + + {
+ 314 + +10462 return t_->size == 0;
+ 315 + + }
+ 316 + +
+ 317 + + auto
+ 318 + +44242 object::
+ 319 + + size() const noexcept ->
+ 320 + + std::size_t
+ 321 + + {
+ 322 + +44242 return t_->size;
+ 323 + + }
+ 324 + +
+ 325 + + constexpr
+ 326 + + std::size_t
+ 327 + +73119 object::
+ 328 + + max_size() noexcept
+ 329 + + {
+ 330 + + // max_size depends on the address model
+ 331 + + using min = std::integral_constant<std::size_t,
+ 332 + + (std::size_t(-1) - sizeof(table)) /
+ 333 + + (sizeof(key_value_pair) + sizeof(index_t))>;
+ 334 + + return min::value < BOOST_JSON_MAX_STRUCTURED_SIZE ?
+ 335 + +73119 min::value : BOOST_JSON_MAX_STRUCTURED_SIZE;
+ 336 + + }
+ 337 + +
+ 338 + + auto
+ 339 + +18830 object::
+ 340 + + capacity() const noexcept ->
+ 341 + + std::size_t
+ 342 + + {
+ 343 + +18830 return t_->capacity;
+ 344 + + }
+ 345 + +
+ 346 + + void
+ 347 + +4737 object::
+ 348 + + reserve(std::size_t new_capacity)
+ 349 + + {
+ 350 + +4737 if( new_capacity <= capacity() )
+ 351 + +3221 return;
+ 352 + +1516 table* const old_table = reserve_impl(new_capacity);
+ 353 + +1451 table::deallocate( old_table, sp_ );
+ 354 + + }
+ 355 + +
+ 356 + + //----------------------------------------------------------
+ 357 + + //
+ 358 + + // Lookup
+ 359 + + //
+ 360 + + //----------------------------------------------------------
+ 361 + +
+ 362 + + value&
+ 363 + +41 object::
+ 364 + + at(string_view key, source_location const& loc) &
+ 365 + + {
+ 366 + +41 auto const& self = *this;
+ 367 + +41 return const_cast< value& >( self.at(key, loc) );
+ 368 + + }
+ 369 + +
+ 370 + + value&&
+ 371 + +5 object::
+ 372 + + at(string_view key, source_location const& loc) &&
+ 373 + + {
+ 374 + +5 return std::move( at(key, loc) );
+ 375 + + }
+ 376 + +
+ 377 + + //----------------------------------------------------------
+ 378 + +
+ 379 + + template<class P, class>
+ 380 + + auto
+ 381 + +3127 object::
+ 382 + + insert(P&& p) ->
+ 383 + + std::pair<iterator, bool>
+ 384 + + {
+ 385 + +3422 key_value_pair v(
+ 386 + +3127 std::forward<P>(p), sp_);
+ 387 + +5791 return emplace_impl( v.key(), pilfer(v) );
+ 388 + +2979 }
+ 389 + +
+ 390 + + template<class M>
+ 391 + + auto
+ 392 + +17 object::
+ 393 + + insert_or_assign(
+ 394 + + string_view key, M&& m) ->
+ 395 + + std::pair<iterator, bool>
+ 396 + + {
+ 397 + +17 std::pair<iterator, bool> result = emplace_impl(
+ 398 + + key, key, static_cast<M&&>(m) );
+ 399 + +10 if( !result.second )
+ 400 + + {
+ 401 + +8 value(static_cast<M>(m), sp_).swap(
+ 402 + +3 result.first->value());
+ 403 + + }
+ 404 + +9 return result;
+ 405 + + }
+ 406 + +
+ 407 + + template<class Arg>
+ 408 + + auto
+ 409 + +990 object::
+ 410 + + emplace(
+ 411 + + string_view key,
+ 412 + + Arg&& arg) ->
+ 413 + + std::pair<iterator, bool>
+ 414 + + {
+ 415 + +990 return emplace_impl( key, key, static_cast<Arg&&>(arg) );
+ 416 + + }
+ 417 + +
+ 418 + + //----------------------------------------------------------
+ 419 + + //
+ 420 + + // (private)
+ 421 + + //
+ 422 + + //----------------------------------------------------------
+ 423 + +
+ 424 + + template<class InputIt>
+ 425 + + void
+ 426 + +78 object::
+ 427 + + construct(
+ 428 + + InputIt first,
+ 429 + + InputIt last,
+ 430 + + std::size_t min_capacity,
+ 431 + + std::input_iterator_tag)
+ 432 + + {
+ 433 + +78 reserve(min_capacity);
+ 434 + +76 revert_construct r(*this);
+ 435 + +753 while(first != last)
+ 436 + + {
+ 437 + +750 insert(*first);
+ 438 + +677 ++first;
+ 439 + + }
+ 440 + +3 r.commit();
+ 441 + +76 }
+ 442 + +
+ 443 + + template<class InputIt>
+ 444 + + void
+ 445 + +82 object::
+ 446 + + construct(
+ 447 + + InputIt first,
+ 448 + + InputIt last,
+ 449 + + std::size_t min_capacity,
+ 450 + + std::forward_iterator_tag)
+ 451 + + {
+ 452 + +82 auto n = static_cast<
+ 453 + +82 std::size_t>(std::distance(
+ 454 + + first, last));
+ 455 + +82 if( n < min_capacity)
+ 456 + +76 n = min_capacity;
+ 457 + +82 reserve(n);
+ 458 + +79 revert_construct r(*this);
+ 459 + +771 while(first != last)
+ 460 + + {
+ 461 + +764 insert(*first);
+ 462 + +692 ++first;
+ 463 + + }
+ 464 + +7 r.commit();
+ 465 + +79 }
+ 466 + +
+ 467 + + template<class InputIt>
+ 468 + + void
+ 469 + +94 object::
+ 470 + + insert(
+ 471 + + InputIt first,
+ 472 + + InputIt last,
+ 473 + + std::input_iterator_tag)
+ 474 + + {
+ 475 + + // Since input iterators cannot be rewound,
+ 476 + + // we keep inserted elements on an exception.
+ 477 + + //
+ 478 + +871 while(first != last)
+ 479 + + {
+ 480 + +867 insert(*first);
+ 481 + +777 ++first;
+ 482 + + }
+ 483 + +4 }
+ 484 + +
+ 485 + + template<class InputIt>
+ 486 + + void
+ 487 + +80 object::
+ 488 + + insert(
+ 489 + + InputIt first,
+ 490 + + InputIt last,
+ 491 + + std::forward_iterator_tag)
+ 492 + + {
+ 493 + +80 auto const n =
+ 494 + + static_cast<std::size_t>(
+ 495 + +80 std::distance(first, last));
+ 496 + +80 auto const n0 = size();
+ 497 + +80 if(n > max_size() - n0)
+ 498 + + {
+ 499 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 500 + +1 detail::throw_system_error( error::object_too_large, &loc );
+ 501 + + }
+ 502 + +79 revert_insert r( *this, n0 + n );
+ 503 + +738 while(first != last)
+ 504 + + {
+ 505 + +734 insert(*first);
+ 506 + +661 ++first;
+ 507 + + }
+ 508 + +4 r.commit();
+ 509 + +77 }
+ 510 + +
+ 511 + + template< class... Args >
+ 512 + + std::pair<object::iterator, bool>
+ 513 + +3986 object::
+ 514 + + emplace_impl( string_view key, Args&& ... args )
+ 515 + + {
+ 516 + +3986 std::pair<iterator, std::size_t> search_result(nullptr, 0);
+ 517 + +3986 if( !empty() )
+ 518 + + {
+ 519 + +3459 search_result = detail::find_in_object(*this, key);
+ 520 + +3459 if( search_result.first )
+ 521 + +28 return { search_result.first, false };
+ 522 + + }
+ 523 + +
+ 524 + + // we create the new value before reserving, in case it is a reference to
+ 525 + + // a subobject of the current object
+ 526 + +4250 key_value_pair kv( static_cast<Args&&>(args)..., sp_ );
+ 527 + + // the key might get deallocated too
+ 528 + +3805 key = kv.key();
+ 529 + +
+ 530 + +3805 std::size_t const old_capacity = capacity();
+ 531 + +3805 reserve(size() + 1);
+ 532 + +4289 if( (empty() && capacity() > detail::small_object_size_)
+ 533 + +4289 || (capacity() != old_capacity) )
+ 534 + +724 search_result.second = detail::digest(
+ 535 + +724 key.begin(), key.end(), t_->salt);
+ 536 + +
+ 537 + +3778 BOOST_ASSERT(
+ 538 + + t_->is_small() ||
+ 539 + + (search_result.second ==
+ 540 + + detail::digest(key.begin(), key.end(), t_->salt)) );
+ 541 + +
+ 542 + +3778 return { insert_impl(pilfer(kv), search_result.second), true };
+ 543 + +3805 }
+ 544 + +
+ 545 + + //----------------------------------------------------------
+ 546 + +
+ 547 + + namespace detail {
+ 548 + +
+ 549 + +34879 unchecked_object::
+ 550 + +1086 ~unchecked_object()
+ 551 + + {
+ 552 + +34879 if(! data_)
+ 553 + +33791 return;
+ 554 + +1088 if(sp_.is_not_shared_and_deallocate_is_trivial())
+ 555 + +2 return;
+ 556 + +1086 value* p = data_;
+ 557 + +1146 while(size_--)
+ 558 + + {
+ 559 + +60 p[0].~value();
+ 560 + +60 p[1].~value();
+ 561 + +60 p += 2;
+ 562 + + }
+ 563 + +34879 }
+ 564 + +
+ 565 + + } // detail
+ 566 + +
+ 567 + + } // namespace json
+ 568 + + } // namespace boost
+ 569 + +
+ 570 + + #endif
+ 571 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.object.ipp.84c492a53a4bbdeb0fd1338b41d399a5.html b/json/gcovr/index.object.ipp.84c492a53a4bbdeb0fd1338b41d399a5.html new file mode 100644 index 00000000..9d3ea413 --- /dev/null +++ b/json/gcovr/index.object.ipp.84c492a53a4bbdeb0fd1338b41d399a5.html @@ -0,0 +1,9598 @@ + + + + + + impl/object.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/object.ipp

+
+ + 100.0% Lines (435/435) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/object.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_OBJECT_IPP
+ 11 + + #define BOOST_JSON_IMPL_OBJECT_IPP
+ 12 + +
+ 13 + + #include <boost/core/detail/static_assert.hpp>
+ 14 + + #include <boost/container_hash/hash.hpp>
+ 15 + + #include <boost/json/object.hpp>
+ 16 + + #include <boost/json/detail/digest.hpp>
+ 17 + + #include <boost/json/detail/except.hpp>
+ 18 + + #include <algorithm>
+ 19 + + #include <cmath>
+ 20 + + #include <cstdlib>
+ 21 + + #include <cstring>
+ 22 + + #include <new>
+ 23 + + #include <stdexcept>
+ 24 + + #include <type_traits>
+ 25 + +
+ 26 + + namespace boost {
+ 27 + + namespace json {
+ 28 + + namespace detail {
+ 29 + +
+ 30 + + template<class CharRange>
+ 31 + + std::pair<key_value_pair*, std::size_t>
+ 32 + +42841 find_in_object(
+ 33 + + object const& obj,
+ 34 + + CharRange key) noexcept
+ 35 + + {
+ 36 + +42841 BOOST_ASSERT(obj.t_->capacity > 0);
+ 37 + +42841 if(obj.t_->is_small())
+ 38 + + {
+ 39 + +40993 auto it = &(*obj.t_)[0];
+ 40 + + auto const last =
+ 41 + +40993 &(*obj.t_)[obj.t_->size];
+ 42 + +75323 for(;it != last; ++it)
+ 43 + +35050 if( key == it->key() )
+ 44 + +720 return { it, 0 };
+ 45 + +40273 return { nullptr, 0 };
+ 46 + + }
+ 47 + + std::pair<
+ 48 + + key_value_pair*,
+ 49 + +1848 std::size_t> result;
+ 50 + +1848 BOOST_ASSERT(obj.t_->salt != 0);
+ 51 + +1848 result.second = detail::digest(key.begin(), key.end(), obj.t_->salt);
+ 52 + +1848 auto i = obj.t_->bucket(
+ 53 + + result.second);
+ 54 + +2554 while(i != object::null_index_)
+ 55 + + {
+ 56 + +1044 auto& v = (*obj.t_)[i];
+ 57 + +1044 if( key == v.key() )
+ 58 + + {
+ 59 + +338 result.first = &v;
+ 60 + +338 return result;
+ 61 + + }
+ 62 + +706 i = access::next(v);
+ 63 + + }
+ 64 + +1510 result.first = nullptr;
+ 65 + +1510 return result;
+ 66 + + }
+ 67 + +
+ 68 + +
+ 69 + + template
+ 70 + + std::pair<key_value_pair*, std::size_t>
+ 71 + + find_in_object<string_view>(
+ 72 + + object const& obj,
+ 73 + + string_view key) noexcept;
+ 74 + +
+ 75 + + } // namespace detail
+ 76 + +
+ 77 + + //----------------------------------------------------------
+ 78 + +
+ 79 + + constexpr object::table::table() = default;
+ 80 + +
+ 81 + + // empty objects point here
+ 82 + + BOOST_JSON_REQUIRE_CONST_INIT
+ 83 + + object::table object::empty_;
+ 84 + +
+ 85 + + std::size_t
+ 86 + +7139 object::table::
+ 87 + + digest(string_view key) const noexcept
+ 88 + + {
+ 89 + +7139 BOOST_ASSERT(salt != 0);
+ 90 + +7139 return detail::digest(
+ 91 + +14278 key.begin(), key.end(), salt);
+ 92 + + }
+ 93 + +
+ 94 + + auto
+ 95 + +10517 object::table::
+ 96 + + bucket(std::size_t hash) noexcept ->
+ 97 + + index_t&
+ 98 + + {
+ 99 + + return reinterpret_cast<
+ 100 + +10517 index_t*>(&(*this)[capacity])[
+ 101 + +10517 hash % capacity];
+ 102 + + }
+ 103 + +
+ 104 + + auto
+ 105 + +7082 object::table::
+ 106 + + bucket(string_view key) noexcept ->
+ 107 + + index_t&
+ 108 + + {
+ 109 + +7082 return bucket(digest(key));
+ 110 + + }
+ 111 + +
+ 112 + + void
+ 113 + +392 object::table::
+ 114 + + clear() noexcept
+ 115 + + {
+ 116 + +392 BOOST_ASSERT(! is_small());
+ 117 + + // initialize buckets
+ 118 + +784 std::memset(
+ 119 + + reinterpret_cast<index_t*>(
+ 120 + +392 &(*this)[capacity]),
+ 121 + + 0xff, // null_index_
+ 122 + +392 capacity * sizeof(index_t));
+ 123 + +392 }
+ 124 + +
+ 125 + + object::table*
+ 126 + +35477 object::table::
+ 127 + + allocate(
+ 128 + + std::size_t capacity,
+ 129 + + std::uintptr_t salt,
+ 130 + + storage_ptr const& sp)
+ 131 + + {
+ 132 + + BOOST_CORE_STATIC_ASSERT(
+ 133 + + alignof(key_value_pair) >= alignof(index_t));
+ 134 + +35477 BOOST_ASSERT(capacity > 0);
+ 135 + +35477 BOOST_ASSERT(capacity <= max_size());
+ 136 + + table* p;
+ 137 + +35477 if(capacity <= detail::small_object_size_)
+ 138 + + {
+ 139 + + p = reinterpret_cast<
+ 140 + +35074 table*>(sp->allocate(
+ 141 + +35074 sizeof(table) + capacity *
+ 142 + + sizeof(key_value_pair)));
+ 143 + +34983 p->capacity = static_cast<
+ 144 + + std::uint32_t>(capacity);
+ 145 + + }
+ 146 + + else
+ 147 + + {
+ 148 + + p = reinterpret_cast<
+ 149 + +403 table*>(sp->allocate(
+ 150 + +403 sizeof(table) + capacity * (
+ 151 + + sizeof(key_value_pair) +
+ 152 + + sizeof(index_t))));
+ 153 + +388 p->capacity = static_cast<
+ 154 + + std::uint32_t>(capacity);
+ 155 + +388 p->clear();
+ 156 + + }
+ 157 + +35371 if(salt)
+ 158 + + {
+ 159 + +489 p->salt = salt;
+ 160 + + }
+ 161 + + else
+ 162 + + {
+ 163 + + // VFALCO This would be better if it
+ 164 + + // was random, but maybe this
+ 165 + + // is good enough.
+ 166 + +34882 p->salt = reinterpret_cast<
+ 167 + + std::uintptr_t>(p);
+ 168 + + }
+ 169 + +35371 return p;
+ 170 + + }
+ 171 + +
+ 172 + + //----------------------------------------------------------
+ 173 + +
+ 174 + + void
+ 175 + +374 object::
+ 176 + + revert_construct::
+ 177 + + destroy() noexcept
+ 178 + + {
+ 179 + +374 obj_->destroy();
+ 180 + +374 }
+ 181 + +
+ 182 + + //----------------------------------------------------------
+ 183 + +
+ 184 + + void
+ 185 + +230 object::
+ 186 + + revert_insert::
+ 187 + + destroy() noexcept
+ 188 + + {
+ 189 + +230 obj_->destroy(
+ 190 + +230 &(*obj_->t_)[size_],
+ 191 + +230 obj_->end());
+ 192 + +230 }
+ 193 + +
+ 194 + + //----------------------------------------------------------
+ 195 + + //
+ 196 + + // Construction
+ 197 + + //
+ 198 + + //----------------------------------------------------------
+ 199 + +
+ 200 + +34879 object::
+ 201 + +34879 object(detail::unchecked_object&& uo)
+ 202 + +34879 : sp_(uo.storage())
+ 203 + + {
+ 204 + +34879 if(uo.size() == 0)
+ 205 + + {
+ 206 + +1049 t_ = &empty_;
+ 207 + +1049 return;
+ 208 + + }
+ 209 + + // should already be checked
+ 210 + +33830 BOOST_ASSERT(
+ 211 + + uo.size() <= max_size());
+ 212 + +33830 t_ = table::allocate(
+ 213 + +33830 uo.size(), 0, sp_);
+ 214 + +
+ 215 + + // insert all elements, keeping
+ 216 + + // the last of any duplicate keys.
+ 217 + +33791 auto dest = begin();
+ 218 + +33791 auto src = uo.release();
+ 219 + +33791 auto const end = src + 2 * uo.size();
+ 220 + +33791 if(t_->is_small())
+ 221 + + {
+ 222 + +33758 t_->size = 0;
+ 223 + +70267 while(src != end)
+ 224 + + {
+ 225 + +36509 access::construct_key_value_pair(
+ 226 + +36509 dest, pilfer(src[0]), pilfer(src[1]));
+ 227 + +36509 src += 2;
+ 228 + +36509 auto result = detail::find_in_object(*this, dest->key());
+ 229 + +36509 if(! result.first)
+ 230 + + {
+ 231 + +36499 ++dest;
+ 232 + +36499 ++t_->size;
+ 233 + +36499 continue;
+ 234 + + }
+ 235 + + // handle duplicate
+ 236 + +10 auto& v = *result.first;
+ 237 + + // don't bother to check if
+ 238 + + // storage deallocate is trivial
+ 239 + +10 v.~key_value_pair();
+ 240 + + // trivial relocate
+ 241 + +10 std::memcpy(
+ 242 + + static_cast<void*>(&v),
+ 243 + + dest, sizeof(v));
+ 244 + + }
+ 245 + +33758 return;
+ 246 + + }
+ 247 + +1674 while(src != end)
+ 248 + + {
+ 249 + +1641 access::construct_key_value_pair(
+ 250 + +1641 dest, pilfer(src[0]), pilfer(src[1]));
+ 251 + +1641 src += 2;
+ 252 + +1641 auto& head = t_->bucket(dest->key());
+ 253 + +1641 auto i = head;
+ 254 + + for(;;)
+ 255 + + {
+ 256 + +2344 if(i == null_index_)
+ 257 + + {
+ 258 + + // end of bucket
+ 259 + +1640 access::next(
+ 260 + +1640 *dest) = head;
+ 261 + +1640 head = static_cast<index_t>(
+ 262 + +1640 dest - begin());
+ 263 + +1640 ++dest;
+ 264 + +1640 break;
+ 265 + + }
+ 266 + +704 auto& v = (*t_)[i];
+ 267 + +704 if(v.key() != dest->key())
+ 268 + + {
+ 269 + +703 i = access::next(v);
+ 270 + +703 continue;
+ 271 + + }
+ 272 + +
+ 273 + + // handle duplicate
+ 274 + +1 access::next(*dest) =
+ 275 + +1 access::next(v);
+ 276 + + // don't bother to check if
+ 277 + + // storage deallocate is trivial
+ 278 + +1 v.~key_value_pair();
+ 279 + + // trivial relocate
+ 280 + +1 std::memcpy(
+ 281 + + static_cast<void*>(&v),
+ 282 + + dest, sizeof(v));
+ 283 + +1 break;
+ 284 + +703 }
+ 285 + + }
+ 286 + +33 t_->size = static_cast<
+ 287 + +33 index_t>(dest - begin());
+ 288 + +39 }
+ 289 + +
+ 290 + +35944 object::
+ 291 + +34394 ~object() noexcept
+ 292 + + {
+ 293 + +35944 if(sp_.is_not_shared_and_deallocate_is_trivial())
+ 294 + +5 return;
+ 295 + +35939 if(t_->capacity == 0)
+ 296 + +1545 return;
+ 297 + +34394 destroy();
+ 298 + +35944 }
+ 299 + +
+ 300 + +7 object::
+ 301 + + object(
+ 302 + + std::size_t min_capacity,
+ 303 + +7 storage_ptr sp)
+ 304 + +7 : sp_(std::move(sp))
+ 305 + +7 , t_(&empty_)
+ 306 + + {
+ 307 + +7 reserve(min_capacity);
+ 308 + +7 }
+ 309 + +
+ 310 + +71 object::
+ 311 + +71 object(object&& other) noexcept
+ 312 + +71 : sp_(other.sp_)
+ 313 + +142 , t_(detail::exchange(
+ 314 + +71 other.t_, &empty_))
+ 315 + + {
+ 316 + +71 }
+ 317 + +
+ 318 + +184 object::
+ 319 + + object(
+ 320 + + object&& other,
+ 321 + +184 storage_ptr sp)
+ 322 + +184 : sp_(std::move(sp))
+ 323 + + {
+ 324 + +184 if(*sp_ == *other.sp_)
+ 325 + + {
+ 326 + +192 t_ = detail::exchange(
+ 327 + +96 other.t_, &empty_);
+ 328 + +96 return;
+ 329 + + }
+ 330 + +
+ 331 + +88 t_ = &empty_;
+ 332 + +151 object(other, sp_).swap(*this);
+ 333 + +63 }
+ 334 + +
+ 335 + +197 object::
+ 336 + + object(
+ 337 + + object const& other,
+ 338 + +197 storage_ptr sp)
+ 339 + +197 : sp_(std::move(sp))
+ 340 + +197 , t_(&empty_)
+ 341 + + {
+ 342 + +197 reserve(other.size());
+ 343 + +185 revert_construct r(*this);
+ 344 + +185 if(t_->is_small())
+ 345 + + {
+ 346 + +712 for(auto const& v : other)
+ 347 + + {
+ 348 + +724 ::new(end())
+ 349 + +800 key_value_pair(v, sp_);
+ 350 + +572 ++t_->size;
+ 351 + + }
+ 352 + +64 r.commit();
+ 353 + +64 return;
+ 354 + + }
+ 355 + +2485 for(auto const& v : other)
+ 356 + + {
+ 357 + + // skip duplicate checking
+ 358 + + auto& head =
+ 359 + +2480 t_->bucket(v.key());
+ 360 + +2480 auto pv = ::new(end())
+ 361 + +2520 key_value_pair(v, sp_);
+ 362 + +2440 access::next(*pv) = head;
+ 363 + +2440 head = t_->size;
+ 364 + +2440 ++t_->size;
+ 365 + + }
+ 366 + +5 r.commit();
+ 367 + +313 }
+ 368 + +
+ 369 + +381 object::
+ 370 + + object(
+ 371 + + std::initializer_list<std::pair<
+ 372 + + string_view, value_ref>> init,
+ 373 + + std::size_t min_capacity,
+ 374 + +381 storage_ptr sp)
+ 375 + +381 : sp_(std::move(sp))
+ 376 + +381 , t_(&empty_)
+ 377 + + {
+ 378 + +381 if( min_capacity < init.size())
+ 379 + +335 min_capacity = init.size();
+ 380 + +381 reserve(min_capacity);
+ 381 + +365 revert_construct r(*this);
+ 382 + +365 insert(init);
+ 383 + +252 r.commit();
+ 384 + +494 }
+ 385 + +
+ 386 + + //----------------------------------------------------------
+ 387 + + //
+ 388 + + // Assignment
+ 389 + + //
+ 390 + + //----------------------------------------------------------
+ 391 + +
+ 392 + + object&
+ 393 + +22 object::
+ 394 + + operator=(object const& other)
+ 395 + + {
+ 396 + +39 object tmp(other, sp_);
+ 397 + +5 this->~object();
+ 398 + +5 ::new(this) object(pilfer(tmp));
+ 399 + +5 return *this;
+ 400 + +5 }
+ 401 + +
+ 402 + + object&
+ 403 + +7 object::
+ 404 + + operator=(object&& other)
+ 405 + + {
+ 406 + +11 object tmp(std::move(other), sp_);
+ 407 + +3 this->~object();
+ 408 + +3 ::new(this) object(pilfer(tmp));
+ 409 + +3 return *this;
+ 410 + +3 }
+ 411 + +
+ 412 + + object&
+ 413 + +7 object::
+ 414 + + operator=(
+ 415 + + std::initializer_list<std::pair<
+ 416 + + string_view, value_ref>> init)
+ 417 + + {
+ 418 + +11 object tmp(init, sp_);
+ 419 + +3 this->~object();
+ 420 + +3 ::new(this) object(pilfer(tmp));
+ 421 + +3 return *this;
+ 422 + +3 }
+ 423 + +
+ 424 + + //----------------------------------------------------------
+ 425 + + //
+ 426 + + // Lookup
+ 427 + + //
+ 428 + + //----------------------------------------------------------
+ 429 + +
+ 430 + + system::result<value&>
+ 431 + +4 object::
+ 432 + + try_at(string_view key) noexcept
+ 433 + + {
+ 434 + +4 auto it = find(key);
+ 435 + +4 if( it != end() )
+ 436 + +2 return it->value();
+ 437 + +
+ 438 + +2 system::error_code ec;
+ 439 + +2 BOOST_JSON_FAIL(ec, error::out_of_range);
+ 440 + +2 return ec;
+ 441 + + }
+ 442 + +
+ 443 + + system::result<value const&>
+ 444 + +107 object::
+ 445 + + try_at(string_view key) const noexcept
+ 446 + + {
+ 447 + +107 auto it = find(key);
+ 448 + +107 if( it != end() )
+ 449 + +101 return it->value();
+ 450 + +
+ 451 + +6 system::error_code ec;
+ 452 + +6 BOOST_JSON_FAIL(ec, error::out_of_range);
+ 453 + +6 return ec;
+ 454 + + }
+ 455 + +
+ 456 + + value const&
+ 457 + +103 object::
+ 458 + + at(string_view key, source_location const& loc) const&
+ 459 + + {
+ 460 + +103 return try_at(key).value(loc);
+ 461 + + }
+ 462 + +
+ 463 + + //----------------------------------------------------------
+ 464 + + //
+ 465 + + // Modifiers
+ 466 + + //
+ 467 + + //----------------------------------------------------------
+ 468 + +
+ 469 + + void
+ 470 + +7 object::
+ 471 + + clear() noexcept
+ 472 + + {
+ 473 + +7 if(empty())
+ 474 + +2 return;
+ 475 + +5 if(! sp_.is_not_shared_and_deallocate_is_trivial())
+ 476 + +5 destroy(begin(), end());
+ 477 + +5 if(! t_->is_small())
+ 478 + +4 t_->clear();
+ 479 + +5 t_->size = 0;
+ 480 + + }
+ 481 + +
+ 482 + + void
+ 483 + +425 object::
+ 484 + + insert(
+ 485 + + std::initializer_list<std::pair<
+ 486 + + string_view, value_ref>> init)
+ 487 + + {
+ 488 + +425 auto const n0 = size();
+ 489 + +425 if(init.size() > max_size() - n0)
+ 490 + + {
+ 491 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 492 + +1 detail::throw_system_error( error::object_too_large, &loc );
+ 493 + + }
+ 494 + +424 revert_insert r( *this, n0 + init.size() );
+ 495 + +417 if(t_->is_small())
+ 496 + + {
+ 497 + +2032 for(auto& iv : init)
+ 498 + + {
+ 499 + + auto result =
+ 500 + +1832 detail::find_in_object(*this, iv.first);
+ 501 + +1832 if(result.first)
+ 502 + + {
+ 503 + + // ignore duplicate
+ 504 + +4 continue;
+ 505 + + }
+ 506 + +1905 ::new(end()) key_value_pair(
+ 507 + + iv.first,
+ 508 + +2056 iv.second.make_value(sp_));
+ 509 + +1751 ++t_->size;
+ 510 + + }
+ 511 + +200 r.commit();
+ 512 + +200 return;
+ 513 + + }
+ 514 + +1999 for(auto& iv : init)
+ 515 + + {
+ 516 + +1939 auto& head = t_->bucket(iv.first);
+ 517 + +1939 auto i = head;
+ 518 + + for(;;)
+ 519 + + {
+ 520 + +2482 if(i == null_index_)
+ 521 + + {
+ 522 + + // VFALCO value_ref should construct
+ 523 + + // a key_value_pair using placement
+ 524 + +1937 auto& v = *::new(end())
+ 525 + + key_value_pair(
+ 526 + + iv.first,
+ 527 + +2097 iv.second.make_value(sp_));
+ 528 + +1857 access::next(v) = head;
+ 529 + +1857 head = static_cast<index_t>(
+ 530 + +1857 t_->size);
+ 531 + +1857 ++t_->size;
+ 532 + +1857 break;
+ 533 + + }
+ 534 + +545 auto& v = (*t_)[i];
+ 535 + +545 if(v.key() == iv.first)
+ 536 + + {
+ 537 + + // ignore duplicate
+ 538 + +2 break;
+ 539 + + }
+ 540 + +543 i = access::next(v);
+ 541 + +543 }
+ 542 + + }
+ 543 + +60 r.commit();
+ 544 + +417 }
+ 545 + +
+ 546 + + auto
+ 547 + +6 object::
+ 548 + + erase(const_iterator pos) noexcept ->
+ 549 + + iterator
+ 550 + + {
+ 551 + +6 return do_erase(pos,
+ 552 + +2 [this](iterator p) {
+ 553 + + // the casts silence warnings
+ 554 + +2 std::memcpy(
+ 555 + + static_cast<void*>(p),
+ 556 + +2 static_cast<void const*>(end()),
+ 557 + + sizeof(*p));
+ 558 + +2 },
+ 559 + +3 [this](iterator p) {
+ 560 + +3 reindex_relocate(end(), p);
+ 561 + +6 });
+ 562 + + }
+ 563 + +
+ 564 + + auto
+ 565 + +5 object::
+ 566 + + erase(string_view key) noexcept ->
+ 567 + + std::size_t
+ 568 + + {
+ 569 + +5 auto it = find(key);
+ 570 + +5 if(it == end())
+ 571 + +1 return 0;
+ 572 + +4 erase(it);
+ 573 + +4 return 1;
+ 574 + + }
+ 575 + +
+ 576 + + auto
+ 577 + +3 object::
+ 578 + + stable_erase(const_iterator pos) noexcept ->
+ 579 + + iterator
+ 580 + + {
+ 581 + +3 return do_erase(pos,
+ 582 + +2 [this](iterator p) {
+ 583 + + // the casts silence warnings
+ 584 + +2 std::memmove(
+ 585 + + static_cast<void*>(p),
+ 586 + +2 static_cast<void const*>(p + 1),
+ 587 + +2 sizeof(*p) * (end() - p));
+ 588 + +2 },
+ 589 + +1 [this](iterator p) {
+ 590 + +10 for (; p != end(); ++p)
+ 591 + + {
+ 592 + +9 reindex_relocate(p + 1, p);
+ 593 + + }
+ 594 + +3 });
+ 595 + + }
+ 596 + +
+ 597 + + auto
+ 598 + +2 object::
+ 599 + + stable_erase(string_view key) noexcept ->
+ 600 + + std::size_t
+ 601 + + {
+ 602 + +2 auto it = find(key);
+ 603 + +2 if(it == end())
+ 604 + +1 return 0;
+ 605 + +1 stable_erase(it);
+ 606 + +1 return 1;
+ 607 + + }
+ 608 + +
+ 609 + + void
+ 610 + +36 object::
+ 611 + + swap(object& other)
+ 612 + + {
+ 613 + +36 if(*sp_ == *other.sp_)
+ 614 + + {
+ 615 + +52 t_ = detail::exchange(
+ 616 + +26 other.t_, t_);
+ 617 + +26 return;
+ 618 + + }
+ 619 + + object temp1(
+ 620 + +10 std::move(*this),
+ 621 + +24 other.storage());
+ 622 + + object temp2(
+ 623 + +6 std::move(other),
+ 624 + +16 this->storage());
+ 625 + +2 other.~object();
+ 626 + +2 ::new(&other) object(pilfer(temp1));
+ 627 + +2 this->~object();
+ 628 + +2 ::new(this) object(pilfer(temp2));
+ 629 + +6 }
+ 630 + +
+ 631 + + //----------------------------------------------------------
+ 632 + + //
+ 633 + + // Lookup
+ 634 + + //
+ 635 + + //----------------------------------------------------------
+ 636 + +
+ 637 + + auto
+ 638 + +144 object::
+ 639 + + operator[](string_view key) ->
+ 640 + + value&
+ 641 + + {
+ 642 + + auto const result =
+ 643 + +144 emplace(key, nullptr);
+ 644 + +288 return result.first->value();
+ 645 + + }
+ 646 + +
+ 647 + + auto
+ 648 + +8 object::
+ 649 + + count(string_view key) const noexcept ->
+ 650 + + std::size_t
+ 651 + + {
+ 652 + +8 if(find(key) == end())
+ 653 + +3 return 0;
+ 654 + +5 return 1;
+ 655 + + }
+ 656 + +
+ 657 + + auto
+ 658 + +27 object::
+ 659 + + find(string_view key) noexcept ->
+ 660 + + iterator
+ 661 + + {
+ 662 + +27 if(empty())
+ 663 + +1 return end();
+ 664 + + auto const p =
+ 665 + +26 detail::find_in_object(*this, key).first;
+ 666 + +26 if(p)
+ 667 + +20 return p;
+ 668 + +6 return end();
+ 669 + + }
+ 670 + +
+ 671 + + auto
+ 672 + +878 object::
+ 673 + + find(string_view key) const noexcept ->
+ 674 + + const_iterator
+ 675 + + {
+ 676 + +878 if(empty())
+ 677 + +1 return end();
+ 678 + + auto const p =
+ 679 + +877 detail::find_in_object(*this, key).first;
+ 680 + +877 if(p)
+ 681 + +865 return p;
+ 682 + +12 return end();
+ 683 + + }
+ 684 + +
+ 685 + + bool
+ 686 + +3 object::
+ 687 + + contains(
+ 688 + + string_view key) const noexcept
+ 689 + + {
+ 690 + +3 if(empty())
+ 691 + +1 return false;
+ 692 + +2 return detail::find_in_object(*this, key).first
+ 693 + +2 != nullptr;
+ 694 + + }
+ 695 + +
+ 696 + + value const*
+ 697 + +3 object::
+ 698 + + if_contains(
+ 699 + + string_view key) const noexcept
+ 700 + + {
+ 701 + +3 auto const it = find(key);
+ 702 + +3 if(it != end())
+ 703 + +2 return &it->value();
+ 704 + +1 return nullptr;
+ 705 + + }
+ 706 + +
+ 707 + + value*
+ 708 + +5 object::
+ 709 + + if_contains(
+ 710 + + string_view key) noexcept
+ 711 + + {
+ 712 + +5 auto const it = find(key);
+ 713 + +5 if(it != end())
+ 714 + +4 return &it->value();
+ 715 + +1 return nullptr;
+ 716 + + }
+ 717 + +
+ 718 + + //----------------------------------------------------------
+ 719 + + //
+ 720 + + // (private)
+ 721 + + //
+ 722 + + //----------------------------------------------------------
+ 723 + +
+ 724 + + key_value_pair*
+ 725 + +3778 object::
+ 726 + + insert_impl(
+ 727 + + pilfered<key_value_pair> p,
+ 728 + + std::size_t hash)
+ 729 + + {
+ 730 + +3778 BOOST_ASSERT(
+ 731 + + capacity() > size());
+ 732 + +3778 if(t_->is_small())
+ 733 + + {
+ 734 + +2191 auto const pv = ::new(end())
+ 735 + +2191 key_value_pair(p);
+ 736 + +2191 ++t_->size;
+ 737 + +2191 return pv;
+ 738 + + }
+ 739 + + auto& head =
+ 740 + +1587 t_->bucket(hash);
+ 741 + +1587 auto const pv = ::new(end())
+ 742 + +1587 key_value_pair(p);
+ 743 + +1587 access::next(*pv) = head;
+ 744 + +1587 head = t_->size;
+ 745 + +1587 ++t_->size;
+ 746 + +1587 return pv;
+ 747 + + }
+ 748 + +
+ 749 + + // allocate new table, copy elements there, and rehash them
+ 750 + + object::table*
+ 751 + +1654 object::
+ 752 + + reserve_impl(std::size_t new_capacity)
+ 753 + + {
+ 754 + +1654 BOOST_ASSERT(
+ 755 + + new_capacity > t_->capacity);
+ 756 + +1647 auto t = table::allocate(
+ 757 + + growth(new_capacity),
+ 758 + +1654 t_->salt, sp_);
+ 759 + +1580 if(! empty())
+ 760 + +488 std::memcpy(
+ 761 + + static_cast<
+ 762 + +488 void*>(&(*t)[0]),
+ 763 + +488 begin(),
+ 764 + +488 size() * sizeof(
+ 765 + + key_value_pair));
+ 766 + +1580 t->size = t_->size;
+ 767 + +1580 std::swap(t_, t);
+ 768 + +
+ 769 + +1580 if(! t_->is_small())
+ 770 + + {
+ 771 + + // rebuild hash table,
+ 772 + + // without dup checks
+ 773 + +355 auto p = end();
+ 774 + +355 index_t i = t_->size;
+ 775 + +1360 while(i-- > 0)
+ 776 + + {
+ 777 + +1005 --p;
+ 778 + + auto& head =
+ 779 + +1005 t_->bucket(p->key());
+ 780 + +1005 access::next(*p) = head;
+ 781 + +1005 head = i;
+ 782 + + }
+ 783 + + }
+ 784 + +
+ 785 + +1580 return t;
+ 786 + + }
+ 787 + +
+ 788 + + bool
+ 789 + +75 object::
+ 790 + + equal(object const& other) const noexcept
+ 791 + + {
+ 792 + +75 if(size() != other.size())
+ 793 + +5 return false;
+ 794 + +70 auto const end_ = other.end();
+ 795 + +825 for(auto e : *this)
+ 796 + + {
+ 797 + +757 auto it = other.find(e.key());
+ 798 + +757 if(it == end_)
+ 799 + +1 return false;
+ 800 + +756 if(it->value() != e.value())
+ 801 + +1 return false;
+ 802 + +757 }
+ 803 + +68 return true;
+ 804 + + }
+ 805 + +
+ 806 + + std::size_t
+ 807 + +1654 object::
+ 808 + + growth(
+ 809 + + std::size_t new_size) const
+ 810 + + {
+ 811 + +1654 if(new_size > max_size())
+ 812 + + {
+ 813 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 814 + +7 detail::throw_system_error( error::object_too_large, &loc );
+ 815 + + }
+ 816 + +1647 std::size_t const old = capacity();
+ 817 + +1647 if(old > max_size() - old / 2)
+ 818 + +2 return new_size;
+ 819 + +1645 std::size_t const g =
+ 820 + +1645 old + old / 2; // 1.5x
+ 821 + +1645 if(g < new_size)
+ 822 + +1243 return new_size;
+ 823 + +402 return g;
+ 824 + + }
+ 825 + +
+ 826 + + void
+ 827 + +17 object::
+ 828 + + remove(
+ 829 + + index_t& head,
+ 830 + + key_value_pair& v) noexcept
+ 831 + + {
+ 832 + +17 BOOST_ASSERT(! t_->is_small());
+ 833 + + auto const i = static_cast<
+ 834 + +17 index_t>(&v - begin());
+ 835 + +17 if(head == i)
+ 836 + + {
+ 837 + +9 head = access::next(v);
+ 838 + +9 return;
+ 839 + + }
+ 840 + + auto* pn =
+ 841 + +8 &access::next((*t_)[head]);
+ 842 + +9 while(*pn != i)
+ 843 + +1 pn = &access::next((*t_)[*pn]);
+ 844 + +8 *pn = access::next(v);
+ 845 + + }
+ 846 + +
+ 847 + + void
+ 848 + +34768 object::
+ 849 + + destroy() noexcept
+ 850 + + {
+ 851 + +34768 BOOST_ASSERT(t_->capacity > 0);
+ 852 + +34768 BOOST_ASSERT(! sp_.is_not_shared_and_deallocate_is_trivial());
+ 853 + +34768 destroy(begin(), end());
+ 854 + +34768 table::deallocate(t_, sp_);
+ 855 + +34768 }
+ 856 + +
+ 857 + + void
+ 858 + +35003 object::
+ 859 + + destroy(
+ 860 + + key_value_pair* first,
+ 861 + + key_value_pair* last) noexcept
+ 862 + + {
+ 863 + +35003 BOOST_ASSERT(! sp_.is_not_shared_and_deallocate_is_trivial());
+ 864 + +83509 while(last != first)
+ 865 + +48506 (--last)->~key_value_pair();
+ 866 + +35003 }
+ 867 + +
+ 868 + + template<class FS, class FB>
+ 869 + + auto
+ 870 + +9 object::
+ 871 + + do_erase(
+ 872 + + const_iterator pos,
+ 873 + + FS small_reloc,
+ 874 + + FB big_reloc) noexcept
+ 875 + + -> iterator
+ 876 + + {
+ 877 + +9 auto p = begin() + (pos - begin());
+ 878 + +9 if(t_->is_small())
+ 879 + + {
+ 880 + +4 p->~value_type();
+ 881 + +4 --t_->size;
+ 882 + +4 if(p != end())
+ 883 + + {
+ 884 + +4 small_reloc(p);
+ 885 + + }
+ 886 + +4 return p;
+ 887 + + }
+ 888 + +5 remove(t_->bucket(p->key()), *p);
+ 889 + +5 p->~value_type();
+ 890 + +5 --t_->size;
+ 891 + +5 if(p != end())
+ 892 + + {
+ 893 + +4 big_reloc(p);
+ 894 + + }
+ 895 + +5 return p;
+ 896 + + }
+ 897 + +
+ 898 + + void
+ 899 + +12 object::
+ 900 + + reindex_relocate(
+ 901 + + key_value_pair* src,
+ 902 + + key_value_pair* dst) noexcept
+ 903 + + {
+ 904 + +12 BOOST_ASSERT(! t_->is_small());
+ 905 + +12 auto& head = t_->bucket(src->key());
+ 906 + +12 remove(head, *src);
+ 907 + + // the casts silence warnings
+ 908 + +12 std::memcpy(
+ 909 + + static_cast<void*>(dst),
+ 910 + + static_cast<void const*>(src),
+ 911 + + sizeof(*dst));
+ 912 + +12 access::next(*dst) = head;
+ 913 + +12 head = static_cast<
+ 914 + +12 index_t>(dst - begin());
+ 915 + +12 }
+ 916 + +
+ 917 + + } // namespace json
+ 918 + + } // namespace boost
+ 919 + +
+ 920 + + //----------------------------------------------------------
+ 921 + + //
+ 922 + + // std::hash specialization
+ 923 + + //
+ 924 + + //----------------------------------------------------------
+ 925 + +
+ 926 + + std::size_t
+ 927 + +8 std::hash<::boost::json::object>::operator()(
+ 928 + + ::boost::json::object const& jo) const noexcept
+ 929 + + {
+ 930 + +8 return ::boost::hash< ::boost::json::object >()( jo );
+ 931 + + }
+ 932 + +
+ 933 + + //----------------------------------------------------------
+ 934 + +
+ 935 + +
+ 936 + + #endif
+ 937 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.parse.ipp.bda6280a016bf6834766bc3a0bff32bc.html b/json/gcovr/index.parse.ipp.bda6280a016bf6834766bc3a0bff32bc.html new file mode 100644 index 00000000..9bcfec7f --- /dev/null +++ b/json/gcovr/index.parse.ipp.bda6280a016bf6834766bc3a0bff32bc.html @@ -0,0 +1,3198 @@ + + + + + + impl/parse.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/parse.ipp

+
+ + 96.1% Lines (49/51) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/parse.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_IMPL_PARSE_IPP
+ 12 + + #define BOOST_JSON_IMPL_PARSE_IPP
+ 13 + +
+ 14 + + #include <boost/json/parse.hpp>
+ 15 + + #include <boost/json/parser.hpp>
+ 16 + + #include <boost/json/detail/except.hpp>
+ 17 + +
+ 18 + + #include <istream>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + +
+ 23 + + value
+ 24 + +2001505 parse(
+ 25 + + string_view s,
+ 26 + + system::error_code& ec,
+ 27 + + storage_ptr sp,
+ 28 + + const parse_options& opt)
+ 29 + + {
+ 30 + + unsigned char temp[
+ 31 + + BOOST_JSON_STACK_BUFFER_SIZE];
+ 32 + +2001505 parser p(storage_ptr(), opt, temp);
+ 33 + +2001505 p.reset(std::move(sp));
+ 34 + +2001505 p.write(s, ec);
+ 35 + +2001504 if(ec)
+ 36 + +15 return nullptr;
+ 37 + +2001489 return p.release();
+ 38 + +2001505 }
+ 39 + +
+ 40 + + value
+ 41 + +4 parse(
+ 42 + + string_view s,
+ 43 + + std::error_code& ec,
+ 44 + + storage_ptr sp,
+ 45 + + parse_options const& opt)
+ 46 + + {
+ 47 + +4 system::error_code jec;
+ 48 + +4 value result = parse(s, jec, std::move(sp), opt);
+ 49 + +4 ec = jec;
+ 50 + +8 return result;
+ 51 + + }
+ 52 + +
+ 53 + + value
+ 54 + +2001038 parse(
+ 55 + + string_view s,
+ 56 + + storage_ptr sp,
+ 57 + + const parse_options& opt)
+ 58 + + {
+ 59 + +2001038 system::error_code ec;
+ 60 + + auto jv = parse(
+ 61 + +2001039 s, ec, std::move(sp), opt);
+ 62 + +2001037 if(ec)
+ 63 + +2 detail::throw_system_error( ec );
+ 64 + +4002070 return jv;
+ 65 + +2 }
+ 66 + +
+ 67 + + value
+ 68 + +10 parse(
+ 69 + + std::istream& is,
+ 70 + + system::error_code& ec,
+ 71 + + storage_ptr sp,
+ 72 + + parse_options const& opt)
+ 73 + + {
+ 74 + + unsigned char parser_buffer[BOOST_JSON_STACK_BUFFER_SIZE / 2];
+ 75 + +10 stream_parser p(storage_ptr(), opt, parser_buffer);
+ 76 + +10 p.reset(std::move(sp));
+ 77 + +
+ 78 + + char read_buffer[BOOST_JSON_STACK_BUFFER_SIZE / 2];
+ 79 + + do
+ 80 + + {
+ 81 + +17 if( is.eof() )
+ 82 + + {
+ 83 + +7 p.finish(ec);
+ 84 + +7 break;
+ 85 + + }
+ 86 + +
+ 87 + +10 if( !is )
+ 88 + + {
+ 89 + +1 BOOST_JSON_FAIL( ec, error::input_error );
+ 90 + +1 break;
+ 91 + + }
+ 92 + +
+ 93 + +9 is.read(read_buffer, sizeof(read_buffer));
+ 94 + +9 auto const consumed = is.gcount();
+ 95 + +
+ 96 + +9 p.write( read_buffer, static_cast<std::size_t>(consumed), ec );
+ 97 + + }
+ 98 + +9 while( !ec.failed() );
+ 99 + +
+ 100 + +10 if( ec.failed() )
+ 101 + +3 return nullptr;
+ 102 + +
+ 103 + +7 return p.release();
+ 104 + +10 }
+ 105 + +
+ 106 + + value
+ 107 + +4 parse(
+ 108 + + std::istream& is,
+ 109 + + std::error_code& ec,
+ 110 + + storage_ptr sp,
+ 111 + + parse_options const& opt)
+ 112 + + {
+ 113 + +4 system::error_code jec;
+ 114 + +4 value result = parse(is, jec, std::move(sp), opt);
+ 115 + +4 ec = jec;
+ 116 + +8 return result;
+ 117 + + }
+ 118 + +
+ 119 + + value
+ 120 + +2 parse(
+ 121 + + std::istream& is,
+ 122 + + storage_ptr sp,
+ 123 + + parse_options const& opt)
+ 124 + + {
+ 125 + +2 system::error_code ec;
+ 126 + + auto jv = parse(
+ 127 + +2 is, ec, std::move(sp), opt);
+ 128 + +2 if(ec)
+ 129 + +1 detail::throw_system_error( ec );
+ 130 + +2 return jv;
+ 131 + +1 }
+ 132 + +
+ 133 + + } // namespace json
+ 134 + + } // namespace boost
+ 135 + +
+ 136 + + #endif
+ 137 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.parse_into.hpp.9fe27b0246ac36c90c713d2ffcd261fd.html b/json/gcovr/index.parse_into.hpp.9fe27b0246ac36c90c713d2ffcd261fd.html new file mode 100644 index 00000000..b6f35d91 --- /dev/null +++ b/json/gcovr/index.parse_into.hpp.9fe27b0246ac36c90c713d2ffcd261fd.html @@ -0,0 +1,3158 @@ + + + + + + impl/parse_into.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/parse_into.hpp

+
+ + 100.0% Lines (43/43) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/parse_into.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_IMPL_PARSE_INTO_HPP
+ 12 + + #define BOOST_JSON_IMPL_PARSE_INTO_HPP
+ 13 + +
+ 14 + + #include <boost/json/basic_parser_impl.hpp>
+ 15 + + #include <boost/json/error.hpp>
+ 16 + + #include <istream>
+ 17 + +
+ 18 + + namespace boost {
+ 19 + + namespace json {
+ 20 + +
+ 21 + + template<class V>
+ 22 + + void
+ 23 + +232 parse_into(
+ 24 + + V& v,
+ 25 + + string_view sv,
+ 26 + + system::error_code& ec,
+ 27 + + parse_options const& opt )
+ 28 + + {
+ 29 + +232 parser_for<V> p( opt, &v );
+ 30 + +
+ 31 + +232 std::size_t n = p.write_some( false, sv.data(), sv.size(), ec );
+ 32 + +
+ 33 + +232 if( !ec && n < sv.size() )
+ 34 + + {
+ 35 + +1 BOOST_JSON_FAIL( ec, error::extra_data );
+ 36 + + }
+ 37 + +232 }
+ 38 + +
+ 39 + + template<class V>
+ 40 + + void
+ 41 + +66 parse_into(
+ 42 + + V& v,
+ 43 + + string_view sv,
+ 44 + + std::error_code& ec,
+ 45 + + parse_options const& opt )
+ 46 + + {
+ 47 + +66 system::error_code jec;
+ 48 + +66 parse_into(v, sv, jec, opt);
+ 49 + +66 ec = jec;
+ 50 + +66 }
+ 51 + +
+ 52 + + template<class V>
+ 53 + + void
+ 54 + +74 parse_into(
+ 55 + + V& v,
+ 56 + + string_view sv,
+ 57 + + parse_options const& opt )
+ 58 + + {
+ 59 + +74 system::error_code ec;
+ 60 + +74 parse_into(v, sv, ec, opt);
+ 61 + +74 if( ec.failed() )
+ 62 + +1 detail::throw_system_error( ec );
+ 63 + +73 }
+ 64 + +
+ 65 + + template<class V>
+ 66 + + void
+ 67 + +201 parse_into(
+ 68 + + V& v,
+ 69 + + std::istream& is,
+ 70 + + system::error_code& ec,
+ 71 + + parse_options const& opt )
+ 72 + + {
+ 73 + +201 parser_for<V> p( opt, &v );
+ 74 + +
+ 75 + + char read_buffer[BOOST_JSON_STACK_BUFFER_SIZE];
+ 76 + + do
+ 77 + + {
+ 78 + +399 if( is.eof() )
+ 79 + + {
+ 80 + +198 p.write_some(false, nullptr, 0, ec);
+ 81 + +198 break;
+ 82 + + }
+ 83 + +
+ 84 + +201 if( !is )
+ 85 + + {
+ 86 + +1 BOOST_JSON_FAIL( ec, error::input_error );
+ 87 + +1 break;
+ 88 + + }
+ 89 + +
+ 90 + +200 is.read(read_buffer, sizeof(read_buffer));
+ 91 + +200 std::size_t const consumed = static_cast<std::size_t>( is.gcount() );
+ 92 + +
+ 93 + +200 std::size_t const n = p.write_some( true, read_buffer, consumed, ec );
+ 94 + +200 if( !ec.failed() && n < consumed )
+ 95 + + {
+ 96 + +1 BOOST_JSON_FAIL( ec, error::extra_data );
+ 97 + + }
+ 98 + + }
+ 99 + +200 while( !ec.failed() );
+ 100 + +201 }
+ 101 + +
+ 102 + + template<class V>
+ 103 + + void
+ 104 + +66 parse_into(
+ 105 + + V& v,
+ 106 + + std::istream& is,
+ 107 + + std::error_code& ec,
+ 108 + + parse_options const& opt )
+ 109 + + {
+ 110 + +66 system::error_code jec;
+ 111 + +66 parse_into(v, is, jec, opt);
+ 112 + +66 ec = jec;
+ 113 + +66 }
+ 114 + +
+ 115 + + template<class V>
+ 116 + + void
+ 117 + +67 parse_into(
+ 118 + + V& v,
+ 119 + + std::istream& is,
+ 120 + + parse_options const& opt )
+ 121 + + {
+ 122 + +67 system::error_code ec;
+ 123 + +67 parse_into(v, is, ec, opt);
+ 124 + +67 if( ec.failed() )
+ 125 + +1 detail::throw_system_error( ec );
+ 126 + +66 }
+ 127 + +
+ 128 + + } // namespace boost
+ 129 + + } // namespace json
+ 130 + +
+ 131 + + #endif
+ 132 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.parse_into.hpp.f1e9fbffabe35587d223b9d98d9e761c.html b/json/gcovr/index.parse_into.hpp.f1e9fbffabe35587d223b9d98d9e761c.html new file mode 100644 index 00000000..71c6dbf8 --- /dev/null +++ b/json/gcovr/index.parse_into.hpp.f1e9fbffabe35587d223b9d98d9e761c.html @@ -0,0 +1,17902 @@ + + + + + + detail/parse_into.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/parse_into.hpp

+
+ + 100.0% Lines (395/395) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/parse_into.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_DETAIL_PARSE_INTO_HPP
+ 12 + + #define BOOST_JSON_DETAIL_PARSE_INTO_HPP
+ 13 + +
+ 14 + + #include <boost/json/detail/config.hpp>
+ 15 + +
+ 16 + + #include <boost/json/error.hpp>
+ 17 + + #include <boost/json/conversion.hpp>
+ 18 + + #include <boost/describe/enum_from_string.hpp>
+ 19 + +
+ 20 + + #include <vector>
+ 21 + +
+ 22 + + /*
+ 23 + + * This file contains the majority of parse_into functionality, specifically
+ 24 + + * the implementation of dedicated handlers for different generic categories of
+ 25 + + * types.
+ 26 + + *
+ 27 + + * At the core of parse_into is the specialisation basic_parser<
+ 28 + + * detail::into_handler<T> >. detail::into_handler<T> is a handler for
+ 29 + + * basic_parser. It directly handles events on_comment_part and on_comment (by
+ 30 + + * ignoring them), on_document_begin (by enabling the nested dedicated
+ 31 + + * handler), and on_document_end (by disabling the nested handler).
+ 32 + + *
+ 33 + + * Every other event is handled by the nested handler, which has the type
+ 34 + + * get_handler< T, into_handler<T> >. The second parameter is the parent
+ 35 + + * handler (in this case, it's the top handler, into_handler<T>). The type is
+ 36 + + * actually an alias to class template converting_handler, which has a separate
+ 37 + + * specialisation for every conversion category from the list of generic
+ 38 + + * conversion categories (e.g. sequence_conversion_tag, tuple_conversion_tag,
+ 39 + + * etc.) Instantiations of the template store a pointer to the parent handler
+ 40 + + * and a pointer to the value T.
+ 41 + + *
+ 42 + + * The nested handler handles specific parser events by setting error_code to
+ 43 + + * an appropriate value, if it receives an event it isn't supposed to handle
+ 44 + + * (e.g. a number handler getting an on_string event), and also updates the
+ 45 + + * value when appropriate. Note that they never need to handle on_comment_part,
+ 46 + + * on_comment, on_document_begin, and on_document_end events, as those are
+ 47 + + * always handled by the top handler into_handler<T>.
+ 48 + + *
+ 49 + + * When the nested handler receives an event that completes the current value,
+ 50 + + * it is supposed to call its parent's signal_value member function. This is
+ 51 + + * necessary for correct handling of composite types (e.g. sequences).
+ 52 + + *
+ 53 + + * Finally, nested handlers should always call parent's signal_end member
+ 54 + + * function if they don't handle on_array_end themselves. This is necessary
+ 55 + + * to correctly handle nested composites (e.g. sequences inside sequences).
+ 56 + + * signal_end can return false and set error state when the containing parser
+ 57 + + * requires more elements.
+ 58 + + *
+ 59 + + * converting_handler instantiations for composite categories of types have
+ 60 + + * their own nested handlers, to which they themselves delegate events. For
+ 61 + + * complex types you will get a tree of handlers with into_handler<T> as the
+ 62 + + * root and handlers for scalars as leaves.
+ 63 + + *
+ 64 + + * To reiterate, only into_handler has to handle on_comment_part, on_comment,
+ 65 + + * on_document_begin, and on_document_end; only handlers for composites and
+ 66 + + * into_handler has to provide signal_value and signal_end; all handlers
+ 67 + + * except for into_handler have to call their parent's signal_end from
+ 68 + + * their on_array_begin, if they don't handle it themselves; once a handler
+ 69 + + * receives an event that finishes its current value, it should call its
+ 70 + + * parent's signal_value.
+ 71 + + */
+ 72 + +
+ 73 + + namespace boost {
+ 74 + + namespace json {
+ 75 + + namespace detail {
+ 76 + +
+ 77 + + template< class Impl, class T, class Parent >
+ 78 + + class converting_handler;
+ 79 + +
+ 80 + + // get_handler
+ 81 + + template< class V, class P >
+ 82 + + using get_handler = converting_handler< generic_conversion_category<V>, V, P >;
+ 83 + +
+ 84 + + template<error E> class handler_error_base
+ 85 + + {
+ 86 + + public:
+ 87 + +
+ 88 + + handler_error_base() = default;
+ 89 + +
+ 90 + + handler_error_base( handler_error_base const& ) = delete;
+ 91 + + handler_error_base& operator=( handler_error_base const& ) = delete;
+ 92 + +
+ 93 + + public:
+ 94 + +
+ 95 + +2 bool on_object_begin( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 96 + +7 bool on_array_begin( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 97 + + bool on_array_end( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 98 + +1 bool on_string_part( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 99 + +60 bool on_string( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 100 + +2 bool on_number_part( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 101 + +8 bool on_int64( system::error_code& ec, std::int64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 102 + +8 bool on_uint64( system::error_code& ec, std::uint64_t ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 103 + +7 bool on_double( system::error_code& ec, double ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 104 + +2 bool on_bool( system::error_code& ec, bool ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 105 + +4 bool on_null( system::error_code& ec ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 106 + +
+ 107 + + // LCOV_EXCL_START
+ 108 + + // parses that can't handle this would fail at on_object_begin
+ 109 + + bool on_object_end( system::error_code& ) { BOOST_ASSERT( false ); return false; }
+ 110 + + bool on_key_part( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 111 + + bool on_key( system::error_code& ec, string_view ) { BOOST_JSON_FAIL( ec, E ); return false; }
+ 112 + + // LCOV_EXCL_STOP
+ 113 + + };
+ 114 + +
+ 115 + + template< class P, error E >
+ 116 + + class scalar_handler
+ 117 + + : public handler_error_base<E>
+ 118 + + {
+ 119 + + protected:
+ 120 + + P* parent_;
+ 121 + +
+ 122 + + public:
+ 123 + + scalar_handler(scalar_handler const&) = delete;
+ 124 + + scalar_handler& operator=(scalar_handler const&) = delete;
+ 125 + +
+ 126 + +816 scalar_handler(P* p): parent_( p )
+ 127 + +816 {}
+ 128 + +
+ 129 + +180 bool on_array_end( system::error_code& ec )
+ 130 + + {
+ 131 + +180 return parent_->signal_end(ec);
+ 132 + + }
+ 133 + + };
+ 134 + +
+ 135 + + template< class D, class V, class P, error E >
+ 136 + + class composite_handler
+ 137 + + {
+ 138 + + protected:
+ 139 + + using inner_handler_type = get_handler<V, D>;
+ 140 + +
+ 141 + + P* parent_;
+ 142 + + #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 143 + + # pragma GCC diagnostic push
+ 144 + + # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+ 145 + + #endif
+ 146 + + V next_value_ = {};
+ 147 + + inner_handler_type inner_;
+ 148 + + bool inner_active_ = false;
+ 149 + +
+ 150 + + public:
+ 151 + + composite_handler( composite_handler const& ) = delete;
+ 152 + + composite_handler& operator=( composite_handler const& ) = delete;
+ 153 + +
+ 154 + +413 composite_handler( P* p )
+ 155 + +413 : parent_(p), inner_( &next_value_, static_cast<D*>(this) )
+ 156 + +413 {}
+ 157 + + #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 158 + + # pragma GCC diagnostic pop
+ 159 + + #endif
+ 160 + +
+ 161 + +272 bool signal_end(system::error_code& ec)
+ 162 + + {
+ 163 + +272 inner_active_ = false;
+ 164 + +272 return parent_->signal_value(ec);
+ 165 + + }
+ 166 + +
+ 167 + + #define BOOST_JSON_INVOKE_INNER(f) \
+ 168 + + if( !inner_active_ ) { \
+ 169 + + BOOST_JSON_FAIL(ec, E); \
+ 170 + + return false; \
+ 171 + + } \
+ 172 + + else \
+ 173 + + return inner_.f
+ 174 + +
+ 175 + +21 bool on_object_begin( system::error_code& ec )
+ 176 + + {
+ 177 + +21 BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
+ 178 + + }
+ 179 + +
+ 180 + +21 bool on_object_end( system::error_code& ec )
+ 181 + + {
+ 182 + +21 BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
+ 183 + + }
+ 184 + +
+ 185 + +59 bool on_array_begin( system::error_code& ec )
+ 186 + + {
+ 187 + +59 BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
+ 188 + + }
+ 189 + +
+ 190 + + bool on_array_end( system::error_code& ec )
+ 191 + + {
+ 192 + + BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
+ 193 + + }
+ 194 + +
+ 195 + +3 bool on_key_part( system::error_code& ec, string_view sv )
+ 196 + + {
+ 197 + +3 BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
+ 198 + + }
+ 199 + +
+ 200 + +21 bool on_key( system::error_code& ec, string_view sv )
+ 201 + + {
+ 202 + +21 BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
+ 203 + + }
+ 204 + +
+ 205 + +24 bool on_string_part( system::error_code& ec, string_view sv )
+ 206 + + {
+ 207 + +24 BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
+ 208 + + }
+ 209 + +
+ 210 + +50 bool on_string( system::error_code& ec, string_view sv )
+ 211 + + {
+ 212 + +50 BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
+ 213 + + }
+ 214 + +
+ 215 + +229 bool on_number_part( system::error_code& ec )
+ 216 + + {
+ 217 + +229 BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
+ 218 + + }
+ 219 + +
+ 220 + +894 bool on_int64( system::error_code& ec, std::int64_t v )
+ 221 + + {
+ 222 + +894 BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
+ 223 + + }
+ 224 + +
+ 225 + +7 bool on_uint64( system::error_code& ec, std::uint64_t v )
+ 226 + + {
+ 227 + +7 BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
+ 228 + + }
+ 229 + +
+ 230 + +42 bool on_double( system::error_code& ec, double v )
+ 231 + + {
+ 232 + +42 BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
+ 233 + + }
+ 234 + +
+ 235 + +21 bool on_bool( system::error_code& ec, bool v )
+ 236 + + {
+ 237 + +21 BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
+ 238 + + }
+ 239 + +
+ 240 + +14 bool on_null( system::error_code& ec )
+ 241 + + {
+ 242 + +14 BOOST_JSON_INVOKE_INNER( on_null(ec) );
+ 243 + + }
+ 244 + +
+ 245 + + #undef BOOST_JSON_INVOKE_INNER
+ 246 + + };
+ 247 + +
+ 248 + + // integral handler
+ 249 + + template<class V,
+ 250 + + typename std::enable_if<std::is_signed<V>::value, int>::type = 0>
+ 251 + +680 bool integral_in_range( std::int64_t v )
+ 252 + + {
+ 253 + +680 return v >= (std::numeric_limits<V>::min)() && v <= (std::numeric_limits<V>::max)();
+ 254 + + }
+ 255 + +
+ 256 + + template<class V,
+ 257 + + typename std::enable_if<!std::is_signed<V>::value, int>::type = 0>
+ 258 + +35 bool integral_in_range( std::int64_t v )
+ 259 + + {
+ 260 + +35 return v >= 0 && static_cast<std::uint64_t>( v ) <= (std::numeric_limits<V>::max)();
+ 261 + + }
+ 262 + +
+ 263 + + template<class V>
+ 264 + +37 bool integral_in_range( std::uint64_t v )
+ 265 + + {
+ 266 + +37 return v <= static_cast<typename std::make_unsigned<V>::type>( (std::numeric_limits<V>::max)() );
+ 267 + + }
+ 268 + +
+ 269 + + template< class V, class P >
+ 270 + + class converting_handler<integral_conversion_tag, V, P>
+ 271 + + : public scalar_handler<P, error::not_integer>
+ 272 + + {
+ 273 + + private:
+ 274 + + V* value_;
+ 275 + +
+ 276 + + public:
+ 277 + +553 converting_handler( V* v, P* p )
+ 278 + + : converting_handler::scalar_handler(p)
+ 279 + +553 , value_(v)
+ 280 + +553 {}
+ 281 + +
+ 282 + +319 bool on_number_part( system::error_code& )
+ 283 + + {
+ 284 + +319 return true;
+ 285 + + }
+ 286 + +
+ 287 + +715 bool on_int64(system::error_code& ec, std::int64_t v)
+ 288 + + {
+ 289 + +715 if( !integral_in_range<V>( v ) )
+ 290 + + {
+ 291 + +2 BOOST_JSON_FAIL( ec, error::not_exact );
+ 292 + +2 return false;
+ 293 + + }
+ 294 + +
+ 295 + +713 *value_ = static_cast<V>( v );
+ 296 + +713 return this->parent_->signal_value(ec);
+ 297 + + }
+ 298 + +
+ 299 + +37 bool on_uint64(system::error_code& ec, std::uint64_t v)
+ 300 + + {
+ 301 + +37 if( !integral_in_range<V>(v) )
+ 302 + + {
+ 303 + +2 BOOST_JSON_FAIL( ec, error::not_exact );
+ 304 + +2 return false;
+ 305 + + }
+ 306 + +
+ 307 + +35 *value_ = static_cast<V>(v);
+ 308 + +35 return this->parent_->signal_value(ec);
+ 309 + + }
+ 310 + + };
+ 311 + +
+ 312 + + // floating point handler
+ 313 + + template< class V, class P>
+ 314 + + class converting_handler<floating_point_conversion_tag, V, P>
+ 315 + + : public scalar_handler<P, error::not_double>
+ 316 + + {
+ 317 + + private:
+ 318 + + V* value_;
+ 319 + +
+ 320 + + public:
+ 321 + +53 converting_handler( V* v, P* p )
+ 322 + + : converting_handler::scalar_handler(p)
+ 323 + +53 , value_(v)
+ 324 + +53 {}
+ 325 + +
+ 326 + +99 bool on_number_part( system::error_code& )
+ 327 + + {
+ 328 + +99 return true;
+ 329 + + }
+ 330 + +
+ 331 + +1 bool on_int64(system::error_code& ec, std::int64_t v)
+ 332 + + {
+ 333 + +1 *value_ = static_cast<V>(v);
+ 334 + +1 return this->parent_->signal_value(ec);
+ 335 + + }
+ 336 + +
+ 337 + +1 bool on_uint64(system::error_code& ec, std::uint64_t v)
+ 338 + + {
+ 339 + +1 *value_ = static_cast<V>(v);
+ 340 + +1 return this->parent_->signal_value(ec);
+ 341 + + }
+ 342 + +
+ 343 + +63 bool on_double(system::error_code& ec, double v)
+ 344 + + {
+ 345 + +63 *value_ = static_cast<V>(v);
+ 346 + +63 return this->parent_->signal_value(ec);
+ 347 + + }
+ 348 + + };
+ 349 + +
+ 350 + + // string handler
+ 351 + + template< class V, class P >
+ 352 + + class converting_handler<string_like_conversion_tag, V, P>
+ 353 + + : public scalar_handler<P, error::not_string>
+ 354 + + {
+ 355 + + private:
+ 356 + + V* value_;
+ 357 + + bool cleared_ = false;
+ 358 + +
+ 359 + + public:
+ 360 + +95 converting_handler( V* v, P* p )
+ 361 + + : converting_handler::scalar_handler(p)
+ 362 + +95 , value_(v)
+ 363 + +95 {}
+ 364 + +
+ 365 + +21 bool on_string_part( system::error_code&, string_view sv )
+ 366 + + {
+ 367 + +21 if( !cleared_ )
+ 368 + + {
+ 369 + +5 cleared_ = true;
+ 370 + +5 value_->clear();
+ 371 + + }
+ 372 + +
+ 373 + +21 value_->append( sv.begin(), sv.end() );
+ 374 + +21 return true;
+ 375 + + }
+ 376 + +
+ 377 + +100 bool on_string(system::error_code& ec, string_view sv)
+ 378 + + {
+ 379 + +100 if( !cleared_ )
+ 380 + +95 value_->clear();
+ 381 + + else
+ 382 + +5 cleared_ = false;
+ 383 + +
+ 384 + +100 value_->append( sv.begin(), sv.end() );
+ 385 + +100 return this->parent_->signal_value(ec);
+ 386 + + }
+ 387 + + };
+ 388 + +
+ 389 + + // bool handler
+ 390 + + template< class V, class P >
+ 391 + + class converting_handler<bool_conversion_tag, V, P>
+ 392 + + : public scalar_handler<P, error::not_bool>
+ 393 + + {
+ 394 + + private:
+ 395 + + V* value_;
+ 396 + +
+ 397 + + public:
+ 398 + +60 converting_handler( V* v, P* p )
+ 399 + + : converting_handler::scalar_handler(p)
+ 400 + +60 , value_(v)
+ 401 + +60 {}
+ 402 + +
+ 403 + +42 bool on_bool(system::error_code& ec, bool v)
+ 404 + + {
+ 405 + +42 *value_ = v;
+ 406 + +42 return this->parent_->signal_value(ec);
+ 407 + + }
+ 408 + + };
+ 409 + +
+ 410 + + // null handler
+ 411 + + template< class V, class P >
+ 412 + + class converting_handler<null_like_conversion_tag, V, P>
+ 413 + + : public scalar_handler<P, error::not_null>
+ 414 + + {
+ 415 + + private:
+ 416 + + V* value_;
+ 417 + +
+ 418 + + public:
+ 419 + +55 converting_handler( V* v, P* p )
+ 420 + + : converting_handler::scalar_handler(p)
+ 421 + +55 , value_(v)
+ 422 + +55 {}
+ 423 + +
+ 424 + +35 bool on_null(system::error_code& ec)
+ 425 + + {
+ 426 + +35 *value_ = {};
+ 427 + +35 return this->parent_->signal_value(ec);
+ 428 + + }
+ 429 + + };
+ 430 + +
+ 431 + + // described enum handler
+ 432 + + template< class V, class P >
+ 433 + + class converting_handler<described_enum_conversion_tag, V, P>
+ 434 + + : public scalar_handler<P, error::not_string>
+ 435 + + {
+ 436 + + #ifndef BOOST_DESCRIBE_CXX14
+ 437 + +
+ 438 + + static_assert(
+ 439 + + sizeof(V) == 0, "Enum support for parse_into requires C++14" );
+ 440 + +
+ 441 + + #else
+ 442 + +
+ 443 + + private:
+ 444 + + V* value_;
+ 445 + + std::string name_;
+ 446 + +
+ 447 + + public:
+ 448 + + converting_handler( V* v, P* p )
+ 449 + + : converting_handler::scalar_handler(p)
+ 450 + + , value_(v)
+ 451 + + {}
+ 452 + +
+ 453 + + bool on_string_part( system::error_code&, string_view sv )
+ 454 + + {
+ 455 + + name_.append( sv.begin(), sv.end() );
+ 456 + + return true;
+ 457 + + }
+ 458 + +
+ 459 + + bool on_string(system::error_code& ec, string_view sv)
+ 460 + + {
+ 461 + + string_view name = sv;
+ 462 + + if( !name_.empty() )
+ 463 + + {
+ 464 + + name_.append( sv.begin(), sv.end() );
+ 465 + + name = name_;
+ 466 + + }
+ 467 + +
+ 468 + + if( !describe::enum_from_string(name, *value_) )
+ 469 + + {
+ 470 + + BOOST_JSON_FAIL(ec, error::unknown_name);
+ 471 + + return false;
+ 472 + + }
+ 473 + +
+ 474 + + return this->parent_->signal_value(ec);
+ 475 + + }
+ 476 + +
+ 477 + + #endif // BOOST_DESCRIBE_CXX14
+ 478 + + };
+ 479 + +
+ 480 + + template< class V, class P >
+ 481 + + class converting_handler<no_conversion_tag, V, P>
+ 482 + + {
+ 483 + + static_assert( sizeof(V) == 0, "This type is not supported" );
+ 484 + + };
+ 485 + +
+ 486 + + // sequence handler
+ 487 + + template< class It >
+ 488 + +128 bool cannot_insert(It i, It e)
+ 489 + + {
+ 490 + +128 return i == e;
+ 491 + + }
+ 492 + +
+ 493 + + template< class It1, class It2 >
+ 494 + +507 std::false_type cannot_insert(It1, It2)
+ 495 + + {
+ 496 + +507 return {};
+ 497 + + }
+ 498 + +
+ 499 + + template< class It >
+ 500 + +30 bool needs_more_elements(It i, It e)
+ 501 + + {
+ 502 + +30 return i != e;
+ 503 + + }
+ 504 + +
+ 505 + + template< class It1, class It2 >
+ 506 + +244 std::false_type needs_more_elements(It1, It2)
+ 507 + + {
+ 508 + +244 return {};
+ 509 + + }
+ 510 + +
+ 511 + + template<class T>
+ 512 + + void
+ 513 + +32 clear_container(
+ 514 + + T&,
+ 515 + + mp11::mp_int<2>)
+ 516 + + {
+ 517 + +32 }
+ 518 + +
+ 519 + + template<class T>
+ 520 + + void
+ 521 + +260 clear_container(
+ 522 + + T& target,
+ 523 + + mp11::mp_int<1>)
+ 524 + + {
+ 525 + +260 target.clear();
+ 526 + +260 }
+ 527 + +
+ 528 + + template<class T>
+ 529 + + void
+ 530 + +149 clear_container(
+ 531 + + T& target,
+ 532 + + mp11::mp_int<0>)
+ 533 + + {
+ 534 + +149 target.clear();
+ 535 + +149 }
+ 536 + +
+ 537 + + template< class V, class P >
+ 538 + + class converting_handler<sequence_conversion_tag, V, P>
+ 539 + + : public composite_handler<
+ 540 + + converting_handler<sequence_conversion_tag, V, P>,
+ 541 + + detail::value_type<V>,
+ 542 + + P,
+ 543 + + error::not_array>
+ 544 + + {
+ 545 + + private:
+ 546 + + V* value_;
+ 547 + +
+ 548 + + using Inserter = decltype(
+ 549 + + detail::inserter(*value_, inserter_implementation<V>()) );
+ 550 + + Inserter inserter;
+ 551 + +
+ 552 + + public:
+ 553 + +276 converting_handler( V* v, P* p )
+ 554 + + : converting_handler::composite_handler(p)
+ 555 + +276 , value_(v)
+ 556 + +276 , inserter( detail::inserter(*value_, inserter_implementation<V>()) )
+ 557 + +276 {}
+ 558 + +
+ 559 + +635 bool signal_value(system::error_code& ec)
+ 560 + + {
+ 561 + +635 if(cannot_insert( inserter, value_->end() ))
+ 562 + + {
+ 563 + +2 BOOST_JSON_FAIL( ec, error::size_mismatch );
+ 564 + +2 return false;
+ 565 + + }
+ 566 + +
+ 567 + +633 *inserter++ = std::move(this->next_value_);
+ 568 + + #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 569 + + # pragma GCC diagnostic push
+ 570 + + # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+ 571 + + #endif
+ 572 + +633 this->next_value_ = {};
+ 573 + + #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 574 + + # pragma GCC diagnostic pop
+ 575 + + #endif
+ 576 + +633 return true;
+ 577 + + }
+ 578 + +
+ 579 + +274 bool signal_end(system::error_code& ec)
+ 580 + + {
+ 581 + +274 if(needs_more_elements( inserter, value_->end() ))
+ 582 + + {
+ 583 + +2 BOOST_JSON_FAIL( ec, error::size_mismatch );
+ 584 + +2 return false;
+ 585 + + }
+ 586 + +
+ 587 + +272 inserter = detail::inserter(*value_, inserter_implementation<V>());
+ 588 + +
+ 589 + +272 return converting_handler::composite_handler::signal_end(ec);
+ 590 + + }
+ 591 + +
+ 592 + +474 bool on_array_begin( system::error_code& ec )
+ 593 + + {
+ 594 + +474 if( this->inner_active_ )
+ 595 + +182 return this->inner_.on_array_begin( ec );
+ 596 + +
+ 597 + +292 this->inner_active_ = true;
+ 598 + +292 clear_container( *value_, inserter_implementation<V>() );
+ 599 + +292 return true;
+ 600 + + }
+ 601 + +
+ 602 + +498 bool on_array_end( system::error_code& ec )
+ 603 + + {
+ 604 + +498 if( this->inner_active_ )
+ 605 + +456 return this->inner_.on_array_end( ec );
+ 606 + +
+ 607 + +42 return this->parent_->signal_end(ec);
+ 608 + + }
+ 609 + + };
+ 610 + +
+ 611 + + // map handler
+ 612 + + template< class V, class P >
+ 613 + + class converting_handler<map_like_conversion_tag, V, P>
+ 614 + + : public composite_handler<
+ 615 + + converting_handler<map_like_conversion_tag, V, P>,
+ 616 + + detail::mapped_type<V>,
+ 617 + + P,
+ 618 + + error::not_object>
+ 619 + + {
+ 620 + + private:
+ 621 + + V* value_;
+ 622 + + std::string key_;
+ 623 + +
+ 624 + + public:
+ 625 + +137 converting_handler( V* v, P* p )
+ 626 + +137 : converting_handler::composite_handler(p), value_(v)
+ 627 + +137 {}
+ 628 + +
+ 629 + +135 bool signal_value(system::error_code&)
+ 630 + + {
+ 631 + +135 value_->emplace( std::move(key_), std::move(this->next_value_) );
+ 632 + +
+ 633 + +135 key_ = {};
+ 634 + +135 this->next_value_ = {};
+ 635 + +
+ 636 + +135 this->inner_active_ = false;
+ 637 + +
+ 638 + +135 return true;
+ 639 + + }
+ 640 + +
+ 641 + +165 bool on_object_begin( system::error_code& ec )
+ 642 + + {
+ 643 + +165 if( this->inner_active_ )
+ 644 + +16 return this->inner_.on_object_begin(ec);
+ 645 + +
+ 646 + +149 clear_container( *value_, inserter_implementation<V>() );
+ 647 + +149 return true;
+ 648 + + }
+ 649 + +
+ 650 + +154 bool on_object_end(system::error_code& ec)
+ 651 + + {
+ 652 + +154 if( this->inner_active_ )
+ 653 + +16 return this->inner_.on_object_end(ec);
+ 654 + +
+ 655 + +138 return this->parent_->signal_value(ec);
+ 656 + + }
+ 657 + +
+ 658 + +60 bool on_array_end( system::error_code& ec )
+ 659 + + {
+ 660 + +60 if( this->inner_active_ )
+ 661 + +53 return this->inner_.on_array_end(ec);
+ 662 + +
+ 663 + +7 return this->parent_->signal_end(ec);
+ 664 + + }
+ 665 + +
+ 666 + +45 bool on_key_part( system::error_code& ec, string_view sv )
+ 667 + + {
+ 668 + +45 if( this->inner_active_ )
+ 669 + +2 return this->inner_.on_key_part(ec, sv);
+ 670 + +
+ 671 + +43 key_.append( sv.data(), sv.size() );
+ 672 + +43 return true;
+ 673 + + }
+ 674 + +
+ 675 + +160 bool on_key( system::error_code& ec, string_view sv )
+ 676 + + {
+ 677 + +160 if( this->inner_active_ )
+ 678 + +14 return this->inner_.on_key(ec, sv);
+ 679 + +
+ 680 + +146 key_.append( sv.data(), sv.size() );
+ 681 + +
+ 682 + +146 this->inner_active_ = true;
+ 683 + +146 return true;
+ 684 + + }
+ 685 + + };
+ 686 + +
+ 687 + + // tuple handler
+ 688 + + template<std::size_t I, class T>
+ 689 + + struct handler_tuple_element
+ 690 + + {
+ 691 + + template< class... Args >
+ 692 + +286 handler_tuple_element( Args&& ... args )
+ 693 + +286 : t_( static_cast<Args&&>(args)... )
+ 694 + +286 {}
+ 695 + +
+ 696 + + T t_;
+ 697 + + };
+ 698 + +
+ 699 + + template<std::size_t I, class T>
+ 700 + + T&
+ 701 + +516 get( handler_tuple_element<I, T>& e )
+ 702 + + {
+ 703 + +516 return e.t_;
+ 704 + + }
+ 705 + +
+ 706 + + template<
+ 707 + + class P,
+ 708 + + class LV,
+ 709 + + class S = mp11::make_index_sequence<mp11::mp_size<LV>::value> >
+ 710 + + struct handler_tuple;
+ 711 + +
+ 712 + + template< class P, template<class...> class L, class... V, std::size_t... I >
+ 713 + + struct handler_tuple< P, L<V...>, mp11::index_sequence<I...> >
+ 714 + + : handler_tuple_element<I, V>
+ 715 + + ...
+ 716 + + {
+ 717 + + handler_tuple( handler_tuple const& ) = delete;
+ 718 + + handler_tuple& operator=( handler_tuple const& ) = delete;
+ 719 + +
+ 720 + + template< class Access, class T >
+ 721 + +129 handler_tuple( Access access, T* pv, P* pp )
+ 722 + + : handler_tuple_element<I, V>(
+ 723 + +6 access( pv, mp11::mp_size_t<I>() ),
+ 724 + + pp )
+ 725 + +129 ...
+ 726 + +129 {}
+ 727 + + };
+ 728 + +
+ 729 + + #if defined(BOOST_MSVC) && BOOST_MSVC < 1910
+ 730 + +
+ 731 + + template< class T >
+ 732 + + struct tuple_element_list_impl
+ 733 + + {
+ 734 + + template< class I >
+ 735 + + using tuple_element_helper = tuple_element_t<I::value, T>;
+ 736 + +
+ 737 + + using type = mp11::mp_transform<
+ 738 + + tuple_element_helper,
+ 739 + + mp11::mp_iota< std::tuple_size<T> > >;
+ 740 + + };
+ 741 + + template< class T >
+ 742 + + using tuple_element_list = typename tuple_element_list_impl<T>::type;
+ 743 + +
+ 744 + + #else
+ 745 + +
+ 746 + + template< class I, class T >
+ 747 + + using tuple_element_helper = tuple_element_t<I::value, T>;
+ 748 + + template< class T >
+ 749 + + using tuple_element_list = mp11::mp_transform_q<
+ 750 + + mp11::mp_bind_back< tuple_element_helper, T>,
+ 751 + + mp11::mp_iota< std::tuple_size<T> > >;
+ 752 + +
+ 753 + + #endif
+ 754 + +
+ 755 + + template< class Op, class... Args>
+ 756 + + struct handler_op_invoker
+ 757 + + {
+ 758 + + public:
+ 759 + + std::tuple<Args&...> args;
+ 760 + +
+ 761 + + template< class Handler >
+ 762 + + bool
+ 763 + +466 operator()( Handler& handler ) const
+ 764 + + {
+ 765 + +466 return (*this)( handler, mp11::index_sequence_for<Args...>() );
+ 766 + + }
+ 767 + +
+ 768 + + private:
+ 769 + + template< class Handler, std::size_t... I >
+ 770 + + bool
+ 771 + +466 operator()( Handler& handler, mp11::index_sequence<I...> ) const
+ 772 + + {
+ 773 + +466 return Op()( handler, std::get<I>(args)... );
+ 774 + + }
+ 775 + + };
+ 776 + +
+ 777 + + template< class Handlers, class F >
+ 778 + + struct tuple_handler_op_invoker
+ 779 + + {
+ 780 + + Handlers& handlers;
+ 781 + + F fn;
+ 782 + +
+ 783 + + template< class I >
+ 784 + + bool
+ 785 + +466 operator()( I ) const
+ 786 + + {
+ 787 + +466 return fn( get<I::value>(handlers) );
+ 788 + + }
+ 789 + + };
+ 790 + +
+ 791 + + struct tuple_accessor
+ 792 + + {
+ 793 + + template< class T, class I >
+ 794 + +286 auto operator()( T* t, I ) const -> tuple_element_t<I::value, T>*
+ 795 + + {
+ 796 + + using std::get;
+ 797 + +286 return &get<I::value>(*t);
+ 798 + + }
+ 799 + + };
+ 800 + +
+ 801 + + template< class T, class P >
+ 802 + + class converting_handler<tuple_conversion_tag, T, P>
+ 803 + + {
+ 804 + +
+ 805 + + private:
+ 806 + + using ElementTypes = tuple_element_list<T>;
+ 807 + +
+ 808 + + template<class V>
+ 809 + + using ElementHandler = get_handler<V, converting_handler>;
+ 810 + + using InnerHandlers = mp11::mp_transform<ElementHandler, ElementTypes>;
+ 811 + + using HandlerTuple = handler_tuple<converting_handler, InnerHandlers>;
+ 812 + +
+ 813 + + T* value_;
+ 814 + + P* parent_;
+ 815 + +
+ 816 + + HandlerTuple handlers_;
+ 817 + + int inner_active_ = -1;
+ 818 + +
+ 819 + + public:
+ 820 + + converting_handler( converting_handler const& ) = delete;
+ 821 + + converting_handler& operator=( converting_handler const& ) = delete;
+ 822 + +
+ 823 + +129 converting_handler( T* v, P* p )
+ 824 + +129 : value_(v) , parent_(p) , handlers_(tuple_accessor(), v, this)
+ 825 + +129 {}
+ 826 + +
+ 827 + +283 bool signal_value(system::error_code&)
+ 828 + + {
+ 829 + +283 ++inner_active_;
+ 830 + +283 return true;
+ 831 + + }
+ 832 + +
+ 833 + +123 bool signal_end(system::error_code& ec)
+ 834 + + {
+ 835 + +123 constexpr int N = std::tuple_size<T>::value;
+ 836 + +123 if( inner_active_ < N )
+ 837 + + {
+ 838 + +4 BOOST_JSON_FAIL( ec, error::size_mismatch );
+ 839 + +4 return false;
+ 840 + + }
+ 841 + +
+ 842 + +119 inner_active_ = -1;
+ 843 + +119 return parent_->signal_value(ec);
+ 844 + + }
+ 845 + +
+ 846 + + #define BOOST_JSON_HANDLE_EVENT(fn) \
+ 847 + + struct do_ ## fn \
+ 848 + + { \
+ 849 + + template< class H, class... Args > \
+ 850 + + bool operator()( H& h, Args& ... args ) const \
+ 851 + + { \
+ 852 + + return h. fn (args...); \
+ 853 + + } \
+ 854 + + }; \
+ 855 + + \
+ 856 + + template< class... Args > \
+ 857 + + bool fn( system::error_code& ec, Args&& ... args ) \
+ 858 + + { \
+ 859 + + if( inner_active_ < 0 ) \
+ 860 + + { \
+ 861 + + BOOST_JSON_FAIL( ec, error::not_array ); \
+ 862 + + return false; \
+ 863 + + } \
+ 864 + + constexpr int N = std::tuple_size<T>::value; \
+ 865 + + if( inner_active_ >= N ) \
+ 866 + + { \
+ 867 + + BOOST_JSON_FAIL( ec, error::size_mismatch ); \
+ 868 + + return false; \
+ 869 + + } \
+ 870 + + using F = handler_op_invoker< do_ ## fn, system::error_code, Args...>; \
+ 871 + + using H = decltype(handlers_); \
+ 872 + + return mp11::mp_with_index<N>( \
+ 873 + + inner_active_, \
+ 874 + + tuple_handler_op_invoker<H, F>{ \
+ 875 + + handlers_, \
+ 876 + + F{ std::forward_as_tuple(ec, args...) } } ); \
+ 877 + + }
+ 878 + +
+ 879 + +56 BOOST_JSON_HANDLE_EVENT( on_object_begin )
+ 880 + +42 BOOST_JSON_HANDLE_EVENT( on_object_end )
+ 881 + +
+ 882 + + struct do_on_array_begin
+ 883 + + {
+ 884 + + HandlerTuple& handlers;
+ 885 + + system::error_code& ec;
+ 886 + +
+ 887 + + template< class I >
+ 888 + +23 bool operator()( I ) const
+ 889 + + {
+ 890 + +23 return get<I::value>(handlers).on_array_begin(ec);
+ 891 + + }
+ 892 + + };
+ 893 + +159 bool on_array_begin( system::error_code& ec )
+ 894 + + {
+ 895 + +159 if( inner_active_ < 0 )
+ 896 + + {
+ 897 + +134 inner_active_ = 0;
+ 898 + +134 return true;
+ 899 + + }
+ 900 + +
+ 901 + +25 constexpr int N = std::tuple_size<T>::value;
+ 902 + +
+ 903 + +25 if( inner_active_ >= N )
+ 904 + + {
+ 905 + +2 BOOST_JSON_FAIL( ec, error::size_mismatch );
+ 906 + +2 return false;
+ 907 + + }
+ 908 + +
+ 909 + +23 return mp11::mp_with_index<N>(
+ 910 + +23 inner_active_, do_on_array_begin{handlers_, ec} );
+ 911 + + }
+ 912 + +
+ 913 + + struct do_on_array_end
+ 914 + + {
+ 915 + + HandlerTuple& handlers;
+ 916 + + system::error_code& ec;
+ 917 + +
+ 918 + + template< class I >
+ 919 + +27 bool operator()( I ) const
+ 920 + + {
+ 921 + +27 return get<I::value>(handlers).on_array_end(ec);
+ 922 + + }
+ 923 + + };
+ 924 + +195 bool on_array_end( system::error_code& ec )
+ 925 + + {
+ 926 + +195 if( inner_active_ < 0 )
+ 927 + +49 return parent_->signal_end(ec);
+ 928 + +
+ 929 + +146 constexpr int N = std::tuple_size<T>::value;
+ 930 + +
+ 931 + +146 if( inner_active_ >= N )
+ 932 + +119 return signal_end(ec);
+ 933 + +
+ 934 + +27 return mp11::mp_with_index<N>(
+ 935 + +27 inner_active_, do_on_array_end{handlers_, ec} );
+ 936 + + }
+ 937 + +
+ 938 + +6 BOOST_JSON_HANDLE_EVENT( on_key_part )
+ 939 + +56 BOOST_JSON_HANDLE_EVENT( on_key )
+ 940 + +10 BOOST_JSON_HANDLE_EVENT( on_string_part )
+ 941 + +56 BOOST_JSON_HANDLE_EVENT( on_string )
+ 942 + +152 BOOST_JSON_HANDLE_EVENT( on_number_part )
+ 943 + +432 BOOST_JSON_HANDLE_EVENT( on_int64 )
+ 944 + +14 BOOST_JSON_HANDLE_EVENT( on_uint64 )
+ 945 + +70 BOOST_JSON_HANDLE_EVENT( on_double )
+ 946 + +28 BOOST_JSON_HANDLE_EVENT( on_bool )
+ 947 + +14 BOOST_JSON_HANDLE_EVENT( on_null )
+ 948 + +
+ 949 + + #undef BOOST_JSON_HANDLE_EVENT
+ 950 + + };
+ 951 + +
+ 952 + + // described struct handler
+ 953 + + #if defined(BOOST_MSVC) && BOOST_MSVC < 1910
+ 954 + +
+ 955 + + template< class T >
+ 956 + + struct struct_element_list_impl
+ 957 + + {
+ 958 + + template< class D >
+ 959 + + using helper = described_member_t<T, D>;
+ 960 + +
+ 961 + + using type = mp11::mp_transform< helper, described_members<T> >;
+ 962 + + };
+ 963 + + template< class T >
+ 964 + + using struct_element_list = typename struct_element_list_impl<T>::type;
+ 965 + +
+ 966 + + #else
+ 967 + +
+ 968 + + template< class T >
+ 969 + + using struct_element_list = mp11::mp_transform_q<
+ 970 + + mp11::mp_bind_front< described_member_t, T >, described_members<T> >;
+ 971 + +
+ 972 + + #endif
+ 973 + +
+ 974 + + struct struct_accessor
+ 975 + + {
+ 976 + + template< class T >
+ 977 + + auto operator()( T*, mp11::mp_size< described_members<T> > ) const
+ 978 + + -> void*
+ 979 + + {
+ 980 + + return nullptr;
+ 981 + + }
+ 982 + +
+ 983 + + template< class T, class I >
+ 984 + + auto operator()( T* t, I ) const
+ 985 + + -> described_member_t<T, mp11::mp_at< described_members<T>, I> >*
+ 986 + + {
+ 987 + + using Ds = described_members<T>;
+ 988 + + using D = mp11::mp_at<Ds, I>;
+ 989 + + return &(t->*D::pointer);
+ 990 + + }
+ 991 + + };
+ 992 + +
+ 993 + + struct struct_key_searcher
+ 994 + + {
+ 995 + + string_view key;
+ 996 + + int& found;
+ 997 + + int index = 0;
+ 998 + +
+ 999 + + struct_key_searcher(string_view key, int& found) noexcept
+ 1000 + + : key(key), found(found)
+ 1001 + + {}
+ 1002 + +
+ 1003 + + template< class D >
+ 1004 + + void
+ 1005 + + operator()( D )
+ 1006 + + {
+ 1007 + + if( key == D::name )
+ 1008 + + found = index;
+ 1009 + + ++index;
+ 1010 + + }
+ 1011 + + };
+ 1012 + +
+ 1013 + + template<class P>
+ 1014 + + struct ignoring_handler
+ 1015 + + {
+ 1016 + + P* parent_;
+ 1017 + + std::size_t array_depth_ = 0;
+ 1018 + + std::size_t object_depth_ = 0;
+ 1019 + +
+ 1020 + + ignoring_handler(ignoring_handler const&) = delete;
+ 1021 + + ignoring_handler& operator=(ignoring_handler const&) = delete;
+ 1022 + +
+ 1023 + + ignoring_handler(void*, P* p) noexcept
+ 1024 + + : parent_(p)
+ 1025 + + {}
+ 1026 + +
+ 1027 + + bool on_object_begin(system::error_code&)
+ 1028 + + {
+ 1029 + + ++object_depth_;
+ 1030 + + return true;
+ 1031 + + }
+ 1032 + +
+ 1033 + + bool on_object_end(system::error_code& ec)
+ 1034 + + {
+ 1035 + + BOOST_ASSERT( object_depth_ > 0 );
+ 1036 + + --object_depth_;
+ 1037 + +
+ 1038 + + if( (array_depth_ + object_depth_) == 0 )
+ 1039 + + return parent_->signal_value(ec);
+ 1040 + + return true;
+ 1041 + + }
+ 1042 + +
+ 1043 + + bool on_array_begin(system::error_code&)
+ 1044 + + {
+ 1045 + + ++array_depth_;
+ 1046 + + return true;
+ 1047 + + }
+ 1048 + +
+ 1049 + + bool on_array_end(system::error_code& ec)
+ 1050 + + {
+ 1051 + + BOOST_ASSERT( array_depth_ > 0 );
+ 1052 + + --array_depth_;
+ 1053 + +
+ 1054 + + if( (array_depth_ + object_depth_) == 0 )
+ 1055 + + return parent_->signal_value(ec);
+ 1056 + + return true;
+ 1057 + + }
+ 1058 + +
+ 1059 + + bool on_key_part(system::error_code&, string_view)
+ 1060 + + {
+ 1061 + + return true;
+ 1062 + + }
+ 1063 + +
+ 1064 + + bool on_key(system::error_code&, string_view)
+ 1065 + + {
+ 1066 + + return true;
+ 1067 + + }
+ 1068 + +
+ 1069 + + bool on_string_part(system::error_code&, string_view)
+ 1070 + + {
+ 1071 + + return true;
+ 1072 + + }
+ 1073 + +
+ 1074 + + bool on_string(system::error_code& ec, string_view)
+ 1075 + + {
+ 1076 + + if( (array_depth_ + object_depth_) == 0 )
+ 1077 + + return parent_->signal_value(ec);
+ 1078 + + return true;
+ 1079 + + }
+ 1080 + +
+ 1081 + + bool on_number_part(system::error_code&)
+ 1082 + + {
+ 1083 + + return true;
+ 1084 + + }
+ 1085 + +
+ 1086 + + bool on_int64(system::error_code& ec, std::int64_t)
+ 1087 + + {
+ 1088 + + if( (array_depth_ + object_depth_) == 0 )
+ 1089 + + return parent_->signal_value(ec);
+ 1090 + + return true;
+ 1091 + + }
+ 1092 + +
+ 1093 + + bool on_uint64(system::error_code& ec, std::uint64_t)
+ 1094 + + {
+ 1095 + + if( (array_depth_ + object_depth_) == 0 )
+ 1096 + + return parent_->signal_value(ec);
+ 1097 + + return true;
+ 1098 + + }
+ 1099 + +
+ 1100 + + bool on_double(system::error_code& ec, double)
+ 1101 + + {
+ 1102 + + if( (array_depth_ + object_depth_) == 0 )
+ 1103 + + return parent_->signal_value(ec);
+ 1104 + + return true;
+ 1105 + + }
+ 1106 + +
+ 1107 + + bool on_bool(system::error_code& ec, bool)
+ 1108 + + {
+ 1109 + + if( (array_depth_ + object_depth_) == 0 )
+ 1110 + + return parent_->signal_value(ec);
+ 1111 + + return true;
+ 1112 + + }
+ 1113 + +
+ 1114 + + bool on_null(system::error_code& ec)
+ 1115 + + {
+ 1116 + + if( (array_depth_ + object_depth_) == 0 )
+ 1117 + + return parent_->signal_value(ec);
+ 1118 + + return true;
+ 1119 + + }
+ 1120 + + };
+ 1121 + +
+ 1122 + + template<class V, class P>
+ 1123 + + class converting_handler<described_class_conversion_tag, V, P>
+ 1124 + + {
+ 1125 + + #if !defined(BOOST_DESCRIBE_CXX14)
+ 1126 + +
+ 1127 + + static_assert(
+ 1128 + + sizeof(V) == 0, "Struct support for parse_into requires C++14" );
+ 1129 + +
+ 1130 + + #else
+ 1131 + +
+ 1132 + + private:
+ 1133 + + static_assert(
+ 1134 + + uniquely_named_members<V>::value,
+ 1135 + + "The type has several described members with the same name.");
+ 1136 + +
+ 1137 + + using Dm = described_members<V>;
+ 1138 + + using Dt = struct_element_list<V>;
+ 1139 + +
+ 1140 + + template<class T>
+ 1141 + + using MemberHandler = get_handler<T, converting_handler>;
+ 1142 + + using InnerHandlers = mp11::mp_push_back<
+ 1143 + + mp11::mp_transform<MemberHandler, Dt>,
+ 1144 + + ignoring_handler<converting_handler> >;
+ 1145 + + using InnerCount = mp11::mp_size<InnerHandlers>;
+ 1146 + +
+ 1147 + + V* value_;
+ 1148 + + P* parent_;
+ 1149 + +
+ 1150 + + std::string key_;
+ 1151 + +
+ 1152 + + handler_tuple<converting_handler, InnerHandlers> handlers_;
+ 1153 + + int inner_active_ = -1;
+ 1154 + + std::size_t activated_ = 0;
+ 1155 + +
+ 1156 + + public:
+ 1157 + + converting_handler( converting_handler const& ) = delete;
+ 1158 + + converting_handler& operator=( converting_handler const& ) = delete;
+ 1159 + +
+ 1160 + + converting_handler( V* v, P* p )
+ 1161 + + : value_(v), parent_(p), handlers_(struct_accessor(), v, this)
+ 1162 + + {}
+ 1163 + +
+ 1164 + + struct is_required_checker
+ 1165 + + {
+ 1166 + + bool operator()( mp11::mp_size<Dt> ) const noexcept
+ 1167 + + {
+ 1168 + + return false;
+ 1169 + + }
+ 1170 + +
+ 1171 + + template< class I >
+ 1172 + + auto operator()( I ) const noexcept
+ 1173 + + {
+ 1174 + + using T = mp11::mp_at<Dt, I>;
+ 1175 + + return !is_optional_like<T>::value;
+ 1176 + + }
+ 1177 + + };
+ 1178 + +
+ 1179 + + bool signal_value(system::error_code&)
+ 1180 + + {
+ 1181 + + BOOST_ASSERT( inner_active_ >= 0 );
+ 1182 + + bool required_member = mp11::mp_with_index<InnerCount>(
+ 1183 + + inner_active_,
+ 1184 + + is_required_checker{});
+ 1185 + + if( required_member )
+ 1186 + + ++activated_;
+ 1187 + +
+ 1188 + + key_ = {};
+ 1189 + + inner_active_ = -1;
+ 1190 + + return true;
+ 1191 + + }
+ 1192 + +
+ 1193 + + bool signal_end(system::error_code& ec)
+ 1194 + + {
+ 1195 + + key_ = {};
+ 1196 + + inner_active_ = -1;
+ 1197 + + return parent_->signal_value(ec);
+ 1198 + + }
+ 1199 + +
+ 1200 + + #define BOOST_JSON_INVOKE_INNER(fn) \
+ 1201 + + if( inner_active_ < 0 ) \
+ 1202 + + { \
+ 1203 + + BOOST_JSON_FAIL( ec, error::not_object ); \
+ 1204 + + return false; \
+ 1205 + + } \
+ 1206 + + auto f = [&](auto& handler) { return handler.fn ; }; \
+ 1207 + + using F = decltype(f); \
+ 1208 + + using H = decltype(handlers_); \
+ 1209 + + return mp11::mp_with_index<InnerCount>( \
+ 1210 + + inner_active_, \
+ 1211 + + tuple_handler_op_invoker<H, F>{handlers_, f} );
+ 1212 + +
+ 1213 + + bool on_object_begin( system::error_code& ec )
+ 1214 + + {
+ 1215 + + if( inner_active_ < 0 )
+ 1216 + + return true;
+ 1217 + +
+ 1218 + + BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
+ 1219 + + }
+ 1220 + +
+ 1221 + + bool on_object_end( system::error_code& ec )
+ 1222 + + {
+ 1223 + + if( inner_active_ < 0 )
+ 1224 + + {
+ 1225 + + using C = mp11::mp_count_if<Dt, is_optional_like>;
+ 1226 + + constexpr int N = mp11::mp_size<Dt>::value - C::value;
+ 1227 + + if( activated_ < N )
+ 1228 + + {
+ 1229 + + BOOST_JSON_FAIL( ec, error::size_mismatch );
+ 1230 + + return false;
+ 1231 + + }
+ 1232 + +
+ 1233 + + return parent_->signal_value(ec);
+ 1234 + + }
+ 1235 + +
+ 1236 + + BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
+ 1237 + + }
+ 1238 + +
+ 1239 + + bool on_array_begin( system::error_code& ec )
+ 1240 + + {
+ 1241 + + BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
+ 1242 + + }
+ 1243 + +
+ 1244 + + bool on_array_end( system::error_code& ec )
+ 1245 + + {
+ 1246 + + if( inner_active_ < 0 )
+ 1247 + + return parent_->signal_end(ec);
+ 1248 + +
+ 1249 + + BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
+ 1250 + + }
+ 1251 + +
+ 1252 + + bool on_key_part( system::error_code& ec, string_view sv )
+ 1253 + + {
+ 1254 + + if( inner_active_ < 0 )
+ 1255 + + {
+ 1256 + + key_.append( sv.data(), sv.size() );
+ 1257 + + return true;
+ 1258 + + }
+ 1259 + +
+ 1260 + + BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
+ 1261 + + }
+ 1262 + +
+ 1263 + + bool on_key( system::error_code& ec, string_view sv )
+ 1264 + + {
+ 1265 + + if( inner_active_ >= 0 )
+ 1266 + + {
+ 1267 + + BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
+ 1268 + + }
+ 1269 + +
+ 1270 + + string_view key = sv;
+ 1271 + + if( !key_.empty() )
+ 1272 + + {
+ 1273 + + key_.append( sv.data(), sv.size() );
+ 1274 + + key = key_;
+ 1275 + + }
+ 1276 + +
+ 1277 + + inner_active_ = InnerCount::value - 1;
+ 1278 + + mp11::mp_for_each<Dm>( struct_key_searcher(key, inner_active_) );
+ 1279 + + return true;
+ 1280 + + }
+ 1281 + +
+ 1282 + + bool on_string_part( system::error_code& ec, string_view sv )
+ 1283 + + {
+ 1284 + + BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
+ 1285 + + }
+ 1286 + +
+ 1287 + + bool on_string( system::error_code& ec, string_view sv )
+ 1288 + + {
+ 1289 + + BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
+ 1290 + + }
+ 1291 + +
+ 1292 + + bool on_number_part( system::error_code& ec )
+ 1293 + + {
+ 1294 + + BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
+ 1295 + + }
+ 1296 + +
+ 1297 + + bool on_int64( system::error_code& ec, std::int64_t v )
+ 1298 + + {
+ 1299 + + BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
+ 1300 + + }
+ 1301 + +
+ 1302 + + bool on_uint64( system::error_code& ec, std::uint64_t v )
+ 1303 + + {
+ 1304 + + BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
+ 1305 + + }
+ 1306 + +
+ 1307 + + bool on_double( system::error_code& ec, double v )
+ 1308 + + {
+ 1309 + + BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
+ 1310 + + }
+ 1311 + +
+ 1312 + + bool on_bool( system::error_code& ec, bool v )
+ 1313 + + {
+ 1314 + + BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
+ 1315 + + }
+ 1316 + +
+ 1317 + + bool on_null( system::error_code& ec )
+ 1318 + + {
+ 1319 + + BOOST_JSON_INVOKE_INNER( on_null(ec) );
+ 1320 + + }
+ 1321 + +
+ 1322 + + #undef BOOST_JSON_INVOKE_INNER
+ 1323 + +
+ 1324 + + #endif
+ 1325 + + };
+ 1326 + +
+ 1327 + + // variant handler
+ 1328 + + struct object_begin_handler_event
+ 1329 + + { };
+ 1330 + +
+ 1331 + + struct object_end_handler_event
+ 1332 + + { };
+ 1333 + +
+ 1334 + + struct array_begin_handler_event
+ 1335 + + { };
+ 1336 + +
+ 1337 + + struct array_end_handler_event
+ 1338 + + { };
+ 1339 + +
+ 1340 + + struct key_handler_event
+ 1341 + + {
+ 1342 + + std::string value;
+ 1343 + + };
+ 1344 + +
+ 1345 + + struct string_handler_event
+ 1346 + + {
+ 1347 + + std::string value;
+ 1348 + + };
+ 1349 + +
+ 1350 + + struct int64_handler_event
+ 1351 + + {
+ 1352 + + std::int64_t value;
+ 1353 + + };
+ 1354 + +
+ 1355 + + struct uint64_handler_event
+ 1356 + + {
+ 1357 + + std::uint64_t value;
+ 1358 + + };
+ 1359 + +
+ 1360 + + struct double_handler_event
+ 1361 + + {
+ 1362 + + double value;
+ 1363 + + };
+ 1364 + +
+ 1365 + + struct bool_handler_event
+ 1366 + + {
+ 1367 + + bool value;
+ 1368 + + };
+ 1369 + +
+ 1370 + + struct null_handler_event
+ 1371 + + { };
+ 1372 + +
+ 1373 + + using parse_event = variant2::variant<
+ 1374 + + object_begin_handler_event,
+ 1375 + + object_end_handler_event,
+ 1376 + + array_begin_handler_event,
+ 1377 + + array_end_handler_event,
+ 1378 + + key_handler_event,
+ 1379 + + string_handler_event,
+ 1380 + + int64_handler_event,
+ 1381 + + uint64_handler_event,
+ 1382 + + double_handler_event,
+ 1383 + + bool_handler_event,
+ 1384 + + null_handler_event>;
+ 1385 + +
+ 1386 + + template< class H >
+ 1387 + + struct event_visitor
+ 1388 + + {
+ 1389 + + H& handler;
+ 1390 + + system::error_code& ec;
+ 1391 + +
+ 1392 + + bool
+ 1393 + +14 operator()(object_begin_handler_event&) const
+ 1394 + + {
+ 1395 + +14 return handler.on_object_begin(ec);
+ 1396 + + }
+ 1397 + +
+ 1398 + + bool
+ 1399 + +7 operator()(object_end_handler_event&) const
+ 1400 + + {
+ 1401 + +7 return handler.on_object_end(ec);
+ 1402 + + }
+ 1403 + +
+ 1404 + + bool
+ 1405 + +42 operator()(array_begin_handler_event&) const
+ 1406 + + {
+ 1407 + +42 return handler.on_array_begin(ec);
+ 1408 + + }
+ 1409 + +
+ 1410 + + bool
+ 1411 + +21 operator()(array_end_handler_event&) const
+ 1412 + + {
+ 1413 + +21 return handler.on_array_end(ec);
+ 1414 + + }
+ 1415 + +
+ 1416 + + bool
+ 1417 + +21 operator()(key_handler_event& ev) const
+ 1418 + + {
+ 1419 + +21 return handler.on_key(ec, ev.value);
+ 1420 + + }
+ 1421 + +
+ 1422 + + bool
+ 1423 + +108 operator()(string_handler_event& ev) const
+ 1424 + + {
+ 1425 + +108 return handler.on_string(ec, ev.value);
+ 1426 + + }
+ 1427 + +
+ 1428 + + bool
+ 1429 + +154 operator()(int64_handler_event& ev) const
+ 1430 + + {
+ 1431 + +154 return handler.on_int64(ec, ev.value);
+ 1432 + + }
+ 1433 + +
+ 1434 + + bool
+ 1435 + +14 operator()(uint64_handler_event& ev) const
+ 1436 + + {
+ 1437 + +14 return handler.on_uint64(ec, ev.value);
+ 1438 + + }
+ 1439 + +
+ 1440 + + bool
+ 1441 + +21 operator()(double_handler_event& ev) const
+ 1442 + + {
+ 1443 + +21 return handler.on_double(ec, ev.value);
+ 1444 + + }
+ 1445 + +
+ 1446 + + bool
+ 1447 + +7 operator()(bool_handler_event& ev) const
+ 1448 + + {
+ 1449 + +7 return handler.on_bool(ec, ev.value);
+ 1450 + + }
+ 1451 + +
+ 1452 + + bool
+ 1453 + +7 operator()(null_handler_event&) const
+ 1454 + + {
+ 1455 + +7 return handler.on_null(ec);
+ 1456 + + }
+ 1457 + + };
+ 1458 + +
+ 1459 + + // L<T...> -> variant< monostate, get_handler<T, P>... >
+ 1460 + + template< class P, class L >
+ 1461 + + using inner_handler_variant = mp11::mp_push_front<
+ 1462 + + mp11::mp_transform_q<
+ 1463 + + mp11::mp_bind_back<get_handler, P>,
+ 1464 + + mp11::mp_apply<variant2::variant, L>>,
+ 1465 + + variant2::monostate>;
+ 1466 + +
+ 1467 + + template< class T, class P >
+ 1468 + + class converting_handler<variant_conversion_tag, T, P>
+ 1469 + + {
+ 1470 + + private:
+ 1471 + + using variant_size = mp11::mp_size<T>;
+ 1472 + +
+ 1473 + + T* value_;
+ 1474 + + P* parent_;
+ 1475 + +
+ 1476 + + std::string string_;
+ 1477 + + std::vector< parse_event > events_;
+ 1478 + + inner_handler_variant<converting_handler, T> inner_;
+ 1479 + + int inner_active_ = -1;
+ 1480 + +
+ 1481 + + public:
+ 1482 + + converting_handler( converting_handler const& ) = delete;
+ 1483 + + converting_handler& operator=( converting_handler const& ) = delete;
+ 1484 + +
+ 1485 + +90 converting_handler( T* v, P* p )
+ 1486 + +90 : value_( v )
+ 1487 + +90 , parent_( p )
+ 1488 + +90 {}
+ 1489 + +
+ 1490 + +126 bool signal_value(system::error_code& ec)
+ 1491 + + {
+ 1492 + +126 inner_.template emplace<0>();
+ 1493 + +126 inner_active_ = -1;
+ 1494 + +126 events_.clear();
+ 1495 + +126 return parent_->signal_value(ec);
+ 1496 + + }
+ 1497 + +
+ 1498 + +14 bool signal_end(system::error_code& ec)
+ 1499 + + {
+ 1500 + +14 return parent_->signal_end(ec);
+ 1501 + + }
+ 1502 + +
+ 1503 + + struct alternative_selector
+ 1504 + + {
+ 1505 + + converting_handler* self;
+ 1506 + +
+ 1507 + + template< class I >
+ 1508 + + void
+ 1509 + +227 operator()( I ) const
+ 1510 + + {
+ 1511 + + using V = mp11::mp_at<T, I>;
+ 1512 + +227 auto& v = self->value_->template emplace<I::value>( V{} );
+ 1513 + +227 self->inner_.template emplace<I::value + 1>(&v, self);
+ 1514 + +227 }
+ 1515 + + };
+ 1516 + + void
+ 1517 + +233 next_alternative()
+ 1518 + + {
+ 1519 + +233 if( ++inner_active_ >= static_cast<int>(variant_size::value) )
+ 1520 + +6 return;
+ 1521 + +
+ 1522 + +227 mp11::mp_with_index< variant_size::value >(
+ 1523 + +227 inner_active_, alternative_selector{this} );
+ 1524 + + }
+ 1525 + +
+ 1526 + + struct event_processor
+ 1527 + + {
+ 1528 + + converting_handler* self;
+ 1529 + + system::error_code& ec;
+ 1530 + + parse_event& event;
+ 1531 + +
+ 1532 + + template< class I >
+ 1533 + +416 bool operator()( I ) const
+ 1534 + + {
+ 1535 + +416 auto& handler = variant2::get<I::value + 1>(self->inner_);
+ 1536 + + using Handler = remove_cvref<decltype(handler)>;
+ 1537 + +416 return variant2::visit(
+ 1538 + +832 event_visitor<Handler>{handler, ec}, event );
+ 1539 + + }
+ 1540 + + };
+ 1541 + +286 bool process_events(system::error_code& ec)
+ 1542 + + {
+ 1543 + +286 constexpr std::size_t N = variant_size::value;
+ 1544 + +
+ 1545 + + // should be pointers not iterators, otherwise MSVC crashes
+ 1546 + +286 auto const last = events_.data() + events_.size();
+ 1547 + +286 auto first = last - 1;
+ 1548 + +286 bool ok = false;
+ 1549 + +
+ 1550 + +286 if( inner_active_ < 0 )
+ 1551 + +146 next_alternative();
+ 1552 + + do
+ 1553 + + {
+ 1554 + +373 if( static_cast<std::size_t>(inner_active_) >= N )
+ 1555 + + {
+ 1556 + +6 BOOST_JSON_FAIL( ec, error::exhausted_variants );
+ 1557 + +6 return false;
+ 1558 + + }
+ 1559 + +
+ 1560 + +696 for ( ; first != last; ++first )
+ 1561 + + {
+ 1562 + +832 ok = mp11::mp_with_index< N >(
+ 1563 + +416 inner_active_, event_processor{this, ec, *first} );
+ 1564 + +416 if( !ok )
+ 1565 + + {
+ 1566 + +87 first = events_.data();
+ 1567 + +87 next_alternative();
+ 1568 + +87 ec.clear();
+ 1569 + +87 break;
+ 1570 + + }
+ 1571 + + }
+ 1572 + + }
+ 1573 + +367 while( !ok );
+ 1574 + +
+ 1575 + +280 return true;
+ 1576 + + }
+ 1577 + +
+ 1578 + + #define BOOST_JSON_INVOKE_INNER(ev, ec) \
+ 1579 + + events_.emplace_back( ev ); \
+ 1580 + + return process_events(ec);
+ 1581 + +
+ 1582 + +7 bool on_object_begin( system::error_code& ec )
+ 1583 + + {
+ 1584 + +7 BOOST_JSON_INVOKE_INNER( object_begin_handler_event{}, ec );
+ 1585 + + }
+ 1586 + +
+ 1587 + +7 bool on_object_end( system::error_code& ec )
+ 1588 + + {
+ 1589 + +7 BOOST_JSON_INVOKE_INNER( object_end_handler_event{}, ec );
+ 1590 + + }
+ 1591 + +
+ 1592 + +21 bool on_array_begin( system::error_code& ec )
+ 1593 + + {
+ 1594 + +21 BOOST_JSON_INVOKE_INNER( array_begin_handler_event{}, ec );
+ 1595 + + }
+ 1596 + +
+ 1597 + +28 bool on_array_end( system::error_code& ec )
+ 1598 + + {
+ 1599 + +28 if( !inner_active_ )
+ 1600 + +7 return signal_end(ec);
+ 1601 + +
+ 1602 + +21 BOOST_JSON_INVOKE_INNER( array_end_handler_event{}, ec );
+ 1603 + + }
+ 1604 + +
+ 1605 + +5 bool on_key_part( system::error_code&, string_view sv )
+ 1606 + + {
+ 1607 + +5 string_.append(sv);
+ 1608 + +5 return true;
+ 1609 + + }
+ 1610 + +
+ 1611 + +14 bool on_key( system::error_code& ec, string_view sv )
+ 1612 + + {
+ 1613 + +14 string_.append(sv);
+ 1614 + +28 BOOST_JSON_INVOKE_INNER( key_handler_event{ std::move(string_) }, ec );
+ 1615 + +14 }
+ 1616 + +
+ 1617 + +31 bool on_string_part( system::error_code&, string_view sv )
+ 1618 + + {
+ 1619 + +31 string_.append(sv);
+ 1620 + +31 return true;
+ 1621 + + }
+ 1622 + +
+ 1623 + +48 bool on_string( system::error_code& ec, string_view sv )
+ 1624 + + {
+ 1625 + +48 string_.append(sv);
+ 1626 + +96 BOOST_JSON_INVOKE_INNER(
+ 1627 + + string_handler_event{ std::move(string_) }, ec );
+ 1628 + +48 }
+ 1629 + +
+ 1630 + +60 bool on_number_part( system::error_code& )
+ 1631 + + {
+ 1632 + +60 return true;
+ 1633 + + }
+ 1634 + +
+ 1635 + +133 bool on_int64( system::error_code& ec, std::int64_t v )
+ 1636 + + {
+ 1637 + +133 BOOST_JSON_INVOKE_INNER( int64_handler_event{v}, ec );
+ 1638 + + }
+ 1639 + +
+ 1640 + +7 bool on_uint64( system::error_code& ec, std::uint64_t v )
+ 1641 + + {
+ 1642 + +7 BOOST_JSON_INVOKE_INNER( uint64_handler_event{v}, ec );
+ 1643 + + }
+ 1644 + +
+ 1645 + +14 bool on_double( system::error_code& ec, double v )
+ 1646 + + {
+ 1647 + +14 BOOST_JSON_INVOKE_INNER( double_handler_event{v}, ec );
+ 1648 + + }
+ 1649 + +
+ 1650 + +7 bool on_bool( system::error_code& ec, bool v )
+ 1651 + + {
+ 1652 + +7 BOOST_JSON_INVOKE_INNER( bool_handler_event{v}, ec );
+ 1653 + + }
+ 1654 + +
+ 1655 + +7 bool on_null( system::error_code& ec )
+ 1656 + + {
+ 1657 + +7 BOOST_JSON_INVOKE_INNER( null_handler_event{}, ec );
+ 1658 + + }
+ 1659 + +
+ 1660 + + #undef BOOST_JSON_INVOKE_INNER
+ 1661 + + };
+ 1662 + +
+ 1663 + + // optional handler
+ 1664 + + template<class V, class P>
+ 1665 + + class converting_handler<optional_conversion_tag, V, P>
+ 1666 + + {
+ 1667 + + private:
+ 1668 + + using inner_type = value_result_type<V>;
+ 1669 + + using inner_handler_type = get_handler<inner_type, converting_handler>;
+ 1670 + +
+ 1671 + + V* value_;
+ 1672 + + P* parent_;
+ 1673 + +
+ 1674 + + inner_type inner_value_ = {};
+ 1675 + + inner_handler_type inner_;
+ 1676 + + bool inner_active_ = false;
+ 1677 + +
+ 1678 + + public:
+ 1679 + + converting_handler( converting_handler const& ) = delete;
+ 1680 + + converting_handler& operator=( converting_handler const& ) = delete;
+ 1681 + +
+ 1682 + + converting_handler( V* v, P* p )
+ 1683 + + : value_(v), parent_(p), inner_(&inner_value_, this)
+ 1684 + + {}
+ 1685 + +
+ 1686 + + bool signal_value(system::error_code& ec)
+ 1687 + + {
+ 1688 + + *value_ = std::move(inner_value_);
+ 1689 + +
+ 1690 + + inner_active_ = false;
+ 1691 + + return parent_->signal_value(ec);
+ 1692 + + }
+ 1693 + +
+ 1694 + + bool signal_end(system::error_code& ec)
+ 1695 + + {
+ 1696 + + return parent_->signal_end(ec);
+ 1697 + + }
+ 1698 + +
+ 1699 + + #define BOOST_JSON_INVOKE_INNER(fn) \
+ 1700 + + if( !inner_active_ ) \
+ 1701 + + inner_active_ = true; \
+ 1702 + + return inner_.fn;
+ 1703 + +
+ 1704 + + bool on_object_begin( system::error_code& ec )
+ 1705 + + {
+ 1706 + + BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
+ 1707 + + }
+ 1708 + +
+ 1709 + + bool on_object_end( system::error_code& ec )
+ 1710 + + {
+ 1711 + + BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
+ 1712 + + }
+ 1713 + +
+ 1714 + + bool on_array_begin( system::error_code& ec )
+ 1715 + + {
+ 1716 + + BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
+ 1717 + + }
+ 1718 + +
+ 1719 + + bool on_array_end( system::error_code& ec )
+ 1720 + + {
+ 1721 + + if( !inner_active_ )
+ 1722 + + return signal_end(ec);
+ 1723 + +
+ 1724 + + BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
+ 1725 + + }
+ 1726 + +
+ 1727 + + bool on_key_part( system::error_code& ec, string_view sv )
+ 1728 + + {
+ 1729 + + BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
+ 1730 + + }
+ 1731 + +
+ 1732 + + bool on_key( system::error_code& ec, string_view sv )
+ 1733 + + {
+ 1734 + + BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
+ 1735 + + }
+ 1736 + +
+ 1737 + + bool on_string_part( system::error_code& ec, string_view sv )
+ 1738 + + {
+ 1739 + + BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
+ 1740 + + }
+ 1741 + +
+ 1742 + + bool on_string( system::error_code& ec, string_view sv )
+ 1743 + + {
+ 1744 + + BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
+ 1745 + + }
+ 1746 + +
+ 1747 + + bool on_number_part( system::error_code& ec )
+ 1748 + + {
+ 1749 + + BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
+ 1750 + + }
+ 1751 + +
+ 1752 + + bool on_int64( system::error_code& ec, std::int64_t v )
+ 1753 + + {
+ 1754 + + BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
+ 1755 + + }
+ 1756 + +
+ 1757 + + bool on_uint64( system::error_code& ec, std::uint64_t v )
+ 1758 + + {
+ 1759 + + BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
+ 1760 + + }
+ 1761 + +
+ 1762 + + bool on_double( system::error_code& ec, double v )
+ 1763 + + {
+ 1764 + + BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
+ 1765 + + }
+ 1766 + +
+ 1767 + + bool on_bool( system::error_code& ec, bool v )
+ 1768 + + {
+ 1769 + + BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
+ 1770 + + }
+ 1771 + +
+ 1772 + + bool on_null(system::error_code& ec)
+ 1773 + + {
+ 1774 + + if( !inner_active_ )
+ 1775 + + {
+ 1776 + + *value_ = {};
+ 1777 + + return this->parent_->signal_value(ec);
+ 1778 + + }
+ 1779 + + else
+ 1780 + + {
+ 1781 + + return inner_.on_null(ec);
+ 1782 + + }
+ 1783 + + }
+ 1784 + +
+ 1785 + + #undef BOOST_JSON_INVOKE_INNER
+ 1786 + + };
+ 1787 + +
+ 1788 + + // path handler
+ 1789 + + template< class V, class P >
+ 1790 + + class converting_handler<path_conversion_tag, V, P>
+ 1791 + + : public scalar_handler<P, error::not_string>
+ 1792 + + {
+ 1793 + + private:
+ 1794 + + V* value_;
+ 1795 + + bool cleared_ = false;
+ 1796 + +
+ 1797 + + public:
+ 1798 + + converting_handler( V* v, P* p )
+ 1799 + + : converting_handler::scalar_handler(p)
+ 1800 + + , value_(v)
+ 1801 + + {}
+ 1802 + +
+ 1803 + + bool on_string_part( system::error_code&, string_view sv )
+ 1804 + + {
+ 1805 + + if( !cleared_ )
+ 1806 + + {
+ 1807 + + cleared_ = true;
+ 1808 + + value_->clear();
+ 1809 + + }
+ 1810 + +
+ 1811 + + value_->concat( sv.begin(), sv.end() );
+ 1812 + + return true;
+ 1813 + + }
+ 1814 + +
+ 1815 + + bool on_string(system::error_code& ec, string_view sv)
+ 1816 + + {
+ 1817 + + if( !cleared_ )
+ 1818 + + value_->clear();
+ 1819 + + else
+ 1820 + + cleared_ = false;
+ 1821 + +
+ 1822 + + value_->concat( sv.begin(), sv.end() );
+ 1823 + +
+ 1824 + + return this->parent_->signal_value(ec);
+ 1825 + + }
+ 1826 + + };
+ 1827 + +
+ 1828 + + // into_handler
+ 1829 + + template< class V >
+ 1830 + + class into_handler
+ 1831 + + {
+ 1832 + + private:
+ 1833 + +
+ 1834 + + using inner_handler_type = get_handler<V, into_handler>;
+ 1835 + +
+ 1836 + + inner_handler_type inner_;
+ 1837 + + bool inner_active_ = true;
+ 1838 + +
+ 1839 + + public:
+ 1840 + +
+ 1841 + + into_handler( into_handler const& ) = delete;
+ 1842 + + into_handler& operator=( into_handler const& ) = delete;
+ 1843 + +
+ 1844 + + public:
+ 1845 + +
+ 1846 + + static constexpr std::size_t max_object_size = object::max_size();
+ 1847 + + static constexpr std::size_t max_array_size = array::max_size();
+ 1848 + + static constexpr std::size_t max_key_size = string::max_size();
+ 1849 + + static constexpr std::size_t max_string_size = string::max_size();
+ 1850 + +
+ 1851 + + public:
+ 1852 + +
+ 1853 + +522 explicit into_handler( V* v ): inner_( v, this )
+ 1854 + + {
+ 1855 + +522 }
+ 1856 + +
+ 1857 + +466 bool signal_value(system::error_code&)
+ 1858 + + {
+ 1859 + +466 return true;
+ 1860 + + }
+ 1861 + +
+ 1862 + +7 bool signal_end(system::error_code&)
+ 1863 + + {
+ 1864 + +7 return true;
+ 1865 + + }
+ 1866 + +
+ 1867 + +521 bool on_document_begin( system::error_code& )
+ 1868 + + {
+ 1869 + +521 return true;
+ 1870 + + }
+ 1871 + +
+ 1872 + +473 bool on_document_end( system::error_code& )
+ 1873 + + {
+ 1874 + +473 inner_active_ = false;
+ 1875 + +473 return true;
+ 1876 + + }
+ 1877 + +
+ 1878 + + #define BOOST_JSON_INVOKE_INNER(f) \
+ 1879 + + if( !inner_active_ ) \
+ 1880 + + { \
+ 1881 + + BOOST_JSON_FAIL( ec, error::extra_data ); \
+ 1882 + + return false; \
+ 1883 + + } \
+ 1884 + + else \
+ 1885 + + return inner_.f
+ 1886 + +
+ 1887 + +144 bool on_object_begin( system::error_code& ec )
+ 1888 + + {
+ 1889 + +144 BOOST_JSON_INVOKE_INNER( on_object_begin(ec) );
+ 1890 + + }
+ 1891 + +
+ 1892 + +138 bool on_object_end( std::size_t, system::error_code& ec )
+ 1893 + + {
+ 1894 + +138 BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
+ 1895 + + }
+ 1896 + +
+ 1897 + +418 bool on_array_begin( system::error_code& ec )
+ 1898 + + {
+ 1899 + +418 BOOST_JSON_INVOKE_INNER( on_array_begin(ec) );
+ 1900 + + }
+ 1901 + +
+ 1902 + +404 bool on_array_end( std::size_t, system::error_code& ec )
+ 1903 + + {
+ 1904 + +404 BOOST_JSON_INVOKE_INNER( on_array_end(ec) );
+ 1905 + + }
+ 1906 + +
+ 1907 + +48 bool on_key_part( string_view sv, std::size_t, system::error_code& ec )
+ 1908 + + {
+ 1909 + +48 BOOST_JSON_INVOKE_INNER( on_key_part(ec, sv) );
+ 1910 + + }
+ 1911 + +
+ 1912 + +139 bool on_key( string_view sv, std::size_t, system::error_code& ec )
+ 1913 + + {
+ 1914 + +139 BOOST_JSON_INVOKE_INNER( on_key(ec, sv) );
+ 1915 + + }
+ 1916 + +
+ 1917 + +54 bool on_string_part( string_view sv, std::size_t, system::error_code& ec )
+ 1918 + + {
+ 1919 + +54 BOOST_JSON_INVOKE_INNER( on_string_part(ec, sv) );
+ 1920 + + }
+ 1921 + +
+ 1922 + +101 bool on_string( string_view sv, std::size_t, system::error_code& ec )
+ 1923 + + {
+ 1924 + +101 BOOST_JSON_INVOKE_INNER( on_string(ec, sv) );
+ 1925 + + }
+ 1926 + +
+ 1927 + +484 bool on_number_part( string_view, system::error_code& ec )
+ 1928 + + {
+ 1929 + +484 BOOST_JSON_INVOKE_INNER( on_number_part(ec) );
+ 1930 + + }
+ 1931 + +
+ 1932 + +707 bool on_int64( std::int64_t v, string_view, system::error_code& ec )
+ 1933 + + {
+ 1934 + +707 BOOST_JSON_INVOKE_INNER( on_int64(ec, v) );
+ 1935 + + }
+ 1936 + +
+ 1937 + +39 bool on_uint64( std::uint64_t v, string_view, system::error_code& ec )
+ 1938 + + {
+ 1939 + +39 BOOST_JSON_INVOKE_INNER( on_uint64(ec, v) );
+ 1940 + + }
+ 1941 + +
+ 1942 + +63 bool on_double( double v, string_view, system::error_code& ec )
+ 1943 + + {
+ 1944 + +63 BOOST_JSON_INVOKE_INNER( on_double(ec, v) );
+ 1945 + + }
+ 1946 + +
+ 1947 + +44 bool on_bool( bool v, system::error_code& ec )
+ 1948 + + {
+ 1949 + +44 BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
+ 1950 + + }
+ 1951 + +
+ 1952 + +39 bool on_null( system::error_code& ec )
+ 1953 + + {
+ 1954 + +39 BOOST_JSON_INVOKE_INNER( on_null(ec) );
+ 1955 + + }
+ 1956 + +
+ 1957 + +1254 bool on_comment_part(string_view, system::error_code&)
+ 1958 + + {
+ 1959 + +1254 return true;
+ 1960 + + }
+ 1961 + +
+ 1962 + +66 bool on_comment(string_view, system::error_code&)
+ 1963 + + {
+ 1964 + +66 return true;
+ 1965 + + }
+ 1966 + +
+ 1967 + + #undef BOOST_JSON_INVOKE_INNER
+ 1968 + + };
+ 1969 + +
+ 1970 + + } // namespace detail
+ 1971 + + } // namespace boost
+ 1972 + + } // namespace json
+ 1973 + +
+ 1974 + + #endif
+ 1975 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.parse_number.hpp.7949b767450af0a0c4e38d459ab8efa6.html b/json/gcovr/index.parse_number.hpp.7949b767450af0a0c4e38d459ab8efa6.html new file mode 100644 index 00000000..061c6ba5 --- /dev/null +++ b/json/gcovr/index.parse_number.hpp.7949b767450af0a0c4e38d459ab8efa6.html @@ -0,0 +1,4006 @@ + + + + + + detail/charconv/detail/fast_float/parse_number.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/fast_float/parse_number.hpp

+
+ + 42.9% Lines (27/63) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/fast_float/parse_number.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2020-2023 Daniel Lemire
+ 2 + + // Copyright 2023 Matt Borland
+ 3 + + // Distributed under the Boost Software License, Version 1.0.
+ 4 + + // https://www.boost.org/LICENSE_1_0.txt
+ 5 + + //
+ 6 + + // Derivative of: https://github.com/fastfloat/fast_float
+ 7 + +
+ 8 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_PARSE_NUMBER_HPP
+ 9 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_PARSE_NUMBER_HPP
+ 10 + +
+ 11 + + #include <boost/json/detail/charconv/detail/fast_float/ascii_number.hpp>
+ 12 + + #include <boost/json/detail/charconv/detail/fast_float/decimal_to_binary.hpp>
+ 13 + + #include <boost/json/detail/charconv/detail/fast_float/digit_comparison.hpp>
+ 14 + + #include <boost/json/detail/charconv/detail/fast_float/float_common.hpp>
+ 15 + +
+ 16 + + #include <cmath>
+ 17 + + #include <cstring>
+ 18 + + #include <limits>
+ 19 + + #include <system_error>
+ 20 + +
+ 21 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float {
+ 22 + +
+ 23 + +
+ 24 + + namespace detail {
+ 25 + + /**
+ 26 + + * Special case +inf, -inf, nan, infinity, -infinity.
+ 27 + + * The case comparisons could be made much faster given that we know that the
+ 28 + + * strings a null-free and fixed.
+ 29 + + **/
+ 30 + +
+ 31 + + #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 32 + + # pragma GCC diagnostic push
+ 33 + + # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+ 34 + + #endif
+ 35 + +
+ 36 + + template <typename T, typename UC>
+ 37 + + from_chars_result_t<UC> BOOST_JSON_CXX14_CONSTEXPR
+ 38 + + parse_infnan(UC const * first, UC const * last, T &value) noexcept {
+ 39 + + from_chars_result_t<UC> answer{};
+ 40 + + answer.ptr = first;
+ 41 + + answer.ec = std::errc(); // be optimistic
+ 42 + + bool minusSign = false;
+ 43 + + if (*first == UC('-')) { // assume first < last, so dereference without checks; C++17 20.19.3.(7.1) explicitly forbids '+' here
+ 44 + + minusSign = true;
+ 45 + + ++first;
+ 46 + + }
+ 47 + + if (last - first >= 3) {
+ 48 + + if (fastfloat_strncasecmp(first, str_const_nan<UC>(), 3)) {
+ 49 + + answer.ptr = (first += 3);
+ 50 + + value = minusSign ? -std::numeric_limits<T>::quiet_NaN() : std::numeric_limits<T>::quiet_NaN();
+ 51 + + // Check for possible nan(n-char-seq-opt), C++17 20.19.3.7, C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan).
+ 52 + + if(first != last && *first == UC('(')) {
+ 53 + + for(UC const * ptr = first + 1; ptr != last; ++ptr) {
+ 54 + + if (*ptr == UC(')')) {
+ 55 + + answer.ptr = ptr + 1; // valid nan(n-char-seq-opt)
+ 56 + + break;
+ 57 + + }
+ 58 + + else if(!((UC('a') <= *ptr && *ptr <= UC('z')) || (UC('A') <= *ptr && *ptr <= UC('Z')) || (UC('0') <= *ptr && *ptr <= UC('9')) || *ptr == UC('_')))
+ 59 + + break; // forbidden char, not nan(n-char-seq-opt)
+ 60 + + }
+ 61 + + }
+ 62 + + return answer;
+ 63 + + }
+ 64 + + if (fastfloat_strncasecmp(first, str_const_inf<UC>(), 3)) {
+ 65 + + if ((last - first >= 8) && fastfloat_strncasecmp(first + 3, str_const_inf<UC>() + 3, 5)) {
+ 66 + + answer.ptr = first + 8;
+ 67 + + } else {
+ 68 + + answer.ptr = first + 3;
+ 69 + + }
+ 70 + + value = minusSign ? -std::numeric_limits<T>::infinity() : std::numeric_limits<T>::infinity();
+ 71 + + return answer;
+ 72 + + }
+ 73 + + }
+ 74 + + answer.ec = std::errc::invalid_argument;
+ 75 + + return answer;
+ 76 + + }
+ 77 + +
+ 78 + + #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 79 + + # pragma GCC diagnostic pop
+ 80 + + #endif
+ 81 + +
+ 82 + + /**
+ 83 + + * Returns true if the floating-pointing rounding mode is to 'nearest'.
+ 84 + + * It is the default on most system. This function is meant to be inexpensive.
+ 85 + + * Credit : @mwalcott3
+ 86 + + */
+ 87 + + BOOST_FORCEINLINE bool rounds_to_nearest() noexcept {
+ 88 + + // https://lemire.me/blog/2020/06/26/gcc-not-nearest/
+ 89 + + #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
+ 90 + + return false;
+ 91 + + #endif
+ 92 + + // See
+ 93 + + // A fast function to check your floating-point rounding mode
+ 94 + + // https://lemire.me/blog/2022/11/16/a-fast-function-to-check-your-floating-point-rounding-mode/
+ 95 + + //
+ 96 + + // This function is meant to be equivalent to :
+ 97 + + // prior: #include <cfenv>
+ 98 + + // return fegetround() == FE_TONEAREST;
+ 99 + + // However, it is expected to be much faster than the fegetround()
+ 100 + + // function call.
+ 101 + + //
+ 102 + + // The volatile keywoard prevents the compiler from computing the function
+ 103 + + // at compile-time.
+ 104 + + // There might be other ways to prevent compile-time optimizations (e.g., asm).
+ 105 + + // The value does not need to be std::numeric_limits<float>::min(), any small
+ 106 + + // value so that 1 + x should round to 1 would do (after accounting for excess
+ 107 + + // precision, as in 387 instructions).
+ 108 + + static volatile float fmin = (std::numeric_limits<float>::min)();
+ 109 + +5895 float fmini = fmin; // we copy it so that it gets loaded at most once.
+ 110 + + //
+ 111 + + // Explanation:
+ 112 + + // Only when fegetround() == FE_TONEAREST do we have that
+ 113 + + // fmin + 1.0f == 1.0f - fmin.
+ 114 + + //
+ 115 + + // FE_UPWARD:
+ 116 + + // fmin + 1.0f > 1
+ 117 + + // 1.0f - fmin == 1
+ 118 + + //
+ 119 + + // FE_DOWNWARD or FE_TOWARDZERO:
+ 120 + + // fmin + 1.0f == 1
+ 121 + + // 1.0f - fmin < 1
+ 122 + + //
+ 123 + + // Note: This may fail to be accurate if fast-math has been
+ 124 + + // enabled, as rounding conventions may not apply.
+ 125 + + #ifdef BOOST_JSON_FASTFLOAT_VISUAL_STUDIO
+ 126 + + # pragma warning(push)
+ 127 + + // todo: is there a VS warning?
+ 128 + + // see https://stackoverflow.com/questions/46079446/is-there-a-warning-for-floating-point-equality-checking-in-visual-studio-2013
+ 129 + + #elif defined(__clang__)
+ 130 + + # pragma clang diagnostic push
+ 131 + + # pragma clang diagnostic ignored "-Wfloat-equal"
+ 132 + + #elif defined(__GNUC__)
+ 133 + + # pragma GCC diagnostic push
+ 134 + + # pragma GCC diagnostic ignored "-Wfloat-equal"
+ 135 + + #endif
+ 136 + +5895 return (fmini + 1.0f == 1.0f - fmini);
+ 137 + + #ifdef BOOST_JSON_FASTFLOAT_VISUAL_STUDIO
+ 138 + + # pragma warning(pop)
+ 139 + + #elif defined(__clang__)
+ 140 + + # pragma clang diagnostic pop
+ 141 + + #elif defined(__GNUC__)
+ 142 + + # pragma GCC diagnostic pop
+ 143 + + #endif
+ 144 + + }
+ 145 + +
+ 146 + + } // namespace detail
+ 147 + +
+ 148 + + template<typename T, typename UC>
+ 149 + + BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 150 + +1009310 from_chars_result_t<UC> from_chars(UC const * first, UC const * last,
+ 151 + + T &value, chars_format fmt /*= chars_format::general*/) noexcept {
+ 152 + +1009310 return from_chars_advanced(first, last, value, parse_options_t<UC>{fmt});
+ 153 + + }
+ 154 + +
+ 155 + + template<typename T, typename UC>
+ 156 + + BOOST_JSON_FASTFLOAT_CONSTEXPR20
+ 157 + +1009310 from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
+ 158 + + T &value, parse_options_t<UC> options) noexcept {
+ 159 + +
+ 160 + + static_assert (std::is_same<T, double>::value || std::is_same<T, float>::value, "only float and double are supported");
+ 161 + + static_assert (std::is_same<UC, char>::value ||
+ 162 + + std::is_same<UC, wchar_t>::value ||
+ 163 + + std::is_same<UC, char16_t>::value ||
+ 164 + + std::is_same<UC, char32_t>::value , "only char, wchar_t, char16_t and char32_t are supported");
+ 165 + +
+ 166 + + from_chars_result_t<UC> answer;
+ 167 + +1009310 if (first == last) {
+ 168 + + answer.ec = std::errc::invalid_argument;
+ 169 + + answer.ptr = first;
+ 170 + + return answer;
+ 171 + + }
+ 172 + +1009310 parsed_number_string_t<UC> pns = parse_number_string<UC>(first, last, options);
+ 173 + +1009310 if (!pns.valid) {
+ 174 + + return detail::parse_infnan(first, last, value);
+ 175 + + }
+ 176 + +1009310 answer.ec = std::errc(); // be optimistic
+ 177 + +1009310 answer.ptr = pns.lastmatch;
+ 178 + + // The implementation of the Clinger's fast path is convoluted because
+ 179 + + // we want round-to-nearest in all cases, irrespective of the rounding mode
+ 180 + + // selected on the thread.
+ 181 + + // We proceed optimistically, assuming that detail::rounds_to_nearest() returns
+ 182 + + // true.
+ 183 + +1009310 if (binary_format<T>::min_exponent_fast_path() <= pns.exponent && pns.exponent <= binary_format<T>::max_exponent_fast_path() && !pns.too_many_digits) {
+ 184 + + // Unfortunately, the conventional Clinger's fast path is only possible
+ 185 + + // when the system rounds to the nearest float.
+ 186 + + //
+ 187 + + // We expect the next branch to almost always be selected.
+ 188 + + // We could check it first (before the previous branch), but
+ 189 + + // there might be performance advantages at having the check
+ 190 + + // be last.
+ 191 + +11790 if(!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) {
+ 192 + + // We have that fegetround() == FE_TONEAREST.
+ 193 + + // Next is Clinger's fast path.
+ 194 + +5895 if (pns.mantissa <=binary_format<T>::max_mantissa_fast_path()) {
+ 195 + +5570 value = T(pns.mantissa);
+ 196 + +5570 if (pns.exponent < 0) { value = value / binary_format<T>::exact_power_of_ten(-pns.exponent); }
+ 197 + +1756 else { value = value * binary_format<T>::exact_power_of_ten(pns.exponent); }
+ 198 + +5570 if (pns.negative) { value = -value; }
+ 199 + +5570 return answer;
+ 200 + + }
+ 201 + + } else {
+ 202 + + // We do not have that fegetround() == FE_TONEAREST.
+ 203 + + // Next is a modified Clinger's fast path, inspired by Jakub Jelínek's proposal
+ 204 + + if (pns.exponent >= 0 && pns.mantissa <=binary_format<T>::max_mantissa_fast_path(pns.exponent)) {
+ 205 + + #if defined(__clang__)
+ 206 + + // Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD
+ 207 + + if(pns.mantissa == 0) {
+ 208 + + value = pns.negative ? -0. : 0.;
+ 209 + + return answer;
+ 210 + + }
+ 211 + + #endif
+ 212 + + value = T(pns.mantissa) * binary_format<T>::exact_power_of_ten(pns.exponent);
+ 213 + + if (pns.negative) { value = -value; }
+ 214 + + return answer;
+ 215 + + }
+ 216 + + }
+ 217 + + }
+ 218 + +1003740 adjusted_mantissa am = compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
+ 219 + +1003740 if(pns.too_many_digits && am.power2 >= 0) {
+ 220 + +2001424 if(am != compute_float<binary_format<T>>(pns.exponent, pns.mantissa + 1)) {
+ 221 + +5972 am = compute_error<binary_format<T>>(pns.exponent, pns.mantissa);
+ 222 + + }
+ 223 + + }
+ 224 + + // If we called compute_float<binary_format<T>>(pns.exponent, pns.mantissa) and we have an invalid power (am.power2 < 0),
+ 225 + + // then we need to go the long way around again. This is very uncommon.
+ 226 + +1003740 if(am.power2 < 0) { am = digit_comp<T>(pns, am); }
+ 227 + +1003740 to_float(pns.negative, am, value);
+ 228 + + // Test for over/underflow.
+ 229 + +1003740 if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) || am.power2 == binary_format<T>::infinite_power()) {
+ 230 + +30608 answer.ec = std::errc::result_out_of_range;
+ 231 + + }
+ 232 + +1003740 return answer;
+ 233 + + }
+ 234 + +
+ 235 + + }}}}}} // namespace fast_float
+ 236 + +
+ 237 + + #endif
+ 238 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.parser.hpp.45a498812670ba69036304cd17e3052d.html b/json/gcovr/index.parser.hpp.45a498812670ba69036304cd17e3052d.html new file mode 100644 index 00000000..84a8739c --- /dev/null +++ b/json/gcovr/index.parser.hpp.45a498812670ba69036304cd17e3052d.html @@ -0,0 +1,5134 @@ + + + + + + detail/charconv/detail/parser.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/charconv/detail/parser.hpp

+
+ + 0.0% Lines (0/162) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/charconv/detail/parser.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + // Copyright 2023 Matt Borland
+ 2 + + // Distributed under the Boost Software License, Version 1.0.
+ 3 + + // https://www.boost.org/LICENSE_1_0.txt
+ 4 + +
+ 5 + + #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_PARSER_HPP
+ 6 + + #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_PARSER_HPP
+ 7 + +
+ 8 + + #include <boost/json/detail/charconv/detail/config.hpp>
+ 9 + + #include <boost/json/detail/charconv/detail/from_chars_result.hpp>
+ 10 + + #include <boost/json/detail/charconv/detail/from_chars_integer_impl.hpp>
+ 11 + + #include <boost/json/detail/charconv/detail/integer_search_trees.hpp>
+ 12 + + #include <boost/json/detail/charconv/limits.hpp>
+ 13 + + #include <boost/json/detail/charconv/chars_format.hpp>
+ 14 + + #include <system_error>
+ 15 + + #include <type_traits>
+ 16 + + #include <limits>
+ 17 + + #include <cerrno>
+ 18 + + #include <cstdint>
+ 19 + + #include <cstring>
+ 20 + +
+ 21 + + #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 22 + + # pragma GCC diagnostic push
+ 23 + + # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+ 24 + + #endif
+ 25 + +
+ 26 + + namespace boost { namespace json { namespace detail { namespace charconv { namespace detail {
+ 27 + +
+ 28 + + inline bool is_integer_char(char c) noexcept
+ 29 + + {
+ 30 + + return (c >= '0') && (c <= '9');
+ 31 + + }
+ 32 + +
+ 33 + + inline bool is_hex_char(char c) noexcept
+ 34 + + {
+ 35 + + return is_integer_char(c) || (((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')));
+ 36 + + }
+ 37 + +
+ 38 + + inline bool is_delimiter(char c, chars_format fmt) noexcept
+ 39 + + {
+ 40 + + if (fmt != chars_format::hex)
+ 41 + + {
+ 42 + + return !is_integer_char(c) && c != 'e' && c != 'E';
+ 43 + + }
+ 44 + +
+ 45 + + return !is_hex_char(c) && c != 'p' && c != 'P';
+ 46 + + }
+ 47 + +
+ 48 + + template <typename Unsigned_Integer, typename Integer>
+ 49 + + inline from_chars_result parser(const char* first, const char* last, bool& sign, Unsigned_Integer& significand, Integer& exponent, chars_format fmt = chars_format::general) noexcept
+ 50 + + {
+ 51 + + if (first > last)
+ 52 + + {
+ 53 + + return {first, std::errc::invalid_argument};
+ 54 + + }
+ 55 + +
+ 56 + + auto next = first;
+ 57 + + bool all_zeros = true;
+ 58 + +
+ 59 + + // First extract the sign
+ 60 + + if (*next == '-')
+ 61 + + {
+ 62 + + sign = true;
+ 63 + + ++next;
+ 64 + + }
+ 65 + + else if (*next == '+')
+ 66 + + {
+ 67 + + return {next, std::errc::invalid_argument};
+ 68 + + }
+ 69 + + else
+ 70 + + {
+ 71 + + sign = false;
+ 72 + + }
+ 73 + +
+ 74 + + // Ignore leading zeros (e.g. 00005 or -002.3e+5)
+ 75 + + while (*next == '0' && next != last)
+ 76 + + {
+ 77 + + ++next;
+ 78 + + }
+ 79 + +
+ 80 + + // If the number is 0 we can abort now
+ 81 + + char exp_char;
+ 82 + + char capital_exp_char;
+ 83 + + if (fmt != chars_format::hex)
+ 84 + + {
+ 85 + + exp_char = 'e';
+ 86 + + capital_exp_char = 'E';
+ 87 + + }
+ 88 + + else
+ 89 + + {
+ 90 + + exp_char = 'p';
+ 91 + + capital_exp_char = 'P';
+ 92 + + }
+ 93 + +
+ 94 + + if (next == last || *next == exp_char || *next == -capital_exp_char)
+ 95 + + {
+ 96 + + significand = 0;
+ 97 + + exponent = 0;
+ 98 + + return {next, std::errc()};
+ 99 + + }
+ 100 + +
+ 101 + + // Next we get the significand
+ 102 + + constexpr std::size_t significand_buffer_size = limits<Unsigned_Integer>::max_chars10 - 1; // Base 10 or 16
+ 103 + + char significand_buffer[significand_buffer_size] {};
+ 104 + + std::size_t i = 0;
+ 105 + + std::size_t dot_position = 0;
+ 106 + + Integer extra_zeros = 0;
+ 107 + + Integer leading_zero_powers = 0;
+ 108 + + const auto char_validation_func = (fmt != charconv::chars_format::hex) ? is_integer_char : is_hex_char;
+ 109 + + const int base = (fmt != charconv::chars_format::hex) ? 10 : 16;
+ 110 + +
+ 111 + + while (char_validation_func(*next) && next != last && i < significand_buffer_size)
+ 112 + + {
+ 113 + + all_zeros = false;
+ 114 + + significand_buffer[i] = *next;
+ 115 + + ++next;
+ 116 + + ++i;
+ 117 + + }
+ 118 + +
+ 119 + + bool fractional = false;
+ 120 + + if (next == last)
+ 121 + + {
+ 122 + + // if fmt is chars_format::scientific the e is required
+ 123 + + if (fmt == chars_format::scientific)
+ 124 + + {
+ 125 + + return {first, std::errc::invalid_argument};
+ 126 + + }
+ 127 + +
+ 128 + + exponent = 0;
+ 129 + + std::size_t offset = i;
+ 130 + +
+ 131 + + from_chars_result r = from_chars(significand_buffer, significand_buffer + offset, significand, base);
+ 132 + + switch (r.ec)
+ 133 + + {
+ 134 + + case std::errc::invalid_argument:
+ 135 + + return {first, std::errc::invalid_argument};
+ 136 + + case std::errc::result_out_of_range:
+ 137 + + return {next, std::errc::result_out_of_range};
+ 138 + + default:
+ 139 + + return {next, std::errc()};
+ 140 + + }
+ 141 + + }
+ 142 + + else if (*next == '.')
+ 143 + + {
+ 144 + + ++next;
+ 145 + + fractional = true;
+ 146 + + dot_position = i;
+ 147 + +
+ 148 + + // Process the fractional part if we have it
+ 149 + + //
+ 150 + + // if fmt is chars_format::scientific the e is required
+ 151 + + // if fmt is chars_format::fixed and not scientific the e is disallowed
+ 152 + + // if fmt is chars_format::general (which is scientific and fixed) the e is optional
+ 153 + +
+ 154 + + // If we have the value 0.00001 we can continue to chop zeros and adjust the exponent
+ 155 + + // so that we get the useful parts of the fraction
+ 156 + + if (all_zeros)
+ 157 + + {
+ 158 + + while (*next == '0' && next != last)
+ 159 + + {
+ 160 + + ++next;
+ 161 + + --leading_zero_powers;
+ 162 + + }
+ 163 + +
+ 164 + + if (next == last)
+ 165 + + {
+ 166 + + return {last, std::errc()};
+ 167 + + }
+ 168 + + }
+ 169 + +
+ 170 + + while (char_validation_func(*next) && next != last && i < significand_buffer_size)
+ 171 + + {
+ 172 + + significand_buffer[i] = *next;
+ 173 + + ++next;
+ 174 + + ++i;
+ 175 + + }
+ 176 + + }
+ 177 + +
+ 178 + + if (i == significand_buffer_size)
+ 179 + + {
+ 180 + + // We can not process any more significant figures into the significand so skip to the end
+ 181 + + // or the exponent part and capture the additional orders of magnitude for the exponent
+ 182 + + bool found_dot = false;
+ 183 + + while ((char_validation_func(*next) || *next == '.') && next != last)
+ 184 + + {
+ 185 + + ++next;
+ 186 + + if (!fractional && !found_dot)
+ 187 + + {
+ 188 + + ++extra_zeros;
+ 189 + + }
+ 190 + + if (*next == '.')
+ 191 + + {
+ 192 + + found_dot = true;
+ 193 + + }
+ 194 + + }
+ 195 + + }
+ 196 + +
+ 197 + + if (next == last || is_delimiter(*next, fmt))
+ 198 + + {
+ 199 + + if (fmt == chars_format::scientific)
+ 200 + + {
+ 201 + + return {first, std::errc::invalid_argument};
+ 202 + + }
+ 203 + + if (dot_position != 0 || fractional)
+ 204 + + {
+ 205 + + exponent = static_cast<Integer>(dot_position) - i + extra_zeros + leading_zero_powers;
+ 206 + + }
+ 207 + + else
+ 208 + + {
+ 209 + + exponent = extra_zeros + leading_zero_powers;
+ 210 + + }
+ 211 + + std::size_t offset = i;
+ 212 + +
+ 213 + + from_chars_result r = from_chars(significand_buffer, significand_buffer + offset, significand, base);
+ 214 + + switch (r.ec)
+ 215 + + {
+ 216 + + case std::errc::invalid_argument:
+ 217 + + return {first, std::errc::invalid_argument};
+ 218 + + case std::errc::result_out_of_range:
+ 219 + + return {next, std::errc::result_out_of_range};
+ 220 + + default:
+ 221 + + return {next, std::errc()};
+ 222 + + }
+ 223 + + }
+ 224 + + else if (*next == exp_char || *next == capital_exp_char)
+ 225 + + {
+ 226 + + // Would be a number without a significand e.g. e+03
+ 227 + + if (next == first)
+ 228 + + {
+ 229 + + return {next, std::errc::invalid_argument};
+ 230 + + }
+ 231 + +
+ 232 + + ++next;
+ 233 + + if (fmt == chars_format::fixed)
+ 234 + + {
+ 235 + + return {first, std::errc::invalid_argument};
+ 236 + + }
+ 237 + +
+ 238 + + exponent = i - 1;
+ 239 + + std::size_t offset = i;
+ 240 + + bool round = false;
+ 241 + + // If more digits are present than representable in the significand of the target type
+ 242 + + // we set the maximum
+ 243 + + if (offset > significand_buffer_size)
+ 244 + + {
+ 245 + + offset = significand_buffer_size - 1;
+ 246 + + i = significand_buffer_size;
+ 247 + + if (significand_buffer[offset] == '5' ||
+ 248 + + significand_buffer[offset] == '6' ||
+ 249 + + significand_buffer[offset] == '7' ||
+ 250 + + significand_buffer[offset] == '8' ||
+ 251 + + significand_buffer[offset] == '9')
+ 252 + + {
+ 253 + + round = true;
+ 254 + + }
+ 255 + + }
+ 256 + +
+ 257 + + // If the significand is 0 from chars will return std::errc::invalid_argument because there is nothing in the buffer,
+ 258 + + // but it is a valid value. We need to continue parsing to get the correct value of ptr even
+ 259 + + // though we know we could bail now.
+ 260 + + //
+ 261 + + // See GitHub issue #29: https://github.com/cppalliance/charconv/issues/29
+ 262 + + if (offset != 0)
+ 263 + + {
+ 264 + + from_chars_result r = from_chars(significand_buffer, significand_buffer + offset, significand, base);
+ 265 + + switch (r.ec)
+ 266 + + {
+ 267 + + case std::errc::invalid_argument:
+ 268 + + return {first, std::errc::invalid_argument};
+ 269 + + case std::errc::result_out_of_range:
+ 270 + + return {next, std::errc::result_out_of_range};
+ 271 + + default:
+ 272 + + break;
+ 273 + + }
+ 274 + +
+ 275 + + if (round)
+ 276 + + {
+ 277 + + significand += 1;
+ 278 + + }
+ 279 + + }
+ 280 + + }
+ 281 + + else
+ 282 + + {
+ 283 + + return {first, std::errc::invalid_argument};
+ 284 + + }
+ 285 + +
+ 286 + + // Finally we get the exponent
+ 287 + + constexpr std::size_t exponent_buffer_size = 6; // Float128 min exp is −16382
+ 288 + + char exponent_buffer[exponent_buffer_size] {};
+ 289 + + Integer significand_digits = i;
+ 290 + + i = 0;
+ 291 + +
+ 292 + + // Get the sign first
+ 293 + + if (*next == '-')
+ 294 + + {
+ 295 + + exponent_buffer[i] = *next;
+ 296 + + ++next;
+ 297 + + ++i;
+ 298 + + }
+ 299 + + else if (*next == '+')
+ 300 + + {
+ 301 + + ++next;
+ 302 + + }
+ 303 + +
+ 304 + + // Next strip any leading zeros
+ 305 + + while (*next == '0')
+ 306 + + {
+ 307 + + ++next;
+ 308 + + }
+ 309 + +
+ 310 + + // Process the significant values
+ 311 + + while (is_integer_char(*next) && next != last && i < exponent_buffer_size)
+ 312 + + {
+ 313 + + exponent_buffer[i] = *next;
+ 314 + + ++next;
+ 315 + + ++i;
+ 316 + + }
+ 317 + +
+ 318 + + // If the exponent can't fit in the buffer the number is not representable
+ 319 + + if (next != last && i == exponent_buffer_size)
+ 320 + + {
+ 321 + + return {next, std::errc::result_out_of_range};
+ 322 + + }
+ 323 + +
+ 324 + + // If the exponent was e+00 or e-00
+ 325 + + if (i == 0 || (i == 1 && exponent_buffer[0] == '-'))
+ 326 + + {
+ 327 + + if (fractional)
+ 328 + + {
+ 329 + + exponent = static_cast<Integer>(dot_position) - significand_digits;
+ 330 + + }
+ 331 + + else
+ 332 + + {
+ 333 + + exponent = extra_zeros;
+ 334 + + }
+ 335 + +
+ 336 + + return {next, std::errc()};
+ 337 + + }
+ 338 + +
+ 339 + + const auto r = from_chars(exponent_buffer, exponent_buffer + i, exponent);
+ 340 + +
+ 341 + + exponent += leading_zero_powers;
+ 342 + +
+ 343 + + switch (r.ec)
+ 344 + + {
+ 345 + + case std::errc::invalid_argument:
+ 346 + + return {first, std::errc::invalid_argument};
+ 347 + + case std::errc::result_out_of_range:
+ 348 + + return {next, std::errc::result_out_of_range};
+ 349 + + default:
+ 350 + + if (fractional)
+ 351 + + {
+ 352 + + // Need to take the offset from 1.xxx because compute_floatXXX assumes the significand is an integer
+ 353 + + // so the exponent is off by the number of digits in the significand - 1
+ 354 + + if (fmt == chars_format::hex)
+ 355 + + {
+ 356 + + // In hex the number of digits parsed is possibly less than the number of digits in base10
+ 357 + + exponent -= num_digits(significand) - dot_position;
+ 358 + + }
+ 359 + + else
+ 360 + + {
+ 361 + + exponent -= significand_digits - dot_position;
+ 362 + + }
+ 363 + + }
+ 364 + + else
+ 365 + + {
+ 366 + + exponent += extra_zeros;
+ 367 + + }
+ 368 + + return {next, std::errc()};
+ 369 + + }
+ 370 + + }
+ 371 + +
+ 372 + + }}}}} // Namespaces
+ 373 + +
+ 374 + + #if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
+ 375 + + # pragma GCC diagnostic pop
+ 376 + + #endif
+ 377 + +
+ 378 + + #endif // BOOST_JSON_DETAIL_CHARCONV_DETAIL_PARSER_HPP
+ 379 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.parser.hpp.d91835266758ed9bedb91a3636a5e82c.html b/json/gcovr/index.parser.hpp.d91835266758ed9bedb91a3636a5e82c.html new file mode 100644 index 00000000..22992aae --- /dev/null +++ b/json/gcovr/index.parser.hpp.d91835266758ed9bedb91a3636a5e82c.html @@ -0,0 +1,6446 @@ + + + + + + parser.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

parser.hpp

+
+ + 100.0% Lines (29/29) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
parser.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_PARSER_HPP
+ 11 + + #define BOOST_JSON_PARSER_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/json/basic_parser.hpp>
+ 15 + + #include <boost/json/storage_ptr.hpp>
+ 16 + + #include <boost/json/value.hpp>
+ 17 + + #include <boost/json/detail/handler.hpp>
+ 18 + + #include <type_traits>
+ 19 + + #include <cstddef>
+ 20 + +
+ 21 + + namespace boost {
+ 22 + + namespace json {
+ 23 + +
+ 24 + + //----------------------------------------------------------
+ 25 + +
+ 26 + + /** A DOM parser for JSON contained in a single buffer.
+ 27 + +
+ 28 + + This class is used to parse a JSON text contained in a single character
+ 29 + + buffer, into a @ref value container.
+ 30 + +
+ 31 + + @par Usage
+ 32 + + To use the parser first construct it, then optionally call @ref reset to
+ 33 + + specify a @ref storage_ptr to use for the resulting @ref value. Then call
+ 34 + + @ref write to parse a character buffer containing a complete JSON text. If
+ 35 + + the parse is successful, call @ref release to take ownership of the value:
+ 36 + + @code
+ 37 + + parser p; // construct a parser
+ 38 + + size_t n = p.write( "[1,2,3]" ); // parse a complete JSON text
+ 39 + + assert( n == 7 ); // all characters consumed
+ 40 + + value jv = p.release(); // take ownership of the value
+ 41 + + @endcode
+ 42 + +
+ 43 + + @par Extra Data
+ 44 + + When the character buffer provided as input contains additional data that
+ 45 + + is not part of the complete JSON text, an error is returned. The @ref
+ 46 + + write_some function is an alternative which allows the parse to finish
+ 47 + + early, without consuming all the characters in the buffer. This allows
+ 48 + + parsing of a buffer containing multiple individual JSON texts or containing
+ 49 + + different protocol data:
+ 50 + + @code
+ 51 + + parser p; // construct a parser
+ 52 + + size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON text
+ 53 + + assert( n == 8 ); // only some characters consumed
+ 54 + + value jv = p.release(); // take ownership of the value
+ 55 + + @endcode
+ 56 + +
+ 57 + + @par Temporary Storage
+ 58 + + The parser may dynamically allocate temporary storage as needed to
+ 59 + + accommodate the nesting level of the JSON text being parsed. Temporary
+ 60 + + storage is first obtained from an optional, caller-owned buffer specified
+ 61 + + upon construction. When that is exhausted, the next allocation uses the
+ 62 + + @ref boost::container::pmr::memory_resource passed to the constructor; if
+ 63 + + no such argument is specified, the default memory resource is used.
+ 64 + + Temporary storage is freed only when the parser is destroyed; The
+ 65 + + performance of parsing multiple JSON texts may be improved by reusing the
+ 66 + + same parser instance.
+ 67 + +
+ 68 + + It is important to note that the `boost::container::pmr::memory_resource`
+ 69 + + supplied upon construction is used for temporary storage only, and not for
+ 70 + + allocating the elements which make up the parsed value. That other memory
+ 71 + + resource is optionally supplied in each call to @ref reset.
+ 72 + +
+ 73 + + @par Duplicate Keys
+ 74 + + If there are object elements with duplicate keys; that is, if multiple
+ 75 + + elements in an object have keys that compare equal, only the last
+ 76 + + equivalent element will be inserted.
+ 77 + +
+ 78 + + @par Non-Standard JSON
+ 79 + + The @ref parse_options structure optionally provided upon construction is
+ 80 + + used to customize some parameters of the parser, including which
+ 81 + + non-standard JSON extensions should be allowed. A default-constructed parse
+ 82 + + options allows only standard JSON.
+ 83 + +
+ 84 + + @par Thread Safety
+ 85 + + Distinct instances may be accessed concurrently. Non-const member functions
+ 86 + + of a shared instance may not be called concurrently with any other member
+ 87 + + functions of that instance.
+ 88 + +
+ 89 + + @see @ref parse, @ref stream_parser.
+ 90 + + */
+ 91 + + class parser
+ 92 + + {
+ 93 + + basic_parser<detail::handler> p_;
+ 94 + +
+ 95 + + public:
+ 96 + + /** Assignment operator.
+ 97 + +
+ 98 + + This type is neither copyable nor movable. The operator is deleted.
+ 99 + + */
+ 100 + + parser& operator=(
+ 101 + + parser const&) = delete;
+ 102 + +
+ 103 + + /** Destructor.
+ 104 + +
+ 105 + + All dynamically allocated memory, including
+ 106 + + any incomplete parsing results, is freed.
+ 107 + +
+ 108 + + @par Complexity
+ 109 + + Linear in the size of partial results.
+ 110 + +
+ 111 + + @par Exception Safety
+ 112 + + No-throw guarantee.
+ 113 + + */
+ 114 + +2001563 ~parser() = default;
+ 115 + +
+ 116 + + /** Constructors.
+ 117 + +
+ 118 + + Construct a new parser.
+ 119 + +
+ 120 + + The parser will only support standard JSON if overloads **(1)**
+ 121 + + or **(2)** are used. Otherwise the parser will support extensions
+ 122 + + specified by the parameter `opt`.
+ 123 + +
+ 124 + + The parsed value will use the \<\<default_memory_resource,default
+ 125 + + memory resource\>\> for storage. To use a different resource, call @ref
+ 126 + + reset after construction.
+ 127 + +
+ 128 + + The main difference between the overloads is in what the constructed
+ 129 + + parser will use for temporary storage:
+ 130 + +
+ 131 + + @li **(1)** the constructed parser uses the default memory resource for
+ 132 + + temporary storage.
+ 133 + +
+ 134 + + @li **(2)**, **(3)** the constructed parser uses the memory resource of
+ 135 + + `sp` for temporary storage.
+ 136 + +
+ 137 + + @li **(4)**, **(6)** the constructed parser first uses the caller-owned
+ 138 + + storage `[buffer, buffer + size)` for temporary storage, falling back
+ 139 + + to the memory resource of `sp` if needed.
+ 140 + +
+ 141 + + @li **(5)**, **(7)** the constructed parser first uses the caller-owned
+ 142 + + storage `[buffer, buffer + N)` for temporary storage, falling back to
+ 143 + + the memory resource of `sp` if needed.
+ 144 + +
+ 145 + + @note Ownership of `buffer` is not transferred. The caller is
+ 146 + + responsible for ensuring the lifetime of the storage pointed to by
+ 147 + + `buffer` extends until the parser is destroyed.
+ 148 + +
+ 149 + + Overload **(8)** is the copy constructor. The type is neither copyable
+ 150 + + nor movable, so the overload is deleted.
+ 151 + +
+ 152 + + @par Complexity
+ 153 + + Constant.
+ 154 + +
+ 155 + + @par Exception Safety
+ 156 + + No-throw guarantee.
+ 157 + +
+ 158 + + @{
+ 159 + + */
+ 160 + +53 parser() noexcept
+ 161 + +53 : parser({}, {})
+ 162 + + {
+ 163 + +53 }
+ 164 + +
+ 165 + + /** Overload
+ 166 + +
+ 167 + + @param sp The memory resource to use for temporary storage.
+ 168 + + */
+ 169 + + explicit
+ 170 + +1 parser(storage_ptr sp) noexcept
+ 171 + +1 : parser(std::move(sp), {})
+ 172 + + {
+ 173 + +1 }
+ 174 + +
+ 175 + + /** Overload
+ 176 + +
+ 177 + + @param opt The parsing options to use.
+ 178 + + @param sp
+ 179 + + */
+ 180 + + BOOST_JSON_DECL
+ 181 + + parser(
+ 182 + + storage_ptr sp,
+ 183 + + parse_options const& opt) noexcept;
+ 184 + +
+ 185 + + /** Overload
+ 186 + +
+ 187 + + @param buffer A pointer to valid storage.
+ 188 + + @param size The number of valid bytes in `buffer`.
+ 189 + + @param sp
+ 190 + + @param opt
+ 191 + + */
+ 192 + + BOOST_JSON_DECL
+ 193 + + parser(
+ 194 + + storage_ptr sp,
+ 195 + + parse_options const& opt,
+ 196 + + unsigned char* buffer,
+ 197 + + std::size_t size) noexcept;
+ 198 + +
+ 199 + + /** Overload
+ 200 + +
+ 201 + + @tparam N The number of valid bytes in `buffer`.
+ 202 + + @param sp
+ 203 + + @param opt
+ 204 + + @param buffer
+ 205 + + */
+ 206 + + template<std::size_t N>
+ 207 + +2001506 parser(
+ 208 + + storage_ptr sp,
+ 209 + + parse_options const& opt,
+ 210 + + unsigned char(&buffer)[N]) noexcept
+ 211 + +2001506 : parser(std::move(sp),
+ 212 + +2001506 opt, &buffer[0], N)
+ 213 + + {
+ 214 + +2001506 }
+ 215 + +
+ 216 + + #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
+ 217 + + /** Overload
+ 218 + +
+ 219 + + @param buffer
+ 220 + + @param size
+ 221 + + @param sp
+ 222 + + @param opt
+ 223 + + */
+ 224 + + parser(
+ 225 + + storage_ptr sp,
+ 226 + + parse_options const& opt,
+ 227 + + std::byte* buffer,
+ 228 + + std::size_t size) noexcept
+ 229 + + : parser(sp, opt, reinterpret_cast<
+ 230 + + unsigned char*>(buffer), size)
+ 231 + + {
+ 232 + + }
+ 233 + +
+ 234 + + /** Overload
+ 235 + +
+ 236 + + @tparam N
+ 237 + + @param sp
+ 238 + + @param opt
+ 239 + + @param buffer
+ 240 + + */
+ 241 + + template<std::size_t N>
+ 242 + + parser(
+ 243 + + storage_ptr sp,
+ 244 + + parse_options const& opt,
+ 245 + + std::byte(&buffer)[N]) noexcept
+ 246 + + : parser(std::move(sp),
+ 247 + + opt, &buffer[0], N)
+ 248 + + {
+ 249 + + }
+ 250 + + #endif
+ 251 + +
+ 252 + + #ifndef BOOST_JSON_DOCS
+ 253 + + // Safety net for accidental buffer overflows
+ 254 + + template<std::size_t N>
+ 255 + + parser(
+ 256 + + storage_ptr sp,
+ 257 + + parse_options const& opt,
+ 258 + + unsigned char(&buffer)[N],
+ 259 + + std::size_t n) noexcept
+ 260 + + : parser(std::move(sp),
+ 261 + + opt, &buffer[0], n)
+ 262 + + {
+ 263 + + // If this goes off, check your parameters
+ 264 + + // closely, chances are you passed an array
+ 265 + + // thinking it was a pointer.
+ 266 + + BOOST_ASSERT(n <= N);
+ 267 + + }
+ 268 + +
+ 269 + + #ifdef __cpp_lib_byte
+ 270 + + // Safety net for accidental buffer overflows
+ 271 + + template<std::size_t N>
+ 272 + + parser(
+ 273 + + storage_ptr sp,
+ 274 + + parse_options const& opt,
+ 275 + + std::byte(&buffer)[N], std::size_t n) noexcept
+ 276 + + : parser(std::move(sp),
+ 277 + + opt, &buffer[0], n)
+ 278 + + {
+ 279 + + // If this goes off, check your parameters
+ 280 + + // closely, chances are you passed an array
+ 281 + + // thinking it was a pointer.
+ 282 + + BOOST_ASSERT(n <= N);
+ 283 + + }
+ 284 + + #endif
+ 285 + + #endif
+ 286 + +
+ 287 + + /// Overload
+ 288 + + parser(
+ 289 + + parser const&) = delete;
+ 290 + + /// @}
+ 291 + +
+ 292 + +
+ 293 + + /** Reset the parser for a new JSON text.
+ 294 + +
+ 295 + + This function is used to reset the parser to
+ 296 + + prepare it for parsing a new complete JSON text.
+ 297 + + Any previous partial results are destroyed.
+ 298 + +
+ 299 + + @par Complexity
+ 300 + + Constant or linear in the size of any previous
+ 301 + + partial parsing results.
+ 302 + +
+ 303 + + @par Exception Safety
+ 304 + + No-throw guarantee.
+ 305 + +
+ 306 + + @param sp A pointer to the @ref boost::container::pmr::memory_resource
+ 307 + + to use for the resulting @ref value. The parser will acquire shared
+ 308 + + ownership.
+ 309 + + */
+ 310 + + BOOST_JSON_DECL
+ 311 + + void
+ 312 + + reset(storage_ptr sp = {}) noexcept;
+ 313 + +
+ 314 + + /** Parse a buffer containing a complete JSON text.
+ 315 + +
+ 316 + + This function parses a complete JSON text contained in the specified
+ 317 + + character buffer. Additional characters past the end of the complete
+ 318 + + JSON text are ignored. The function returns the actual number of
+ 319 + + characters parsed, which may be less than the size of the input. This
+ 320 + + allows parsing of a buffer containing multiple individual JSON texts or
+ 321 + + containing different protocol data:
+ 322 + +
+ 323 + + @par Example
+ 324 + + @code
+ 325 + + parser p; // construct a parser
+ 326 + + size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON text
+ 327 + + assert( n == 8 ); // only some characters consumed
+ 328 + + value jv = p.release(); // take ownership of the value
+ 329 + + @endcode
+ 330 + +
+ 331 + + Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
+ 332 + + setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
+ 333 + + exceptions.
+ 334 + +
+ 335 + + @par Complexity
+ 336 + + @li **(1)**--**(3)** linear in `size`.
+ 337 + + @li **(4)**--**(6)** linear in `s.size()`.
+ 338 + +
+ 339 + + @par Exception Safety
+ 340 + + Basic guarantee. Calls to `memory_resource::allocate` may throw. Upon
+ 341 + + error or exception, subsequent calls will fail until @ref reset is
+ 342 + + called to parse a new JSON text.
+ 343 + +
+ 344 + + @return The number of characters consumed from the buffer.
+ 345 + +
+ 346 + + @param data A pointer to a buffer of `size` characters to parse.
+ 347 + + @param size The number of characters pointed to by `data`.
+ 348 + + @param ec Set to the error, if any occurred.
+ 349 + +
+ 350 + + @{
+ 351 + + */
+ 352 + + BOOST_JSON_DECL
+ 353 + + std::size_t
+ 354 + + write_some(
+ 355 + + char const* data,
+ 356 + + std::size_t size,
+ 357 + + system::error_code& ec);
+ 358 + +
+ 359 + + BOOST_JSON_DECL
+ 360 + + std::size_t
+ 361 + + write_some(
+ 362 + + char const* data,
+ 363 + + std::size_t size,
+ 364 + + std::error_code& ec);
+ 365 + +
+ 366 + + /** Overload
+ 367 + +
+ 368 + + @param data
+ 369 + + @param size
+ 370 + + */
+ 371 + + BOOST_JSON_DECL
+ 372 + + std::size_t
+ 373 + + write_some(
+ 374 + + char const* data,
+ 375 + + std::size_t size);
+ 376 + +
+ 377 + + /** Overload
+ 378 + +
+ 379 + + @param s The character string to parse.
+ 380 + + @param ec
+ 381 + + */
+ 382 + + std::size_t
+ 383 + +2 write_some(
+ 384 + + string_view s,
+ 385 + + system::error_code& ec)
+ 386 + + {
+ 387 + +2 return write_some(
+ 388 + +2 s.data(), s.size(), ec);
+ 389 + + }
+ 390 + +
+ 391 + + /** Overload
+ 392 + +
+ 393 + + @param s
+ 394 + + @param ec
+ 395 + + */
+ 396 + + std::size_t
+ 397 + +2 write_some(
+ 398 + + string_view s,
+ 399 + + std::error_code& ec)
+ 400 + + {
+ 401 + +2 return write_some(
+ 402 + +2 s.data(), s.size(), ec);
+ 403 + + }
+ 404 + +
+ 405 + + /** Overload
+ 406 + +
+ 407 + + @param s
+ 408 + + */
+ 409 + + std::size_t
+ 410 + +4 write_some(
+ 411 + + string_view s)
+ 412 + + {
+ 413 + +4 return write_some(
+ 414 + +2 s.data(), s.size());
+ 415 + + }
+ 416 + + /// @}
+ 417 + +
+ 418 + + /** Parse a buffer containing a complete JSON text.
+ 419 + +
+ 420 + + This function parses a complete JSON text contained in the specified
+ 421 + + character buffer. The entire buffer must be consumed; if there are
+ 422 + + additional characters past the end of the complete JSON text, the parse
+ 423 + + fails and an error is returned.
+ 424 + +
+ 425 + + @par Example
+ 426 + + @code
+ 427 + + parser p; // construct a parser
+ 428 + + size_t n = p.write( "[1,2,3]" ); // parse a complete JSON text
+ 429 + + assert( n == 7 ); // all characters consumed
+ 430 + + value jv = p.release(); // take ownership of the value
+ 431 + + @endcode
+ 432 + +
+ 433 + + Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
+ 434 + + setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
+ 435 + + exceptions.
+ 436 + +
+ 437 + + @par Complexity
+ 438 + + @li **(1)**--**(3)** linear in `size`.
+ 439 + + @li **(4)**--**(6)** linear in `s.size()`.
+ 440 + +
+ 441 + + @par Exception Safety
+ 442 + + Basic guarantee. Calls to `memory_resource::allocate` may throw. Upon
+ 443 + + error or exception, subsequent calls will fail until @ref reset is
+ 444 + + called to parse a new JSON text.
+ 445 + +
+ 446 + + @return The number of characters consumed from the buffer.
+ 447 + +
+ 448 + + @param data A pointer to a buffer of `size` characters to parse.
+ 449 + + @param size The number of characters pointed to by `data`.
+ 450 + + @param ec Set to the error, if any occurred.
+ 451 + +
+ 452 + + @{
+ 453 + + */
+ 454 + + BOOST_JSON_DECL
+ 455 + + std::size_t
+ 456 + + write(
+ 457 + + char const* data,
+ 458 + + std::size_t size,
+ 459 + + system::error_code& ec);
+ 460 + +
+ 461 + + BOOST_JSON_DECL
+ 462 + + std::size_t
+ 463 + + write(
+ 464 + + char const* data,
+ 465 + + std::size_t size,
+ 466 + + std::error_code& ec);
+ 467 + +
+ 468 + + /** Overload
+ 469 + +
+ 470 + + @throw `boost::system::system_error` Thrown on error.
+ 471 + + */
+ 472 + + BOOST_JSON_DECL
+ 473 + + std::size_t
+ 474 + + write(
+ 475 + + char const* data,
+ 476 + + std::size_t size);
+ 477 + +
+ 478 + + /** Overload
+ 479 + +
+ 480 + + @param s The character string to parse.
+ 481 + + @param ec
+ 482 + + */
+ 483 + + std::size_t
+ 484 + +2001508 write(
+ 485 + + string_view s,
+ 486 + + system::error_code& ec)
+ 487 + + {
+ 488 + +2001508 return write(
+ 489 + +2001507 s.data(), s.size(), ec);
+ 490 + + }
+ 491 + +
+ 492 + + /** Overload
+ 493 + +
+ 494 + + @param s
+ 495 + + @param ec
+ 496 + + */
+ 497 + + std::size_t
+ 498 + +3 write(
+ 499 + + string_view s,
+ 500 + + std::error_code& ec)
+ 501 + + {
+ 502 + +3 return write(
+ 503 + +3 s.data(), s.size(), ec);
+ 504 + + }
+ 505 + +
+ 506 + + /** Overload
+ 507 + +
+ 508 + + @param s
+ 509 + + */
+ 510 + + std::size_t
+ 511 + +8 write(
+ 512 + + string_view s)
+ 513 + + {
+ 514 + +8 return write(
+ 515 + +4 s.data(), s.size());
+ 516 + + }
+ 517 + + /// @}
+ 518 + +
+ 519 + + /** Return the parsed JSON text as a @ref value.
+ 520 + +
+ 521 + + This returns the parsed value, or throws an exception if the parsing is
+ 522 + + incomplete or failed. It is necessary to call @ref reset after calling
+ 523 + + this function in order to parse another JSON text.
+ 524 + +
+ 525 + + @par Complexity
+ 526 + + Constant.
+ 527 + +
+ 528 + + @return The parsed value. Ownership of this value is transferred to the
+ 529 + + caller.
+ 530 + +
+ 531 + + @throw boost::system::system_error A complete JSON text hasn't been
+ 532 + + parsed, or parsing failed.
+ 533 + + */
+ 534 + + BOOST_JSON_DECL
+ 535 + + value
+ 536 + + release();
+ 537 + + };
+ 538 + +
+ 539 + + } // namespace json
+ 540 + + } // namespace boost
+ 541 + +
+ 542 + + #endif
+ 543 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.parser.ipp.266f2bed4bd28788f0addeb11aa58a0d.html b/json/gcovr/index.parser.ipp.266f2bed4bd28788f0addeb11aa58a0d.html new file mode 100644 index 00000000..7ae92a30 --- /dev/null +++ b/json/gcovr/index.parser.ipp.266f2bed4bd28788f0addeb11aa58a0d.html @@ -0,0 +1,3430 @@ + + + + + + impl/parser.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/parser.ipp

+
+ + 100.0% Lines (59/59) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/parser.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_PARSER_IPP
+ 11 + + #define BOOST_JSON_IMPL_PARSER_IPP
+ 12 + +
+ 13 + + #include <boost/json/parser.hpp>
+ 14 + + #include <boost/json/basic_parser_impl.hpp>
+ 15 + + #include <boost/json/error.hpp>
+ 16 + + #include <cstring>
+ 17 + + #include <stdexcept>
+ 18 + + #include <utility>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + +
+ 23 + +2001508 parser::
+ 24 + + parser(
+ 25 + + storage_ptr sp,
+ 26 + + parse_options const& opt,
+ 27 + + unsigned char* buffer,
+ 28 + +2001508 std::size_t size) noexcept
+ 29 + +2001508 : p_(
+ 30 + + opt,
+ 31 + +2001508 std::move(sp),
+ 32 + + buffer,
+ 33 + + size)
+ 34 + + {
+ 35 + +2001508 reset();
+ 36 + +2001508 }
+ 37 + +
+ 38 + +55 parser::
+ 39 + + parser(
+ 40 + + storage_ptr sp,
+ 41 + +55 parse_options const& opt) noexcept
+ 42 + +55 : p_(
+ 43 + + opt,
+ 44 + +55 std::move(sp),
+ 45 + +110 nullptr,
+ 46 + +55 0)
+ 47 + + {
+ 48 + +55 reset();
+ 49 + +55 }
+ 50 + +
+ 51 + + void
+ 52 + +4003070 parser::
+ 53 + + reset(storage_ptr sp) noexcept
+ 54 + + {
+ 55 + +4003070 p_.reset();
+ 56 + +4003070 p_.handler().st.reset(sp);
+ 57 + +4003070 }
+ 58 + +
+ 59 + + std::size_t
+ 60 + +2001553 parser::
+ 61 + + write_some(
+ 62 + + char const* data,
+ 63 + + std::size_t size,
+ 64 + + system::error_code& ec)
+ 65 + + {
+ 66 + +2001553 auto const n = p_.write_some(
+ 67 + + false, data, size, ec);
+ 68 + +2001552 BOOST_ASSERT(ec || p_.done());
+ 69 + +2001552 return n;
+ 70 + + }
+ 71 + +
+ 72 + + std::size_t
+ 73 + +6 parser::
+ 74 + + write_some(
+ 75 + + char const* data,
+ 76 + + std::size_t size,
+ 77 + + std::error_code& ec)
+ 78 + + {
+ 79 + +6 system::error_code jec;
+ 80 + +6 std::size_t const result = write_some(data, size, jec);
+ 81 + +6 ec = jec;
+ 82 + +6 return result;
+ 83 + + }
+ 84 + +
+ 85 + + std::size_t
+ 86 + +8 parser::
+ 87 + + write_some(
+ 88 + + char const* data,
+ 89 + + std::size_t size)
+ 90 + + {
+ 91 + +8 system::error_code ec;
+ 92 + +8 auto const n = write_some(
+ 93 + + data, size, ec);
+ 94 + +8 if(ec)
+ 95 + +4 detail::throw_system_error( ec );
+ 96 + +4 return n;
+ 97 + + }
+ 98 + +
+ 99 + + std::size_t
+ 100 + +2001533 parser::
+ 101 + + write(
+ 102 + + char const* data,
+ 103 + + std::size_t size,
+ 104 + + system::error_code& ec)
+ 105 + + {
+ 106 + +2001533 auto const n = write_some(
+ 107 + + data, size, ec);
+ 108 + +2001532 if(! ec && n < size)
+ 109 + + {
+ 110 + +8 BOOST_JSON_FAIL(ec, error::extra_data);
+ 111 + +8 p_.fail(ec);
+ 112 + + }
+ 113 + +2001532 return n;
+ 114 + + }
+ 115 + +
+ 116 + + std::size_t
+ 117 + +7 parser::
+ 118 + + write(
+ 119 + + char const* data,
+ 120 + + std::size_t size,
+ 121 + + std::error_code& ec)
+ 122 + + {
+ 123 + +7 system::error_code jec;
+ 124 + +7 std::size_t const result = write(data, size, jec);
+ 125 + +7 ec = jec;
+ 126 + +7 return result;
+ 127 + + }
+ 128 + +
+ 129 + + std::size_t
+ 130 + +14 parser::
+ 131 + + write(
+ 132 + + char const* data,
+ 133 + + std::size_t size)
+ 134 + + {
+ 135 + +14 system::error_code ec;
+ 136 + +14 auto const n = write(
+ 137 + + data, size, ec);
+ 138 + +14 if(ec)
+ 139 + +8 detail::throw_system_error( ec );
+ 140 + +6 return n;
+ 141 + + }
+ 142 + +
+ 143 + + value
+ 144 + +2001495 parser::
+ 145 + + release()
+ 146 + + {
+ 147 + +2001495 if( ! p_.done())
+ 148 + + {
+ 149 + + // prevent undefined behavior
+ 150 + +4 if(! p_.last_error())
+ 151 + + {
+ 152 + +2 system::error_code ec;
+ 153 + +2 BOOST_JSON_FAIL(ec, error::incomplete);
+ 154 + +2 p_.fail(ec);
+ 155 + + }
+ 156 + +8 detail::throw_system_error(
+ 157 + +8 p_.last_error());
+ 158 + + }
+ 159 + +2001491 return p_.handler().st.release();
+ 160 + + }
+ 161 + +
+ 162 + + } // namespace json
+ 163 + + } // namespace boost
+ 164 + +
+ 165 + + #endif
+ 166 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.pilfer.hpp.4dd6b487af20fd66fc07f525c990eb8b.html b/json/gcovr/index.pilfer.hpp.4dd6b487af20fd66fc07f525c990eb8b.html new file mode 100644 index 00000000..c0e7e88c --- /dev/null +++ b/json/gcovr/index.pilfer.hpp.4dd6b487af20fd66fc07f525c990eb8b.html @@ -0,0 +1,3838 @@ + + + + + + pilfer.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

pilfer.hpp

+
+ + 100.0% Lines (7/7) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
pilfer.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_PILFER_HPP
+ 11 + + #define BOOST_JSON_PILFER_HPP
+ 12 + +
+ 13 + + #include <boost/core/detail/static_assert.hpp>
+ 14 + + #include <boost/json/detail/config.hpp>
+ 15 + + #include <type_traits>
+ 16 + + #include <utility>
+ 17 + +
+ 18 + + /*
+ 19 + + Implements "pilfering" from P0308R0
+ 20 + +
+ 21 + + @see
+ 22 + + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html
+ 23 + + */
+ 24 + +
+ 25 + + namespace boost {
+ 26 + + namespace json {
+ 27 + +
+ 28 + + /** Tag wrapper to specify pilfer-construction.
+ 29 + +
+ 30 + + This wrapper is used to specify a pilfer constructor
+ 31 + + overload.
+ 32 + +
+ 33 + + @par Example
+ 34 + +
+ 35 + + A pilfer constructor accepts a single argument
+ 36 + + of type @ref pilfered and throws nothing:
+ 37 + +
+ 38 + + @code
+ 39 + + struct T
+ 40 + + {
+ 41 + + T( pilfered<T> ) noexcept;
+ 42 + + };
+ 43 + + @endcode
+ 44 + +
+ 45 + + @note
+ 46 + +
+ 47 + + The constructor should not be marked explicit.
+ 48 + +
+ 49 + + @see @ref pilfer, @ref is_pilfer_constructible,
+ 50 + + <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
+ 51 + + Valueless Variants Considered Harmful</a>
+ 52 + + */
+ 53 + + template<class T>
+ 54 + + class pilfered
+ 55 + + {
+ 56 + + T& t_;
+ 57 + +
+ 58 + + public:
+ 59 + + /** Constructor
+ 60 + +
+ 61 + + Construct the wrapper from `t`.
+ 62 + +
+ 63 + + @param t The pilferable object. Ownership
+ 64 + + is not transferred.
+ 65 + + */
+ 66 + + explicit
+ 67 + + constexpr
+ 68 + +2174071 pilfered(T&& t) noexcept
+ 69 + +2174071 : t_(t)
+ 70 + + {
+ 71 + +2174071 }
+ 72 + +
+ 73 + + /** Return a reference to the pilferable object.
+ 74 + +
+ 75 + + This returns a reference to the wrapped object.
+ 76 + + */
+ 77 + + constexpr T&
+ 78 + +4316710 get() const noexcept
+ 79 + + {
+ 80 + +4316710 return t_;
+ 81 + + }
+ 82 + +
+ 83 + + /** Return a pointer to the pilferable object.
+ 84 + +
+ 85 + + This returns a pointer to the wrapped object.
+ 86 + + */
+ 87 + + constexpr T*
+ 88 + + operator->() const noexcept
+ 89 + + {
+ 90 + + //return std::addressof(t_);
+ 91 + + return reinterpret_cast<T*>(
+ 92 + + const_cast<char *>(
+ 93 + + &reinterpret_cast<
+ 94 + + const volatile char &>(t_)));
+ 95 + + }
+ 96 + + };
+ 97 + +
+ 98 + + #ifndef BOOST_JSON_DOCS
+ 99 + + // VFALCO Renamed this to work around an msvc bug
+ 100 + + namespace detail_pilfer {
+ 101 + + template<class>
+ 102 + + struct not_pilfered
+ 103 + + {
+ 104 + + };
+ 105 + + } // detail_pilfer
+ 106 + + #endif
+ 107 + +
+ 108 + + /** Metafunction returning `true` if `T` is <em>PilferConstructible</em>
+ 109 + +
+ 110 + + If `T` can be pilfer constructed, this metafunction is
+ 111 + + equal to `std::true_type`. Otherwise it is equal to
+ 112 + + `std::false_type`.
+ 113 + +
+ 114 + + @see @ref pilfer, @ref pilfered,
+ 115 + + <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
+ 116 + + Valueless Variants Considered Harmful</a>
+ 117 + + */
+ 118 + + template<class T>
+ 119 + + struct is_pilfer_constructible
+ 120 + + #ifndef BOOST_JSON_DOCS
+ 121 + + : std::integral_constant<bool,
+ 122 + + std::is_nothrow_move_constructible<T>::value ||
+ 123 + + (
+ 124 + + std::is_nothrow_constructible<
+ 125 + + T, pilfered<T> >::value &&
+ 126 + + ! std::is_nothrow_constructible<
+ 127 + + T, detail_pilfer::not_pilfered<T> >::value
+ 128 + + )>
+ 129 + + #endif
+ 130 + + {
+ 131 + + };
+ 132 + +
+ 133 + + /** Indicate that an object `t` may be pilfered from.
+ 134 + +
+ 135 + + A <em>pilfer</em> operation is the construction
+ 136 + + of a new object of type `T` from an existing
+ 137 + + object `t`. After the construction, the only
+ 138 + + valid operation on the pilfered-from object is
+ 139 + + destruction. This permits optimizations beyond
+ 140 + + those available for a move-construction, as the
+ 141 + + pilfered-from object is not required to be in
+ 142 + + a "usable" state.
+ 143 + + \n
+ 144 + + This is used similarly to `std::move`.
+ 145 + +
+ 146 + + @par Example
+ 147 + +
+ 148 + + A pilfer constructor accepts a single argument
+ 149 + + of type @ref pilfered and throws nothing:
+ 150 + +
+ 151 + + @code
+ 152 + + struct T
+ 153 + + {
+ 154 + + T( pilfered<T> ) noexcept;
+ 155 + + };
+ 156 + + @endcode
+ 157 + +
+ 158 + + Pilfer construction is performed using @ref pilfer :
+ 159 + +
+ 160 + + @code
+ 161 + + {
+ 162 + + T t1; // default construction
+ 163 + + T t2( pilfer( t1 ) ); // pilfer-construct from t1
+ 164 + +
+ 165 + + // At this point, t1 may only be destroyed
+ 166 + + }
+ 167 + + @endcode
+ 168 + +
+ 169 + + @see @ref pilfered, @ref is_pilfer_constructible,
+ 170 + + <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
+ 171 + + Valueless Variants Considered Harmful</a>
+ 172 + + */
+ 173 + + template<class T>
+ 174 + + auto
+ 175 + +6327199 pilfer(T&& t) noexcept ->
+ 176 + + typename std::conditional<
+ 177 + + std::is_nothrow_constructible<
+ 178 + + typename std::remove_reference<T>::type,
+ 179 + + pilfered<typename
+ 180 + + std::remove_reference<T>::type> >::value &&
+ 181 + + ! std::is_nothrow_constructible<
+ 182 + + typename std::remove_reference<T>::type,
+ 183 + + detail_pilfer::not_pilfered<typename
+ 184 + + std::remove_reference<T>::type> >::value,
+ 185 + + pilfered<typename std::remove_reference<T>::type>,
+ 186 + + typename std::remove_reference<T>::type&&
+ 187 + + >::type
+ 188 + + {
+ 189 + + using U =
+ 190 + + typename std::remove_reference<T>::type;
+ 191 + + BOOST_CORE_STATIC_ASSERT( is_pilfer_constructible<U>::value );
+ 192 + + return typename std::conditional<
+ 193 + + std::is_nothrow_constructible<
+ 194 + + U, pilfered<U> >::value &&
+ 195 + + ! std::is_nothrow_constructible<
+ 196 + + U, detail_pilfer::not_pilfered<U> >::value,
+ 197 + + pilfered<U>, U&&
+ 198 + +6327199 >::type(std::move(t));
+ 199 + + }
+ 200 + +
+ 201 + + /*
+ 202 + + template<class T>
+ 203 + + void
+ 204 + + relocate(T* dest, T& src) noexcept
+ 205 + + {
+ 206 + + BOOST_CORE_STATIC_ASSERT( is_pilfer_constructible<T>::value );
+ 207 + + ::new(dest) T(pilfer(src));
+ 208 + + src.~T();
+ 209 + + }
+ 210 + + */
+ 211 + +
+ 212 + + } // json
+ 213 + + } // boost
+ 214 + +
+ 215 + +
+ 216 + + #endif
+ 217 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.pointer.ipp.29ac44758c62ce39e625bbc7f1409991.html b/json/gcovr/index.pointer.ipp.29ac44758c62ce39e625bbc7f1409991.html new file mode 100644 index 00000000..0dcb5616 --- /dev/null +++ b/json/gcovr/index.pointer.ipp.29ac44758c62ce39e625bbc7f1409991.html @@ -0,0 +1,6318 @@ + + + + + + impl/pointer.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/pointer.ipp

+
+ + 100.0% Lines (244/244) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/pointer.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_POINTER_IPP
+ 11 + + #define BOOST_JSON_IMPL_POINTER_IPP
+ 12 + +
+ 13 + + #include <boost/json/value.hpp>
+ 14 + +
+ 15 + + namespace boost {
+ 16 + + namespace json {
+ 17 + +
+ 18 + + namespace detail {
+ 19 + +
+ 20 + + class pointer_token
+ 21 + + {
+ 22 + + public:
+ 23 + + class iterator;
+ 24 + +
+ 25 + +158 pointer_token(
+ 26 + + string_view sv) noexcept
+ 27 + +158 : b_( sv.begin() + 1 )
+ 28 + +158 , e_( sv.end() )
+ 29 + + {
+ 30 + +158 BOOST_ASSERT( !sv.empty() );
+ 31 + +158 BOOST_ASSERT( *sv.data() == '/' );
+ 32 + +158 }
+ 33 + +
+ 34 + + iterator begin() const noexcept;
+ 35 + + iterator end() const noexcept;
+ 36 + +
+ 37 + + private:
+ 38 + + char const* b_;
+ 39 + + char const* e_;
+ 40 + + };
+ 41 + +
+ 42 + + class pointer_token::iterator
+ 43 + + {
+ 44 + + public:
+ 45 + + using value_type = char;
+ 46 + + using reference = char;
+ 47 + + using pointer = value_type*;
+ 48 + + using difference_type = std::ptrdiff_t;
+ 49 + + using iterator_category = std::forward_iterator_tag;
+ 50 + +
+ 51 + +576 explicit iterator(char const* base) noexcept
+ 52 + +576 : base_(base)
+ 53 + + {
+ 54 + +576 }
+ 55 + +
+ 56 + +625 char operator*() const noexcept
+ 57 + + {
+ 58 + +625 switch( char c = *base_ )
+ 59 + + {
+ 60 + +2 case '~':
+ 61 + +2 c = base_[1];
+ 62 + +2 if( '0' == c )
+ 63 + +1 return '~';
+ 64 + +1 BOOST_ASSERT('1' == c);
+ 65 + +1 return '/';
+ 66 + +623 default:
+ 67 + +623 return c;
+ 68 + + }
+ 69 + + }
+ 70 + +
+ 71 + +827 iterator& operator++() noexcept
+ 72 + + {
+ 73 + +827 if( '~' == *base_ )
+ 74 + +2 base_ += 2;
+ 75 + + else
+ 76 + +825 ++base_;
+ 77 + +827 return *this;
+ 78 + + }
+ 79 + +
+ 80 + +29 iterator operator++(int) noexcept
+ 81 + + {
+ 82 + +29 iterator result = *this;
+ 83 + +29 ++(*this);
+ 84 + +29 return result;
+ 85 + + }
+ 86 + +
+ 87 + +1678 char const* base() const noexcept
+ 88 + + {
+ 89 + +1678 return base_;
+ 90 + + }
+ 91 + +
+ 92 + + private:
+ 93 + + char const* base_;
+ 94 + + };
+ 95 + +
+ 96 + +619 bool operator==(pointer_token::iterator l, pointer_token::iterator r) noexcept
+ 97 + + {
+ 98 + +619 return l.base() == r.base();
+ 99 + + }
+ 100 + +
+ 101 + +220 bool operator!=(pointer_token::iterator l, pointer_token::iterator r) noexcept
+ 102 + + {
+ 103 + +220 return l.base() != r.base();
+ 104 + + }
+ 105 + +
+ 106 + +288 pointer_token::iterator pointer_token::begin() const noexcept
+ 107 + + {
+ 108 + +288 return iterator(b_);
+ 109 + + }
+ 110 + +
+ 111 + +288 pointer_token::iterator pointer_token::end() const noexcept
+ 112 + + {
+ 113 + +288 return iterator(e_);
+ 114 + + }
+ 115 + +
+ 116 + +249 bool operator==(pointer_token token, string_view sv) noexcept
+ 117 + + {
+ 118 + +249 auto t_b = token.begin();
+ 119 + +249 auto const t_e = token.end();
+ 120 + +249 auto s_b = sv.begin();
+ 121 + +249 auto const s_e = sv.end();
+ 122 + +619 while( s_b != s_e )
+ 123 + + {
+ 124 + +474 if( t_e == t_b )
+ 125 + +4 return false;
+ 126 + +470 if( *t_b != *s_b )
+ 127 + +100 return false;
+ 128 + +370 ++t_b;
+ 129 + +370 ++s_b;
+ 130 + + }
+ 131 + +145 return t_b == t_e;
+ 132 + + }
+ 133 + +
+ 134 + +72 bool is_invalid_zero(
+ 135 + + char const* b,
+ 136 + + char const* e) noexcept
+ 137 + + {
+ 138 + + // in JSON Pointer only zero index can start character '0'
+ 139 + +72 if( *b != '0' )
+ 140 + +56 return false;
+ 141 + +
+ 142 + + // if an index token starts with '0', then it should not have any more
+ 143 + + // characters: either the string should end, or new token should start
+ 144 + +16 ++b;
+ 145 + +16 if( b == e )
+ 146 + +13 return false;
+ 147 + +
+ 148 + +3 BOOST_ASSERT( *b != '/' );
+ 149 + +3 return true;
+ 150 + + }
+ 151 + +
+ 152 + +69 bool is_past_the_end_token(
+ 153 + + char const* b,
+ 154 + + char const* e) noexcept
+ 155 + + {
+ 156 + +69 if( *b != '-' )
+ 157 + +57 return false;
+ 158 + +
+ 159 + +12 ++b;
+ 160 + +12 BOOST_ASSERT( (b == e) || (*b != '/') );
+ 161 + +12 return b == e;
+ 162 + + }
+ 163 + +
+ 164 + + std::size_t
+ 165 + +75 parse_number_token(
+ 166 + + string_view sv,
+ 167 + + system::error_code& ec) noexcept
+ 168 + + {
+ 169 + +75 BOOST_ASSERT( !sv.empty() );
+ 170 + +
+ 171 + +75 char const* b = sv.begin();
+ 172 + +75 BOOST_ASSERT( *b == '/' );
+ 173 + +
+ 174 + +75 ++b;
+ 175 + +75 char const* const e = sv.end();
+ 176 + +75 if( ( b == e )
+ 177 + +75 || is_invalid_zero(b, e) )
+ 178 + + {
+ 179 + +6 BOOST_JSON_FAIL(ec, error::token_not_number);
+ 180 + +6 return {};
+ 181 + + }
+ 182 + +
+ 183 + +69 if( is_past_the_end_token(b, e) )
+ 184 + + {
+ 185 + +10 ++b;
+ 186 + +10 BOOST_JSON_FAIL(ec, error::past_the_end);
+ 187 + +10 return {};
+ 188 + + }
+ 189 + +
+ 190 + +59 std::size_t result = 0;
+ 191 + +133 for( ; b != e; ++b )
+ 192 + + {
+ 193 + +104 char const c = *b;
+ 194 + +104 BOOST_ASSERT( c != '/' );
+ 195 + +
+ 196 + +104 unsigned d = c - '0';
+ 197 + +104 if( d > 9 )
+ 198 + + {
+ 199 + +28 BOOST_JSON_FAIL(ec, error::token_not_number);
+ 200 + +28 return {};
+ 201 + + }
+ 202 + +
+ 203 + +76 std::size_t new_result = result * 10 + d;
+ 204 + +76 if( new_result < result )
+ 205 + + {
+ 206 + +2 BOOST_JSON_FAIL(ec, error::token_overflow);
+ 207 + +2 return {};
+ 208 + + }
+ 209 + +
+ 210 + +74 result = new_result;
+ 211 + +
+ 212 + + }
+ 213 + +29 return result;
+ 214 + + }
+ 215 + +
+ 216 + + string_view
+ 217 + +344 next_segment(
+ 218 + + string_view& sv,
+ 219 + + system::error_code& ec) noexcept
+ 220 + + {
+ 221 + +344 if( sv.empty() )
+ 222 + +108 return sv;
+ 223 + +
+ 224 + +236 char const* const start = sv.begin();
+ 225 + +236 char const* b = start;
+ 226 + +236 if( *b++ != '/' )
+ 227 + + {
+ 228 + +5 BOOST_JSON_FAIL( ec, error::missing_slash );
+ 229 + +5 return {};
+ 230 + + }
+ 231 + +
+ 232 + +231 char const* e = sv.end();
+ 233 + +768 for( ; b < e; ++b )
+ 234 + + {
+ 235 + +655 char const c = *b;
+ 236 + +655 if( '/' == c )
+ 237 + +112 break;
+ 238 + +
+ 239 + +543 if( '~' == c )
+ 240 + + {
+ 241 + +8 if( ++b == e )
+ 242 + + {
+ 243 + +3 BOOST_JSON_FAIL( ec, error::invalid_escape );
+ 244 + +3 break;
+ 245 + + }
+ 246 + +
+ 247 + +5 switch (*b)
+ 248 + + {
+ 249 + +2 case '0': // fall through
+ 250 + + case '1':
+ 251 + + // valid escape sequence
+ 252 + +2 continue;
+ 253 + +3 default: {
+ 254 + +3 BOOST_JSON_FAIL( ec, error::invalid_escape );
+ 255 + +3 break;
+ 256 + + }
+ 257 + +2 }
+ 258 + +3 break;
+ 259 + + }
+ 260 + + }
+ 261 + +
+ 262 + +231 sv.remove_prefix( b - start );
+ 263 + +231 return string_view( start, b );
+ 264 + + }
+ 265 + +
+ 266 + + value*
+ 267 + +125 if_contains_token(object const& obj, pointer_token token)
+ 268 + + {
+ 269 + +125 if( obj.empty() )
+ 270 + +2 return nullptr;
+ 271 + +
+ 272 + +123 auto const it = detail::find_in_object(obj, token).first;
+ 273 + +123 if( !it )
+ 274 + +5 return nullptr;
+ 275 + +
+ 276 + +118 return &it->value();
+ 277 + + }
+ 278 + +
+ 279 + + template<
+ 280 + + class Value,
+ 281 + + class OnObject,
+ 282 + + class OnArray,
+ 283 + + class OnScalar >
+ 284 + + Value*
+ 285 + +129 walk_pointer(
+ 286 + + Value& jv,
+ 287 + + string_view sv,
+ 288 + + system::error_code& ec,
+ 289 + + OnObject on_object,
+ 290 + + OnArray on_array,
+ 291 + + OnScalar on_scalar)
+ 292 + + {
+ 293 + +129 ec.clear();
+ 294 + +
+ 295 + +129 string_view segment = detail::next_segment( sv, ec );
+ 296 + +
+ 297 + +129 Value* result = &jv;
+ 298 + +244 while( true )
+ 299 + + {
+ 300 + +373 if( ec.failed() )
+ 301 + +43 return nullptr;
+ 302 + +
+ 303 + +330 if( !result )
+ 304 + + {
+ 305 + +12 BOOST_JSON_FAIL(ec, error::not_found);
+ 306 + +12 return nullptr;
+ 307 + + }
+ 308 + +
+ 309 + +318 if( segment.empty() )
+ 310 + +74 break;
+ 311 + +
+ 312 + +244 switch( result->kind() )
+ 313 + + {
+ 314 + +158 case kind::object: {
+ 315 + +158 auto& obj = result->get_object();
+ 316 + +
+ 317 + +158 detail::pointer_token const token( segment );
+ 318 + +158 segment = detail::next_segment( sv, ec );
+ 319 + +
+ 320 + +158 result = on_object( obj, token );
+ 321 + +158 break;
+ 322 + + }
+ 323 + +57 case kind::array: {
+ 324 + +57 auto const index = detail::parse_number_token( segment, ec );
+ 325 + +57 segment = detail::next_segment( sv, ec );
+ 326 + +
+ 327 + +57 auto& arr = result->get_array();
+ 328 + +57 result = on_array( arr, index, ec );
+ 329 + +57 break;
+ 330 + + }
+ 331 + +29 default: {
+ 332 + +29 if( on_scalar( *result, segment ) )
+ 333 + +21 break;
+ 334 + +8 BOOST_JSON_FAIL( ec, error::value_is_scalar );
+ 335 + + }}
+ 336 + + }
+ 337 + +
+ 338 + +74 BOOST_ASSERT( result );
+ 339 + +74 return result;
+ 340 + + }
+ 341 + +
+ 342 + + } // namespace detail
+ 343 + +
+ 344 + + value const&
+ 345 + +56 value::at_pointer(string_view ptr, source_location const& loc) const&
+ 346 + + {
+ 347 + +56 return try_at_pointer(ptr).value(loc);
+ 348 + + }
+ 349 + +
+ 350 + + system::result<value const&>
+ 351 + +58 value::try_at_pointer(string_view ptr) const noexcept
+ 352 + + {
+ 353 + +58 system::error_code ec;
+ 354 + +58 auto const found = find_pointer(ptr, ec);
+ 355 + +58 if( !found )
+ 356 + +10 return ec;
+ 357 + +48 return *found;
+ 358 + + }
+ 359 + +
+ 360 + + system::result<value&>
+ 361 + +2 value::try_at_pointer(string_view ptr) noexcept
+ 362 + + {
+ 363 + +2 system::error_code ec;
+ 364 + +2 auto const found = find_pointer(ptr, ec);
+ 365 + +2 if( !found )
+ 366 + +1 return ec;
+ 367 + +1 return *found;
+ 368 + + }
+ 369 + +
+ 370 + + value const*
+ 371 + +101 value::find_pointer( string_view sv, system::error_code& ec ) const noexcept
+ 372 + + {
+ 373 + +101 return detail::walk_pointer(
+ 374 + + *this,
+ 375 + + sv,
+ 376 + + ec,
+ 377 + +125 []( object const& obj, detail::pointer_token token )
+ 378 + + {
+ 379 + +125 return detail::if_contains_token(obj, token);
+ 380 + + },
+ 381 + +37 []( array const& arr, std::size_t index, system::error_code& ec )
+ 382 + + -> value const*
+ 383 + + {
+ 384 + +37 if( ec )
+ 385 + +22 return nullptr;
+ 386 + +
+ 387 + +15 return arr.if_contains(index);
+ 388 + + },
+ 389 + +5 []( value const&, string_view)
+ 390 + + {
+ 391 + +5 return std::false_type();
+ 392 + +101 });
+ 393 + + }
+ 394 + +
+ 395 + + value*
+ 396 + +22 value::find_pointer(string_view ptr, system::error_code& ec) noexcept
+ 397 + + {
+ 398 + +22 value const& self = *this;
+ 399 + +22 return const_cast<value*>(self.find_pointer(ptr, ec));
+ 400 + + }
+ 401 + +
+ 402 + + value const*
+ 403 + +20 value::find_pointer(string_view ptr, std::error_code& ec) const noexcept
+ 404 + + {
+ 405 + +20 system::error_code jec;
+ 406 + +20 value const* result = find_pointer(ptr, jec);
+ 407 + +20 ec = jec;
+ 408 + +20 return result;
+ 409 + + }
+ 410 + +
+ 411 + + value*
+ 412 + +19 value::find_pointer(string_view ptr, std::error_code& ec) noexcept
+ 413 + + {
+ 414 + +19 value const& self = *this;
+ 415 + +19 return const_cast<value*>(self.find_pointer(ptr, ec));
+ 416 + + }
+ 417 + +
+ 418 + + value*
+ 419 + +28 value::set_at_pointer(
+ 420 + + string_view sv,
+ 421 + + value_ref ref,
+ 422 + + system::error_code& ec,
+ 423 + + set_pointer_options const& opts )
+ 424 + + {
+ 425 + +28 value* result = detail::walk_pointer(
+ 426 + + *this,
+ 427 + + sv,
+ 428 + + ec,
+ 429 + +33 []( object& obj, detail::pointer_token token)
+ 430 + + {
+ 431 + +33 if( !obj.empty() )
+ 432 + + {
+ 433 + +13 key_value_pair* kv = detail::find_in_object( obj, token ).first;
+ 434 + +13 if( kv )
+ 435 + +12 return &kv->value();
+ 436 + + }
+ 437 + +
+ 438 + +21 string key( token.begin(), token.end(), obj.storage() );
+ 439 + +21 return &obj.emplace( std::move(key), nullptr ).first->value();
+ 440 + +21 },
+ 441 + +20 [ &opts ]( array& arr, std::size_t index, system::error_code& ec ) -> value*
+ 442 + + {
+ 443 + +20 if( ec == error::past_the_end )
+ 444 + +6 index = arr.size();
+ 445 + +14 else if( ec.failed() )
+ 446 + +2 return nullptr;
+ 447 + +
+ 448 + +18 if( index >= arr.size() )
+ 449 + + {
+ 450 + +13 std::size_t const n = index - arr.size();
+ 451 + +13 if( n >= opts.max_created_elements )
+ 452 + +3 return nullptr;
+ 453 + +
+ 454 + +10 arr.resize( arr.size() + n + 1 );
+ 455 + + }
+ 456 + +
+ 457 + +15 ec.clear();
+ 458 + +15 return arr.data() + index;
+ 459 + + },
+ 460 + +24 [ &opts ]( value& jv, string_view segment )
+ 461 + + {
+ 462 + +24 if( jv.is_null() || opts.replace_any_scalar )
+ 463 + + {
+ 464 + +21 if( opts.create_arrays )
+ 465 + + {
+ 466 + +18 system::error_code ec;
+ 467 + +18 detail::parse_number_token( segment, ec );
+ 468 + +18 if( !ec.failed() || ec == error::past_the_end )
+ 469 + + {
+ 470 + +2 jv = array( jv.storage() );
+ 471 + +2 return true;
+ 472 + + }
+ 473 + + }
+ 474 + +
+ 475 + +19 if( opts.create_objects )
+ 476 + + {
+ 477 + +19 jv = object( jv.storage() );
+ 478 + +19 return true;
+ 479 + + }
+ 480 + + }
+ 481 + +
+ 482 + +3 return false;
+ 483 + + });
+ 484 + +
+ 485 + +28 if( result )
+ 486 + +20 *result = ref.make_value( storage() );
+ 487 + +28 return result;
+ 488 + + }
+ 489 + +
+ 490 + + value*
+ 491 + +5 value::set_at_pointer(
+ 492 + + string_view sv,
+ 493 + + value_ref ref,
+ 494 + + std::error_code& ec,
+ 495 + + set_pointer_options const& opts )
+ 496 + + {
+ 497 + +5 system::error_code jec;
+ 498 + +5 value* result = set_at_pointer( sv, ref, jec, opts );
+ 499 + +5 ec = jec;
+ 500 + +5 return result;
+ 501 + + }
+ 502 + +
+ 503 + + system::result<value&>
+ 504 + +18 value::try_set_at_pointer(
+ 505 + + string_view sv,
+ 506 + + value_ref ref,
+ 507 + + set_pointer_options const& opts )
+ 508 + + {
+ 509 + +18 system::error_code ec;
+ 510 + +18 value* result = set_at_pointer( sv, ref, ec, opts );
+ 511 + +18 if( result )
+ 512 + +16 return *result;
+ 513 + +2 return ec;
+ 514 + + }
+ 515 + +
+ 516 + + value&
+ 517 + +17 value::set_at_pointer(
+ 518 + + string_view sv, value_ref ref, set_pointer_options const& opts )
+ 519 + + {
+ 520 + +17 return try_set_at_pointer(sv, ref, opts).value();
+ 521 + + }
+ 522 + +
+ 523 + + } // namespace json
+ 524 + + } // namespace boost
+ 525 + +
+ 526 + + #endif // BOOST_JSON_IMPL_POINTER_IPP
+ 527 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.result_for.hpp.e956a435ea4d78939339c698f7ed6545.html b/json/gcovr/index.result_for.hpp.e956a435ea4d78939339c698f7ed6545.html new file mode 100644 index 00000000..584818ae --- /dev/null +++ b/json/gcovr/index.result_for.hpp.e956a435ea4d78939339c698f7ed6545.html @@ -0,0 +1,3182 @@ + + + + + + result_for.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

result_for.hpp

+
+ + 100.0% Lines (3/3) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
result_for.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2024 Dmitry Arkhipov (grisumbras@yandex.ru)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_RESULT_FOR_HPP
+ 12 + + #define BOOST_JSON_RESULT_FOR_HPP
+ 13 + +
+ 14 + + #include <boost/json/detail/config.hpp>
+ 15 + + #include <boost/json/fwd.hpp>
+ 16 + + #include <boost/assert/source_location.hpp>
+ 17 + + #include <boost/system/result.hpp>
+ 18 + +
+ 19 + + namespace boost {
+ 20 + + namespace json {
+ 21 + +
+ 22 + + /**
+ 23 + + Helper trait that returns @ref boost::system::result.
+ 24 + +
+ 25 + + The primary template is an incomplete type. The library provides a partial
+ 26 + + specialisation `result_for<T1, value>`, that has nested type alias `type`
+ 27 + + that aliases the type `result<T1>`.
+ 28 + +
+ 29 + + The purpose of this trait is to let users provide non-throwing conversions
+ 30 + + for their types without creating a physical dependency on Boost.Json. For
+ 31 + + example:
+ 32 + +
+ 33 + + @code
+ 34 + + namespace boost {
+ 35 + + namespace json {
+ 36 + +
+ 37 + + template<class T>
+ 38 + + struct value_to_tag;
+ 39 + +
+ 40 + + template<class T1, class T2>
+ 41 + + struct result_for;
+ 42 + + }
+ 43 + + }
+ 44 + +
+ 45 + + namespace mine
+ 46 + + {
+ 47 + + class my_class;
+ 48 + + ...
+ 49 + + template<class JsonValue>
+ 50 + + boost::json::result_for<my_class, JsonValue>
+ 51 + + tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
+ 52 + + { ... }
+ 53 + + }
+ 54 + + @endcode
+ 55 + +
+ 56 + + @see @ref try_value_to, @ref try_value_to_tag
+ 57 + + */
+ 58 + + template <class T1, class T2>
+ 59 + + struct result_for;
+ 60 + +
+ 61 + + /** Create @ref boost::system::result containing a portable error code.
+ 62 + +
+ 63 + + This function constructs a `boost::system::result<T>` that stores
+ 64 + + `error_code` with `value()` equal to `e` and `category()` equal to
+ 65 + + @ref boost::system::generic_category().
+ 66 + +
+ 67 + + The main use for this function is in implementation of functions returning
+ 68 + + `boost::system::result`, without including `boost/json/system_error.hpp` or
+ 69 + + even `<system_error>`. In particular, it may be useful for customizations
+ 70 + + of @ref try_value_to without creating a physical dependency on Boost.JSON.
+ 71 + + For example:
+ 72 + +
+ 73 + + @code
+ 74 + + #include <cerrno>
+ 75 + + #include <boost/assert/source_location.hpp>
+ 76 + +
+ 77 + + namespace boost {
+ 78 + + namespace json {
+ 79 + +
+ 80 + + class value;
+ 81 + +
+ 82 + + template<class T>
+ 83 + + struct try_value_to_tag;
+ 84 + +
+ 85 + + template<class T1, class T2>
+ 86 + + struct result_for;
+ 87 + +
+ 88 + + template <class T>
+ 89 + + typename result_for<T, value>::type
+ 90 + + result_from_errno(int e, boost::source_location const* loc) noexcept
+ 91 + +
+ 92 + + }
+ 93 + + }
+ 94 + +
+ 95 + + namespace mine {
+ 96 + +
+ 97 + + class my_class;
+ 98 + + ...
+ 99 + + template<class JsonValue>
+ 100 + + boost::json::result_for<my_class, JsonValue>
+ 101 + + tag_invoke(boost::json::try_value_to_tag<my_class>, const JsonValue& jv)
+ 102 + + {
+ 103 + + BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
+ 104 + + if( !jv.is_null() )
+ 105 + + return boost::json::result_from_errno<my_class>(EINVAL, &loc);
+ 106 + + return my_class();
+ 107 + + }
+ 108 + +
+ 109 + + }
+ 110 + + @endcode
+ 111 + +
+ 112 + + @par Exception Safety
+ 113 + + Does not throw exceptions.
+ 114 + +
+ 115 + + @tparam T The value type of returned `result`.
+ 116 + + @param e The error value.
+ 117 + + @param loc The error location.
+ 118 + +
+ 119 + + @returns A @ref boost::system::result containing an error.
+ 120 + +
+ 121 + + @see @ref try_value_to_tag, @ref try_value_to, @ref result_for.
+ 122 + + */
+ 123 + + template <class T>
+ 124 + + typename result_for<T, value>::type
+ 125 + +56 result_from_errno(int e, boost::source_location const* loc) noexcept
+ 126 + + {
+ 127 + +56 system::error_code ec(e, system::generic_category(), loc);
+ 128 + +56 return {system::in_place_error, ec};
+ 129 + + }
+ 130 + +
+ 131 + + } // namespace json
+ 132 + + } // namespace boost
+ 133 + +
+ 134 + + #endif // BOOST_JSON_RESULT_FOR_HPP
+ 135 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.ryu.9a047557b83bbcb666051bf9b69b073a.html b/json/gcovr/index.ryu.9a047557b83bbcb666051bf9b69b073a.html new file mode 100644 index 00000000..4021fc05 --- /dev/null +++ b/json/gcovr/index.ryu.9a047557b83bbcb666051bf9b69b073a.html @@ -0,0 +1,2188 @@ + + + + + + detail/ryu/ - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + +
+
+
+ +
+
+
+
+
+

Lines

+
+
+
+ + + + + 93.3% +
+
+
+ Hit + 8225 +
+
+ Total + 8811 +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + -% +
+
+
+ Hit + 0 +
+
+ Total + 0 +
+
+
+
+
+ +
+ High: ≥ 90.0% + Medium: ≥ 75.0% + Low: < 75.0% +
+ +
+
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+
+ +
+
+ +
+ + + + detail +
+ +
+
+
+
+ 100.0% +
+ +
+ 114 + / + 114 +
+ + +
+
+ +
+ + + + impl/d2s.ipp +
+ +
+
+
+
+ 99.6% +
+ +
+ 224 + / + 225 +
+ + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.sbo_buffer.hpp.9e08251ec0ed54496b3a8a6fb89a63c3.html b/json/gcovr/index.sbo_buffer.hpp.9e08251ec0ed54496b3a8a6fb89a63c3.html new file mode 100644 index 00000000..0e43839a --- /dev/null +++ b/json/gcovr/index.sbo_buffer.hpp.9e08251ec0ed54496b3a8a6fb89a63c3.html @@ -0,0 +1,3630 @@ + + + + + + detail/sbo_buffer.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/sbo_buffer.hpp

+
+ + 100.0% Lines (44/44) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/sbo_buffer.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2023 Dmitry Arkhipov (grisumbras@yandex.ru)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_DETAIL_SBO_BUFFER_HPP
+ 12 + + #define BOOST_JSON_DETAIL_SBO_BUFFER_HPP
+ 13 + +
+ 14 + + #include <boost/core/detail/static_assert.hpp>
+ 15 + + #include <boost/json/detail/config.hpp>
+ 16 + + #include <boost/json/detail/except.hpp>
+ 17 + + #include <string>
+ 18 + + #include <array>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + + namespace detail {
+ 23 + +
+ 24 + + template< std::size_t N >
+ 25 + + class sbo_buffer
+ 26 + + {
+ 27 + + struct size_ptr_pair
+ 28 + + {
+ 29 + + std::size_t size;
+ 30 + + char* ptr;
+ 31 + + };
+ 32 + + BOOST_CORE_STATIC_ASSERT( N >= sizeof(size_ptr_pair) );
+ 33 + +
+ 34 + + union {
+ 35 + + std::array<char, N> buffer_;
+ 36 + + std::size_t capacity_;
+ 37 + + };
+ 38 + + char* data_ = buffer_.data();
+ 39 + + std::size_t size_ = 0;
+ 40 + +
+ 41 + + bool
+ 42 + +2183146 is_small() const noexcept
+ 43 + + {
+ 44 + +2183146 return data_ == buffer_.data();
+ 45 + + }
+ 46 + +
+ 47 + + void
+ 48 + +9271 dispose()
+ 49 + + {
+ 50 + +9271 if( is_small() )
+ 51 + +4771 return;
+ 52 + +
+ 53 + +4500 delete[] data_;
+ 54 + + #if defined(__GNUC__)
+ 55 + + # pragma GCC diagnostic push
+ 56 + + # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+ 57 + + #endif
+ 58 + +4500 buffer_ = {};
+ 59 + + #if defined(__GNUC__)
+ 60 + + # pragma GCC diagnostic pop
+ 61 + + #endif
+ 62 + +9000 data_ = buffer_.data();
+ 63 + + }
+ 64 + +
+ 65 + + static constexpr
+ 66 + + std::size_t
+ 67 + +18543 max_size() noexcept
+ 68 + + {
+ 69 + +18543 return BOOST_JSON_MAX_STRING_SIZE;
+ 70 + + }
+ 71 + +
+ 72 + + public:
+ 73 + +2164604 sbo_buffer()
+ 74 + +2164604 : buffer_()
+ 75 + +2164604 {}
+ 76 + +
+ 77 + + sbo_buffer( sbo_buffer&& other ) noexcept
+ 78 + + : size_(other.size_)
+ 79 + + {
+ 80 + + if( other.is_small() )
+ 81 + + {
+ 82 + + buffer_ = other.buffer_;
+ 83 + + data_ = buffer_.data();
+ 84 + + }
+ 85 + + else
+ 86 + + {
+ 87 + + data_ = other.data_;
+ 88 + + other.data_ = other.buffer_.data();
+ 89 + + }
+ 90 + + BOOST_ASSERT( other.is_small() );
+ 91 + + }
+ 92 + +
+ 93 + + sbo_buffer&
+ 94 + + operator=( sbo_buffer&& other ) noexcept
+ 95 + + {
+ 96 + + if( &other == this )
+ 97 + + return this;
+ 98 + +
+ 99 + + if( other.is_small() )
+ 100 + + {
+ 101 + + buffer_ = other.buffer_;
+ 102 + + data_ = buffer_.data();
+ 103 + + }
+ 104 + + else
+ 105 + + {
+ 106 + + data_ = other.data_;
+ 107 + + other.data_ = other.buffer_.data();
+ 108 + + }
+ 109 + +
+ 110 + + size_ = other.size_;
+ 111 + + other.size_ = 0;
+ 112 + +
+ 113 + + return *this;
+ 114 + + }
+ 115 + +
+ 116 + +2164604 ~sbo_buffer()
+ 117 + + {
+ 118 + +2164604 if( !is_small() )
+ 119 + +4771 delete[] data_;
+ 120 + +2164604 }
+ 121 + +
+ 122 + + std::size_t
+ 123 + +9271 capacity() const noexcept
+ 124 + + {
+ 125 + +14042 return is_small() ? buffer_.size() : capacity_;
+ 126 + + }
+ 127 + +
+ 128 + + void
+ 129 + + reset() noexcept
+ 130 + + {
+ 131 + + dispose();
+ 132 + + clear();
+ 133 + + }
+ 134 + +
+ 135 + + void
+ 136 + +6242824 clear()
+ 137 + + {
+ 138 + +6242824 size_ = 0;
+ 139 + +6242824 }
+ 140 + +
+ 141 + + void
+ 142 + +11794 grow( std::size_t size )
+ 143 + + {
+ 144 + +11794 if( !size )
+ 145 + +2522 return;
+ 146 + +
+ 147 + +9272 if( max_size() - size_ < size )
+ 148 + + {
+ 149 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 150 + +1 detail::throw_system_error( error::number_too_large, &loc );
+ 151 + + }
+ 152 + +
+ 153 + +9271 std::size_t const old_capacity = this->capacity();
+ 154 + +9271 std::size_t new_capacity = size_ + size;
+ 155 + +
+ 156 + + // growth factor 2
+ 157 + +9271 if( old_capacity <= max_size() - old_capacity ) // check for overflow
+ 158 + +9271 new_capacity = (std::max)(old_capacity * 2, new_capacity);
+ 159 + +
+ 160 + +9271 char* new_data = new char[new_capacity];
+ 161 + +9271 std::memcpy(new_data, data_, size_);
+ 162 + +
+ 163 + +9271 dispose();
+ 164 + +9271 data_ = new_data;
+ 165 + +9271 capacity_ = new_capacity;
+ 166 + + }
+ 167 + +
+ 168 + + char*
+ 169 + +11794 append( char const* ptr, std::size_t size )
+ 170 + + {
+ 171 + +11794 grow(size);
+ 172 + +
+ 173 + +11793 if(BOOST_JSON_LIKELY( size ))
+ 174 + +9271 std::memcpy( data_ + size_, ptr, size );
+ 175 + +11793 size_ += size;
+ 176 + +11793 return data_;
+ 177 + + }
+ 178 + +
+ 179 + + std::size_t
+ 180 + +3066342 size() noexcept
+ 181 + + {
+ 182 + +3066342 return size_;
+ 183 + + }
+ 184 + + };
+ 185 + +
+ 186 + + } // namespace detail
+ 187 + + } // namespace json
+ 188 + + } // namespace boost
+ 189 + +
+ 190 + + #endif // BOOST_JSON_DETAIL_SBO_BUFFER_HPP
+ 191 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.serialize.hpp.d3414f2b51c87c80044a72e36bd57115.html b/json/gcovr/index.serialize.hpp.d3414f2b51c87c80044a72e36bd57115.html new file mode 100644 index 00000000..8d8e830f --- /dev/null +++ b/json/gcovr/index.serialize.hpp.d3414f2b51c87c80044a72e36bd57115.html @@ -0,0 +1,2462 @@ + + + + + + impl/serialize.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/serialize.hpp

+
+ + 100.0% Lines (8/8) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/serialize.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2023 Dmitry Arkhipov (grisumbras@yandex.ru)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_SERIALIZE_HPP
+ 11 + + #define BOOST_JSON_IMPL_SERIALIZE_HPP
+ 12 + +
+ 13 + + #include <boost/json/serializer.hpp>
+ 14 + +
+ 15 + + namespace boost {
+ 16 + + namespace json {
+ 17 + + namespace detail {
+ 18 + +
+ 19 + + BOOST_JSON_DECL
+ 20 + + void
+ 21 + + serialize_impl(std::string& s, serializer& sr);
+ 22 + +
+ 23 + + } // namespace detail
+ 24 + +
+ 25 + + template<class T>
+ 26 + + std::string
+ 27 + +40 serialize(T const& t, serialize_options const& opts)
+ 28 + + {
+ 29 + + unsigned char buf[256];
+ 30 + +40 serializer sr(
+ 31 + +80 storage_ptr(),
+ 32 + + buf,
+ 33 + + sizeof(buf),
+ 34 + + opts);
+ 35 + +40 std::string s;
+ 36 + +40 sr.reset(&t);
+ 37 + +40 detail::serialize_impl(s, sr);
+ 38 + +80 return s;
+ 39 + +40 }
+ 40 + +
+ 41 + + } // namespace json
+ 42 + + } // namespace boost
+ 43 + +
+ 44 + + #endif // BOOST_JSON_IMPL_SERIALIZE_HPP
+ 45 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.serialize.ipp.01c963125bda877c839757dd2c6962c0.html b/json/gcovr/index.serialize.ipp.01c963125bda877c839757dd2c6962c0.html new file mode 100644 index 00000000..103aff29 --- /dev/null +++ b/json/gcovr/index.serialize.ipp.01c963125bda877c839757dd2c6962c0.html @@ -0,0 +1,4206 @@ + + + + + + impl/serialize.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/serialize.ipp

+
+ + 96.0% Lines (95/99) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/serialize.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_SERIALIZE_IPP
+ 11 + + #define BOOST_JSON_IMPL_SERIALIZE_IPP
+ 12 + +
+ 13 + + #include <boost/json/serialize.hpp>
+ 14 + + #include <boost/json/serializer.hpp>
+ 15 + + #include <ostream>
+ 16 + +
+ 17 + + namespace boost {
+ 18 + + namespace json {
+ 19 + +
+ 20 + + namespace {
+ 21 + +
+ 22 + + int serialize_xalloc = std::ios::xalloc();
+ 23 + +
+ 24 + + enum class serialize_stream_flags : long
+ 25 + + {
+ 26 + + allow_infinity_and_nan = 1,
+ 27 + + };
+ 28 + +
+ 29 + + std::underlying_type<serialize_stream_flags>::type
+ 30 + +2 to_bitmask( serialize_options const& opts )
+ 31 + + {
+ 32 + + using E = serialize_stream_flags;
+ 33 + + using I = std::underlying_type<E>::type;
+ 34 + +2 return (opts.allow_infinity_and_nan
+ 35 + +2 ? static_cast<I>(E::allow_infinity_and_nan) : 0);
+ 36 + + }
+ 37 + +
+ 38 + + serialize_options
+ 39 + +9 get_stream_flags( std::ostream& os )
+ 40 + + {
+ 41 + +9 auto const flags = os.iword(serialize_xalloc);
+ 42 + +
+ 43 + +9 serialize_options opts;
+ 44 + + using E = serialize_stream_flags;
+ 45 + + using I = std::underlying_type<E>::type;
+ 46 + +9 opts.allow_infinity_and_nan =
+ 47 + +9 flags & static_cast<I>(E::allow_infinity_and_nan);
+ 48 + +9 return opts;
+ 49 + + }
+ 50 + +
+ 51 + + } // namespace
+ 52 + +
+ 53 + + namespace detail {
+ 54 + +
+ 55 + + void
+ 56 + +18893 serialize_impl(
+ 57 + + std::string& s,
+ 58 + + serializer& sr)
+ 59 + + {
+ 60 + + // serialize to a small buffer to avoid
+ 61 + + // the first few allocations in std::string
+ 62 + + char buf[BOOST_JSON_STACK_BUFFER_SIZE];
+ 63 + +18893 string_view sv;
+ 64 + +18893 sv = sr.read(buf);
+ 65 + +18893 if(sr.done())
+ 66 + + {
+ 67 + + // fast path
+ 68 + +10885 s.append(
+ 69 + + sv.data(), sv.size());
+ 70 + +10885 return;
+ 71 + + }
+ 72 + +8008 std::size_t len = sv.size();
+ 73 + +8008 s.reserve(len * 2);
+ 74 + +8008 s.resize(s.capacity());
+ 75 + +8008 BOOST_ASSERT(
+ 76 + + s.size() >= len * 2);
+ 77 + +16016 std::memcpy(&s[0],
+ 78 + +8008 sv.data(), sv.size());
+ 79 + + auto const lim =
+ 80 + +8008 s.max_size() / 2;
+ 81 + + for(;;)
+ 82 + + {
+ 83 + + sv = sr.read(
+ 84 + +8008 &s[0] + len,
+ 85 + +8008 s.size() - len);
+ 86 + +8008 len += sv.size();
+ 87 + +8008 if(sr.done())
+ 88 + +8008 break;
+ 89 + + // growth factor 2x
+ 90 + + if(s.size() < lim)
+ 91 + + s.resize(s.size() * 2);
+ 92 + + else
+ 93 + + s.resize(2 * lim);
+ 94 + + }
+ 95 + +8008 s.resize(len);
+ 96 + + }
+ 97 + +
+ 98 + + } // namespace detail
+ 99 + +
+ 100 + + std::string
+ 101 + +18801 serialize(
+ 102 + + value const& jv,
+ 103 + + serialize_options const& opts)
+ 104 + + {
+ 105 + + unsigned char buf[256];
+ 106 + + serializer sr(
+ 107 + +37602 storage_ptr(),
+ 108 + + buf,
+ 109 + + sizeof(buf),
+ 110 + +18801 opts);
+ 111 + +18801 sr.reset(&jv);
+ 112 + +18801 std::string s;
+ 113 + +18801 serialize_impl(s, sr);
+ 114 + +37602 return s;
+ 115 + +18801 }
+ 116 + +
+ 117 + + std::string
+ 118 + +2 serialize(
+ 119 + + array const& arr,
+ 120 + + serialize_options const& opts)
+ 121 + + {
+ 122 + + unsigned char buf[256];
+ 123 + + serializer sr(
+ 124 + +4 storage_ptr(),
+ 125 + + buf,
+ 126 + + sizeof(buf),
+ 127 + +2 opts);
+ 128 + +2 std::string s;
+ 129 + +2 sr.reset(&arr);
+ 130 + +2 serialize_impl(s, sr);
+ 131 + +4 return s;
+ 132 + +2 }
+ 133 + +
+ 134 + + std::string
+ 135 + +49 serialize(
+ 136 + + object const& obj,
+ 137 + + serialize_options const& opts)
+ 138 + + {
+ 139 + + unsigned char buf[256];
+ 140 + + serializer sr(
+ 141 + +98 storage_ptr(),
+ 142 + + buf,
+ 143 + + sizeof(buf),
+ 144 + +49 opts);
+ 145 + +49 std::string s;
+ 146 + +49 sr.reset(&obj);
+ 147 + +49 serialize_impl(s, sr);
+ 148 + +98 return s;
+ 149 + +49 }
+ 150 + +
+ 151 + + std::string
+ 152 + +1 serialize(
+ 153 + + string const& str,
+ 154 + + serialize_options const& opts)
+ 155 + + {
+ 156 + +1 return serialize( str.subview(), opts );
+ 157 + + }
+ 158 + +
+ 159 + + // this is here for key_value_pair::key()
+ 160 + + std::string
+ 161 + +1 serialize(
+ 162 + + string_view sv,
+ 163 + + serialize_options const& opts)
+ 164 + + {
+ 165 + + unsigned char buf[256];
+ 166 + + serializer sr(
+ 167 + +2 storage_ptr(),
+ 168 + + buf,
+ 169 + + sizeof(buf),
+ 170 + +1 opts);
+ 171 + +1 std::string s;
+ 172 + +1 sr.reset(sv);
+ 173 + +1 serialize_impl(s, sr);
+ 174 + +2 return s;
+ 175 + +1 }
+ 176 + +
+ 177 + + //----------------------------------------------------------
+ 178 + +
+ 179 + + // tag::example_operator_lt_lt[]
+ 180 + + // Serialize a value into an output stream
+ 181 + +
+ 182 + + std::ostream&
+ 183 + +6 operator<<( std::ostream& os, value const& jv )
+ 184 + + {
+ 185 + + // Create a serializer
+ 186 + +6 serializer sr( get_stream_flags(os) );
+ 187 + +
+ 188 + + // Set the serializer up for our value
+ 189 + +6 sr.reset( &jv );
+ 190 + +
+ 191 + + // Loop until all output is produced.
+ 192 + +12 while( ! sr.done() )
+ 193 + + {
+ 194 + + // Use a local buffer to avoid allocation.
+ 195 + + char buf[ BOOST_JSON_STACK_BUFFER_SIZE ];
+ 196 + +
+ 197 + + // Fill our buffer with serialized characters and write it to the output stream.
+ 198 + +6 os << sr.read( buf );
+ 199 + + }
+ 200 + +
+ 201 + +6 return os;
+ 202 + +6 }
+ 203 + + // end::example_operator_lt_lt[]
+ 204 + +
+ 205 + + static
+ 206 + + void
+ 207 + +3 to_ostream(
+ 208 + + std::ostream& os,
+ 209 + + serializer& sr)
+ 210 + + {
+ 211 + +6 while(! sr.done())
+ 212 + + {
+ 213 + + char buf[BOOST_JSON_STACK_BUFFER_SIZE];
+ 214 + +3 auto s = sr.read(buf);
+ 215 + +3 os.write(s.data(), s.size());
+ 216 + + }
+ 217 + +3 }
+ 218 + +
+ 219 + + std::ostream&
+ 220 + +1 operator<<(
+ 221 + + std::ostream& os,
+ 222 + + array const& arr)
+ 223 + + {
+ 224 + +1 serializer sr( get_stream_flags(os) );
+ 225 + +1 sr.reset(&arr);
+ 226 + +1 to_ostream(os, sr);
+ 227 + +1 return os;
+ 228 + +1 }
+ 229 + +
+ 230 + + std::ostream&
+ 231 + +1 operator<<(
+ 232 + + std::ostream& os,
+ 233 + + object const& obj)
+ 234 + + {
+ 235 + +1 serializer sr( get_stream_flags(os) );
+ 236 + +1 sr.reset(&obj);
+ 237 + +1 to_ostream(os, sr);
+ 238 + +1 return os;
+ 239 + +1 }
+ 240 + +
+ 241 + + std::ostream&
+ 242 + +1 operator<<(
+ 243 + + std::ostream& os,
+ 244 + + string const& str)
+ 245 + + {
+ 246 + +1 serializer sr( get_stream_flags(os) );
+ 247 + +1 sr.reset(&str);
+ 248 + +1 to_ostream(os, sr);
+ 249 + +1 return os;
+ 250 + +1 }
+ 251 + +
+ 252 + + std::ostream&
+ 253 + +2 operator<<( std::ostream& os, serialize_options const& opts )
+ 254 + + {
+ 255 + +2 os.iword(serialize_xalloc) = to_bitmask(opts);
+ 256 + +2 return os;
+ 257 + + }
+ 258 + +
+ 259 + + } // namespace json
+ 260 + + } // namespace boost
+ 261 + +
+ 262 + + #endif
+ 263 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.serializer.hpp.79c79ec35822453ea6370e04c673a001.html b/json/gcovr/index.serializer.hpp.79c79ec35822453ea6370e04c673a001.html new file mode 100644 index 00000000..46ebe549 --- /dev/null +++ b/json/gcovr/index.serializer.hpp.79c79ec35822453ea6370e04c673a001.html @@ -0,0 +1,4286 @@ + + + + + + serializer.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

serializer.hpp

+
+ + 100.0% Lines (4/4) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
serializer.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_SERIALIZER_HPP
+ 11 + + #define BOOST_JSON_SERIALIZER_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/json/detail/format.hpp>
+ 15 + + #include <boost/json/detail/stream.hpp>
+ 16 + + #include <boost/json/detail/writer.hpp>
+ 17 + + #include <boost/json/serialize_options.hpp>
+ 18 + + #include <boost/json/value.hpp>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + +
+ 23 + + /** A serializer for JSON.
+ 24 + +
+ 25 + + This class traverses an instance of a library type and emits serialized
+ 26 + + JSON text by filling in one or more caller-provided buffers. To use,
+ 27 + + declare a variable and call @ref reset with a pointer to the variable you
+ 28 + + want to serialize. Then call @ref read over and over until @ref done
+ 29 + + returns `true`.
+ 30 + +
+ 31 + + @par Example
+ 32 + + This demonstrates how the serializer may be used to print a JSON value to
+ 33 + + an output stream.
+ 34 + +
+ 35 + + @code
+ 36 + + void print( std::ostream& os, value const& jv)
+ 37 + + {
+ 38 + + serializer sr;
+ 39 + + sr.reset( &jv );
+ 40 + + while( ! sr.done() )
+ 41 + + {
+ 42 + + char buf[ 4000 ];
+ 43 + + os << sr.read( buf );
+ 44 + + }
+ 45 + + }
+ 46 + + @endcode
+ 47 + +
+ 48 + + @par Thread Safety
+ 49 + + The same instance may not be accessed concurrently.
+ 50 + +
+ 51 + + @par Non-Standard JSON
+ 52 + + The @ref serialize_options structure optionally provided upon construction
+ 53 + + is used to enable non-standard JSON extensions. A default-constructed
+ 54 + + `serialize_options` doesn't enable any extensions.
+ 55 + +
+ 56 + + @see @ref serialize.
+ 57 + + */
+ 58 + + class serializer
+ 59 + + : detail::writer
+ 60 + + {
+ 61 + + using fn_t = bool (*)(writer&, detail::stream&);
+ 62 + +
+ 63 + + fn_t fn0_ = nullptr;
+ 64 + + fn_t fn1_ = nullptr;
+ 65 + + bool done_ = false;
+ 66 + +
+ 67 + + public:
+ 68 + + /** Destructor
+ 69 + +
+ 70 + + All temporary storage is deallocated.
+ 71 + +
+ 72 + + @par Complexity
+ 73 + + Constant
+ 74 + +
+ 75 + + @par Exception Safety
+ 76 + + No-throw guarantee.
+ 77 + + */
+ 78 + + #ifdef BOOST_JSON_DOCS
+ 79 + + BOOST_JSON_DECL
+ 80 + + ~serializer() noexcept;
+ 81 + + #endif // BOOST_JSON_DOCS
+ 82 + +
+ 83 + + /** Constructors.
+ 84 + +
+ 85 + + The serializer is constructed with no value to serialize The value may
+ 86 + + be set later by calling @ref reset. If serialization is attempted with
+ 87 + + no value, the output is as if a null value is serialized.
+ 88 + +
+ 89 + + Overload **(3)** is a move constructor. The type is neither copyable
+ 90 + + nor movable, so this constructor is deleted.
+ 91 + +
+ 92 + + @par Complexity
+ 93 + + Constant.
+ 94 + +
+ 95 + + @par Exception Safety
+ 96 + + No-throw guarantee.
+ 97 + +
+ 98 + + @param opts The options for the serializer. If this parameter is
+ 99 + + omitted, the serializer will output only standard JSON.
+ 100 + +
+ 101 + + @{
+ 102 + + */
+ 103 + + BOOST_JSON_DECL
+ 104 + + serializer( serialize_options const& opts = {} ) noexcept;
+ 105 + +
+ 106 + + /** Overload
+ 107 + +
+ 108 + + @param sp A pointer to the @ref boost::container::pmr::memory_resource
+ 109 + + to use when producing partial output. Shared ownership of the memory
+ 110 + + resource is retained until the serializer is destroyed.
+ 111 + +
+ 112 + + @param buf An optional static buffer to use for temporary storage when
+ 113 + + producing partial output.
+ 114 + +
+ 115 + + @param size The number of bytes of valid memory pointed to by
+ 116 + + `buf`.
+ 117 + +
+ 118 + + @param opts
+ 119 + + */
+ 120 + + BOOST_JSON_DECL
+ 121 + + serializer(
+ 122 + + storage_ptr sp,
+ 123 + + unsigned char* buf = nullptr,
+ 124 + + std::size_t size = 0,
+ 125 + + serialize_options const& opts = {}) noexcept;
+ 126 + +
+ 127 + + /// Overload
+ 128 + + serializer(serializer&&) = delete;
+ 129 + + /// @}
+ 130 + +
+ 131 + + /** Check if the serialization is complete.
+ 132 + +
+ 133 + + This function returns `true` when all of the characters in the
+ 134 + + serialized representation of the value have been read.
+ 135 + +
+ 136 + + @par Complexity
+ 137 + + Constant.
+ 138 + +
+ 139 + + @par Exception Safety
+ 140 + + No-throw guarantee.
+ 141 + + */
+ 142 + + bool
+ 143 + +26922 done() const noexcept
+ 144 + + {
+ 145 + +26922 return done_;
+ 146 + + }
+ 147 + +
+ 148 + + /** Reset the serializer for a new element.
+ 149 + +
+ 150 + + This function prepares the serializer to emit a new serialized JSON
+ 151 + + representing its argument: `*p` **(1)**--**(5)**, `sv` **(6)**, or
+ 152 + + `np` **(7)**. Ownership is not transferred. The caller is responsible
+ 153 + + for ensuring that the lifetime of the object pointed to by the argument
+ 154 + + extends until it is no longer needed.
+ 155 + +
+ 156 + + Any memory internally allocated for previous uses of this `serializer`
+ 157 + + object is preserved and re-used for the new output.
+ 158 + +
+ 159 + + Overload **(5)** uses \<\<direct_conversion,direct serialization\>\>.
+ 160 + +
+ 161 + + @param p A pointer to the element to serialize.
+ 162 + +
+ 163 + + @{
+ 164 + + */
+ 165 + + BOOST_JSON_DECL
+ 166 + + void
+ 167 + + reset(value const* p) noexcept;
+ 168 + +
+ 169 + + BOOST_JSON_DECL
+ 170 + + void
+ 171 + + reset(array const* p) noexcept;
+ 172 + +
+ 173 + + BOOST_JSON_DECL
+ 174 + + void
+ 175 + + reset(object const* p) noexcept;
+ 176 + +
+ 177 + + BOOST_JSON_DECL
+ 178 + + void
+ 179 + + reset(string const* p) noexcept;
+ 180 + +
+ 181 + + template<class T>
+ 182 + + void
+ 183 + + reset(T const* p) noexcept;
+ 184 + +
+ 185 + + /** Overload
+ 186 + +
+ 187 + + @param sv The characters representing a string.
+ 188 + + */
+ 189 + + BOOST_JSON_DECL
+ 190 + + void
+ 191 + + reset(string_view sv) noexcept;
+ 192 + +
+ 193 + + /** Overload
+ 194 + +
+ 195 + + @param np Represents a null value.
+ 196 + + */
+ 197 + + BOOST_JSON_DECL
+ 198 + + void
+ 199 + + reset(std::nullptr_t np) noexcept;
+ 200 + + /// @}
+ 201 + +
+ 202 + + /** Read the next buffer of serialized JSON.
+ 203 + +
+ 204 + + This function attempts to fill the caller provided buffer starting at
+ 205 + + `dest` with up to `size` characters of the serialized JSON that
+ 206 + + represents the value. If the buffer is not large enough, multiple calls
+ 207 + + may be required.
+ 208 + +
+ 209 + + If serialization completes during this call; that is, that all of the
+ 210 + + characters belonging to the serialized value have been written to
+ 211 + + caller-provided buffers, the function @ref done will return `true`.
+ 212 + +
+ 213 + + @pre
+ 214 + + @code
+ 215 + + done() == false
+ 216 + + @endcode
+ 217 + +
+ 218 + + @par Complexity
+ 219 + + @li **(1)** linear in `size`.
+ 220 + + @li **(2)** linear in `N`.
+ 221 + +
+ 222 + + @par Exception Safety
+ 223 + + Basic guarantee. Calls to `memory_resource::allocate` may throw.
+ 224 + +
+ 225 + + @return A @ref string_view containing the characters written, which may
+ 226 + + be less than `size` or `N`.
+ 227 + +
+ 228 + + @param dest A pointer to storage to write into.
+ 229 + +
+ 230 + + @param size The maximum number of characters to write to the memory
+ 231 + + pointed to by `dest`.
+ 232 + +
+ 233 + + @{
+ 234 + + */
+ 235 + + BOOST_JSON_DECL
+ 236 + + string_view
+ 237 + + read(char* dest, std::size_t size);
+ 238 + +
+ 239 + + /** Overload
+ 240 + +
+ 241 + + @tparam N The size of the array `dest`.
+ 242 + + @param dest
+ 243 + + */
+ 244 + + template<std::size_t N>
+ 245 + + string_view
+ 246 + +18911 read(char(&dest)[N])
+ 247 + + {
+ 248 + +18911 return read(dest, N);
+ 249 + + }
+ 250 + + /// @}
+ 251 + +
+ 252 + + #ifndef BOOST_JSON_DOCS
+ 253 + + // Safety net for accidental buffer overflows
+ 254 + + template<std::size_t N>
+ 255 + + string_view
+ 256 + + read(char(&dest)[N], std::size_t n)
+ 257 + + {
+ 258 + + // If this goes off, check your parameters
+ 259 + + // closely, chances are you passed an array
+ 260 + + // thinking it was a pointer.
+ 261 + + BOOST_ASSERT(n <= N);
+ 262 + + return read(dest, n);
+ 263 + + }
+ 264 + + #endif
+ 265 + + };
+ 266 + +
+ 267 + + } // namespace json
+ 268 + + } // namespace boost
+ 269 + +
+ 270 + + #include <boost/json/impl/serializer.hpp>
+ 271 + +
+ 272 + + #endif
+ 273 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.serializer.hpp.ad86b38709508f8d05ea641d2e98c1da.html b/json/gcovr/index.serializer.hpp.ad86b38709508f8d05ea641d2e98c1da.html new file mode 100644 index 00000000..f2e9c01e --- /dev/null +++ b/json/gcovr/index.serializer.hpp.ad86b38709508f8d05ea641d2e98c1da.html @@ -0,0 +1,8902 @@ + + + + + + impl/serializer.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/serializer.hpp

+
+ + 97.8% Lines (178/182) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/serializer.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2024 Dmitry Arkhipov (grisumbras@yandex.ru)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_SERIALIZER_HPP
+ 11 + + #define BOOST_JSON_IMPL_SERIALIZER_HPP
+ 12 + +
+ 13 + + #include <boost/core/detail/static_assert.hpp>
+ 14 + + #include <boost/describe/enum_to_string.hpp>
+ 15 + + #include <boost/json/conversion.hpp>
+ 16 + + #include <cstddef>
+ 17 + +
+ 18 + + namespace boost {
+ 19 + + namespace json {
+ 20 + + namespace detail {
+ 21 + +
+ 22 + + enum class writer::state : char
+ 23 + + {
+ 24 + + str1, str2, str3, esc1, utf1,
+ 25 + + utf2, utf3, utf4, utf5,
+ 26 + + lit,
+ 27 + + arr1, arr2, arr3, arr4,
+ 28 + + obj1, obj2, obj3, obj4, obj5, obj6
+ 29 + + };
+ 30 + +
+ 31 + + bool
+ 32 + +11258 writer::
+ 33 + + suspend(state st)
+ 34 + + {
+ 35 + +11258 st_.push(st);
+ 36 + +11257 return false;
+ 37 + + }
+ 38 + +
+ 39 + + template<class U, class T>
+ 40 + + bool
+ 41 + +11875 writer::
+ 42 + + suspend(state st, U u, T const* pt)
+ 43 + + {
+ 44 + +11875 st_.push(pt);
+ 45 + +11874 st_.push(u);
+ 46 + +11874 st_.push(st);
+ 47 + +11874 return false;
+ 48 + + }
+ 49 + +
+ 50 + + template<class T, bool StackEmpty>
+ 51 + + bool
+ 52 + + write_impl(writer& w, stream& ss);
+ 53 + +
+ 54 + + template<class T, bool StackEmpty>
+ 55 + + BOOST_FORCEINLINE
+ 56 + + bool
+ 57 + + write_impl(null_like_conversion_tag, writer& w, stream& ss)
+ 58 + + {
+ 59 + + #if defined(_MSC_VER)
+ 60 + + # pragma warning( push )
+ 61 + + # pragma warning( disable : 4127 )
+ 62 + + #endif
+ 63 + +14 if( StackEmpty || w.st_.empty() )
+ 64 + +20 return write_null(w, ss);
+ 65 + + #if defined(_MSC_VER)
+ 66 + + # pragma warning( pop )
+ 67 + + #endif
+ 68 + +14 return resume_buffer(w, ss);
+ 69 + + }
+ 70 + +
+ 71 + + template<class T, bool StackEmpty>
+ 72 + + BOOST_FORCEINLINE
+ 73 + + bool
+ 74 + + write_impl(bool_conversion_tag, writer& w, stream& ss)
+ 75 + + {
+ 76 + + BOOST_ASSERT( w.p_ );
+ 77 + +97 auto const t = *reinterpret_cast<T const*>(w.p_);
+ 78 + +
+ 79 + + #if defined(_MSC_VER)
+ 80 + + # pragma warning( push )
+ 81 + + # pragma warning( disable : 4127 )
+ 82 + + #endif
+ 83 + +61 if( StackEmpty || w.st_.empty() )
+ 84 + + #if defined(_MSC_VER)
+ 85 + + # pragma warning( pop )
+ 86 + + #endif
+ 87 + + {
+ 88 + +67 if( t )
+ 89 + +58 return write_true(w, ss);
+ 90 + + else
+ 91 + +9 return write_false(w, ss);
+ 92 + + }
+ 93 + +
+ 94 + +30 return resume_buffer(w, ss);
+ 95 + + }
+ 96 + +
+ 97 + + template<class T, bool StackEmpty>
+ 98 + + BOOST_FORCEINLINE
+ 99 + + bool
+ 100 + + write_impl(integral_conversion_tag, writer& w, stream& ss0)
+ 101 + + {
+ 102 + + #if defined(_MSC_VER)
+ 103 + + # pragma warning( push )
+ 104 + + # pragma warning( disable : 4127 )
+ 105 + + #endif
+ 106 + +200 if( StackEmpty || w.st_.empty() )
+ 107 + + #if defined(_MSC_VER)
+ 108 + + # pragma warning( pop )
+ 109 + + #endif
+ 110 + + {
+ 111 + +6 auto const& t = *reinterpret_cast<T const*>(w.p_);
+ 112 + +
+ 113 + + #if defined(__clang__)
+ 114 + + # pragma clang diagnostic push
+ 115 + + # pragma clang diagnostic ignored "-Wsign-compare"
+ 116 + + #elif defined(__GNUC__)
+ 117 + + # pragma GCC diagnostic push
+ 118 + + # pragma GCC diagnostic ignored "-Wsign-compare"
+ 119 + + #elif defined(_MSC_VER)
+ 120 + + # pragma warning( push )
+ 121 + + # pragma warning( disable : 4018 )
+ 122 + + # pragma warning( disable : 4127 )
+ 123 + + #endif
+ 124 + +
+ 125 + +134 if( t < 0 )
+ 126 + + {
+ 127 + + // T is obviously signed, so this comparison is safe
+ 128 + +6 if( t >= (std::numeric_limits<std::int64_t>::min)() )
+ 129 + + {
+ 130 + +6 std::int64_t i = t;
+ 131 + +6 return write_int64(w, ss0, i);
+ 132 + + }
+ 133 + + }
+ 134 + +334 else if( t <= (std::numeric_limits<std::uint64_t>::max)() )
+ 135 + + {
+ 136 + +334 std::uint64_t u = t;
+ 137 + +334 return write_uint64(w, ss0, u);
+ 138 + + }
+ 139 + + #if defined(__clang__)
+ 140 + + # pragma clang diagnostic pop
+ 141 + + #elif defined(__GNUC__)
+ 142 + + # pragma GCC diagnostic pop
+ 143 + + #elif defined(_MSC_VER)
+ 144 + + # pragma warning( pop )
+ 145 + + #endif
+ 146 + +
+ 147 + + #if defined(_MSC_VER)
+ 148 + + # pragma warning( push )
+ 149 + + # pragma warning( disable : 4244 )
+ 150 + + #endif
+ 151 + + double d = t;
+ 152 + + return write_double(w, ss0, d);
+ 153 + + #if defined(_MSC_VER)
+ 154 + + # pragma warning( pop )
+ 155 + + #endif
+ 156 + + }
+ 157 + +
+ 158 + +66 return resume_buffer(w, ss0);
+ 159 + + }
+ 160 + +
+ 161 + + template<class T, bool StackEmpty>
+ 162 + + BOOST_FORCEINLINE
+ 163 + + bool
+ 164 + + write_impl(floating_point_conversion_tag, writer& w, stream& ss0)
+ 165 + + {
+ 166 + + #if defined(_MSC_VER)
+ 167 + + # pragma warning( push )
+ 168 + + # pragma warning( disable : 4127 )
+ 169 + + #endif
+ 170 + +10 if( StackEmpty || w.st_.empty() )
+ 171 + + #if defined(_MSC_VER)
+ 172 + + # pragma warning( pop )
+ 173 + + #endif
+ 174 + + {
+ 175 + +10 double d = *reinterpret_cast<T const*>(w.p_);
+ 176 + +10 return write_double(w, ss0, d);
+ 177 + + }
+ 178 + +
+ 179 + +10 return resume_buffer(w, ss0);
+ 180 + + }
+ 181 + +
+ 182 + + template<class T, bool StackEmpty>
+ 183 + + BOOST_FORCEINLINE
+ 184 + + bool
+ 185 + + write_impl(string_like_conversion_tag, writer& w, stream& ss0)
+ 186 + + {
+ 187 + + #if defined(_MSC_VER)
+ 188 + + # pragma warning( push )
+ 189 + + # pragma warning( disable : 4127 )
+ 190 + + #endif
+ 191 + +112 if( StackEmpty || w.st_.empty() )
+ 192 + + #if defined(_MSC_VER)
+ 193 + + # pragma warning( pop )
+ 194 + + #endif
+ 195 + + {
+ 196 + + string_view const sv = *reinterpret_cast<T const*>(w.p_);
+ 197 + +91 w.cs0_ = { sv.data(), sv.size() };
+ 198 + +91 return write_string(w, ss0);
+ 199 + + }
+ 200 + +
+ 201 + +112 return resume_string(w, ss0);
+ 202 + + }
+ 203 + +
+ 204 + + template<class T, bool StackEmpty>
+ 205 + + BOOST_FORCEINLINE
+ 206 + + bool
+ 207 + + write_impl(sequence_conversion_tag, writer& w, stream& ss0)
+ 208 + + {
+ 209 + + using It = iterator_type<T const>;
+ 210 + + using Elem = value_type<T>;
+ 211 + +
+ 212 + + T const* pt;
+ 213 + +6078 local_stream ss(ss0);
+ 214 + +37 It it;
+ 215 + +17 It end;
+ 216 + + #if defined(_MSC_VER)
+ 217 + + # pragma warning( push )
+ 218 + + # pragma warning( disable : 4127 )
+ 219 + + #endif
+ 220 + +2656 if(StackEmpty || w.st_.empty())
+ 221 + + {
+ 222 + + #if defined(_MSC_VER)
+ 223 + + # pragma warning( pop )
+ 224 + + #endif
+ 225 + +3422 BOOST_ASSERT( w.p_ );
+ 226 + +3422 pt = reinterpret_cast<T const*>(w.p_);
+ 227 + +3422 it = std::begin(*pt);
+ 228 + +6844 end = std::end(*pt);
+ 229 + + }
+ 230 + + else
+ 231 + + {
+ 232 + + writer::state st;
+ 233 + +2656 w.st_.pop(st);
+ 234 + +2656 w.st_.pop(it);
+ 235 + +2656 w.st_.pop(pt);
+ 236 + +2656 end = std::end(*pt);
+ 237 + +2656 switch(st)
+ 238 + + {
+ 239 + +70 default:
+ 240 + +70 case writer::state::arr1: goto do_arr1;
+ 241 + +2314 case writer::state::arr2: goto do_arr2;
+ 242 + +40 case writer::state::arr3: goto do_arr3;
+ 243 + +232 case writer::state::arr4: goto do_arr4;
+ 244 + + break;
+ 245 + + }
+ 246 + + }
+ 247 + +3492 do_arr1:
+ 248 + +3492 if(BOOST_JSON_LIKELY(ss))
+ 249 + +3422 ss.append('[');
+ 250 + + else
+ 251 + +70 return w.suspend(writer::state::arr1, it, pt);
+ 252 + +3422 if(it == end)
+ 253 + +507 goto do_arr4;
+ 254 + + for(;;)
+ 255 + + {
+ 256 + +4064 w.p_ = std::addressof(*it);
+ 257 + +6378 do_arr2:
+ 258 + +6378 if( !write_impl<Elem, StackEmpty>(w, ss) )
+ 259 + +2315 return w.suspend(writer::state::arr2, it, pt);
+ 260 + +4063 if(BOOST_JSON_UNLIKELY( ++it == end ))
+ 261 + +2914 break;
+ 262 + +1149 do_arr3:
+ 263 + +1189 if(BOOST_JSON_LIKELY(ss))
+ 264 + +1149 ss.append(',');
+ 265 + + else
+ 266 + +40 return w.suspend(writer::state::arr3, it, pt);
+ 267 + + }
+ 268 + +3653 do_arr4:
+ 269 + +3653 if(BOOST_JSON_LIKELY(ss))
+ 270 + +3421 ss.append(']');
+ 271 + + else
+ 272 + +232 return w.suspend(writer::state::arr4, it, pt);
+ 273 + +3421 return true;
+ 274 + +6078 }
+ 275 + +
+ 276 + + template<class T, bool StackEmpty>
+ 277 + + BOOST_FORCEINLINE
+ 278 + + bool
+ 279 + + write_impl(map_like_conversion_tag, writer& w, stream& ss0)
+ 280 + + {
+ 281 + + using It = iterator_type<T const>;
+ 282 + + using Mapped = mapped_type<T>;
+ 283 + +
+ 284 + + T const* pt;
+ 285 + +27290 local_stream ss(ss0);
+ 286 + +96 It it;
+ 287 + +96 It end;
+ 288 + + #if defined(_MSC_VER)
+ 289 + + # pragma warning( push )
+ 290 + + # pragma warning( disable : 4127 )
+ 291 + + #endif
+ 292 + +9120 if(StackEmpty || w.st_.empty())
+ 293 + + #if defined(_MSC_VER)
+ 294 + + # pragma warning( pop )
+ 295 + + #endif
+ 296 + + {
+ 297 + +18170 BOOST_ASSERT( w.p_ );
+ 298 + +18170 pt = reinterpret_cast<T const*>(w.p_);
+ 299 + +18170 it = std::begin(*pt);
+ 300 + +36340 end = std::end(*pt);
+ 301 + + }
+ 302 + + else
+ 303 + + {
+ 304 + + writer::state st;
+ 305 + +9120 w.st_.pop(st);
+ 306 + +9120 w.st_.pop(it);
+ 307 + +9120 w.st_.pop(pt);
+ 308 + +9120 end = std::end(*pt);
+ 309 + +9120 switch(st)
+ 310 + + {
+ 311 + +12 default:
+ 312 + +12 case writer::state::obj1: goto do_obj1;
+ 313 + +296 case writer::state::obj2: goto do_obj2;
+ 314 + +50 case writer::state::obj3: goto do_obj3;
+ 315 + +8700 case writer::state::obj4: goto do_obj4;
+ 316 + +16 case writer::state::obj5: goto do_obj5;
+ 317 + +46 case writer::state::obj6: goto do_obj6;
+ 318 + + break;
+ 319 + + }
+ 320 + + }
+ 321 + +18182 do_obj1:
+ 322 + +18182 if(BOOST_JSON_LIKELY( ss ))
+ 323 + +18170 ss.append('{');
+ 324 + + else
+ 325 + +12 return w.suspend(writer::state::obj1, it, pt);
+ 326 + +18170 if(BOOST_JSON_UNLIKELY( it == end ))
+ 327 + +563 goto do_obj6;
+ 328 + +2129 for(;;)
+ 329 + + {
+ 330 + + {
+ 331 + + using std::get;
+ 332 + +19736 string_view const sv = get<0>(*it);
+ 333 + +19736 w.cs0_ = { sv.data(), sv.size() };
+ 334 + + }
+ 335 + + if( true )
+ 336 + + {
+ 337 + +19736 if(BOOST_JSON_UNLIKELY( !write_string(w, ss) ))
+ 338 + +173 return w.suspend(writer::state::obj2, it, pt);
+ 339 + + }
+ 340 + + else
+ 341 + + {
+ 342 + +296 do_obj2:
+ 343 + +296 if(BOOST_JSON_UNLIKELY( !resume_string(w, ss) ))
+ 344 + +123 return w.suspend(writer::state::obj2, it, pt);
+ 345 + + }
+ 346 + +173 do_obj3:
+ 347 + +19786 if(BOOST_JSON_LIKELY(ss))
+ 348 + +19736 ss.append(':');
+ 349 + + else
+ 350 + +50 return w.suspend(writer::state::obj3, it, pt);
+ 351 + +28436 do_obj4:
+ 352 + + {
+ 353 + + using std::get;
+ 354 + +28436 w.p_ = std::addressof( get<1>(*it) );
+ 355 + + }
+ 356 + +28436 if(BOOST_JSON_UNLIKELY(( !write_impl<Mapped, StackEmpty>(w, ss) )))
+ 357 + +8700 return w.suspend(writer::state::obj4, it, pt);
+ 358 + +19736 ++it;
+ 359 + +19736 if(BOOST_JSON_UNLIKELY(it == end))
+ 360 + +17607 break;
+ 361 + +2129 do_obj5:
+ 362 + +2145 if(BOOST_JSON_LIKELY(ss))
+ 363 + +2129 ss.append(',');
+ 364 + + else
+ 365 + +16 return w.suspend(writer::state::obj5, it, pt);
+ 366 + + }
+ 367 + +18216 do_obj6:
+ 368 + +18216 if(BOOST_JSON_LIKELY( ss ))
+ 369 + + {
+ 370 + +18170 ss.append('}');
+ 371 + +18170 return true;
+ 372 + + }
+ 373 + +46 return w.suspend(writer::state::obj6, it, pt);
+ 374 + +27290 }
+ 375 + +
+ 376 + + template< class T, bool StackEmpty >
+ 377 + + struct serialize_tuple_elem_helper
+ 378 + + {
+ 379 + + writer& w;
+ 380 + + stream& ss;
+ 381 + + T const* pt;
+ 382 + +
+ 383 + + template< std::size_t I >
+ 384 + + bool
+ 385 + +258 operator()( std::integral_constant<std::size_t, I> ) const
+ 386 + + {
+ 387 + + using std::get;
+ 388 + +258 w.p_ = std::addressof( get<I>(*pt) );
+ 389 + +
+ 390 + + using Elem = tuple_element_t<I, T>;
+ 391 + +258 return write_impl<Elem, StackEmpty>(w, ss);
+ 392 + + }
+ 393 + + };
+ 394 + +
+ 395 + + template<class T, bool StackEmpty>
+ 396 + + BOOST_FORCEINLINE
+ 397 + + bool
+ 398 + + write_impl(tuple_conversion_tag, writer& w, stream& ss0)
+ 399 + + {
+ 400 + + T const* pt;
+ 401 + +174 local_stream ss(ss0);
+ 402 + + std::size_t cur;
+ 403 + +64 constexpr std::size_t N = std::tuple_size<T>::value;
+ 404 + + #if defined(_MSC_VER)
+ 405 + + # pragma warning( push )
+ 406 + + # pragma warning( disable : 4127 )
+ 407 + + #endif
+ 408 + +110 if(StackEmpty || w.st_.empty())
+ 409 + + {
+ 410 + + #if defined(_MSC_VER)
+ 411 + + # pragma warning( pop )
+ 412 + + #endif
+ 413 + +76 BOOST_ASSERT( w.p_ );
+ 414 + +76 pt = reinterpret_cast<T const*>(w.p_);
+ 415 + +76 cur = 0;
+ 416 + + }
+ 417 + + else
+ 418 + + {
+ 419 + + writer::state st;
+ 420 + +98 w.st_.pop(st);
+ 421 + +98 w.st_.pop(cur);
+ 422 + +98 w.st_.pop(pt);
+ 423 + +98 switch(st)
+ 424 + + {
+ 425 + +2 default:
+ 426 + +2 case writer::state::arr1: goto do_arr1;
+ 427 + +82 case writer::state::arr2: goto do_arr2;
+ 428 + +8 case writer::state::arr3: goto do_arr3;
+ 429 + +6 case writer::state::arr4: goto do_arr4;
+ 430 + + break;
+ 431 + + }
+ 432 + + }
+ 433 + +78 do_arr1:
+ 434 + +78 if(BOOST_JSON_LIKELY(ss))
+ 435 + +76 ss.append('[');
+ 436 + + else
+ 437 + +2 return w.suspend(writer::state::arr1, cur, pt);
+ 438 + +100 for(;;)
+ 439 + + {
+ 440 + +258 do_arr2:
+ 441 + + {
+ 442 + +258 bool const stop = !mp11::mp_with_index<N>(
+ 443 + + cur,
+ 444 + + serialize_tuple_elem_helper<T, StackEmpty>{w, ss, pt});
+ 445 + +258 if(BOOST_JSON_UNLIKELY( stop ))
+ 446 + +82 return w.suspend(writer::state::arr2, cur, pt);
+ 447 + + }
+ 448 + +176 if(BOOST_JSON_UNLIKELY( ++cur == N ))
+ 449 + +76 break;
+ 450 + +100 do_arr3:
+ 451 + +108 if(BOOST_JSON_LIKELY(ss))
+ 452 + +100 ss.append(',');
+ 453 + + else
+ 454 + +8 return w.suspend(writer::state::arr3, cur, pt);
+ 455 + + }
+ 456 + +82 do_arr4:
+ 457 + +82 if(BOOST_JSON_LIKELY(ss))
+ 458 + +76 ss.append(']');
+ 459 + + else
+ 460 + +6 return w.suspend(writer::state::arr4, cur, pt);
+ 461 + +76 return true;
+ 462 + +174 }
+ 463 + +
+ 464 + + template< class T, bool StackEmpty >
+ 465 + + struct serialize_struct_elem_helper
+ 466 + + {
+ 467 + + static_assert(
+ 468 + + uniquely_named_members<T>::value,
+ 469 + + "The type has several described members with the same name.");
+ 470 + +
+ 471 + + writer& w;
+ 472 + + local_stream& ss;
+ 473 + + T const* pt;
+ 474 + + writer::state st;
+ 475 + +
+ 476 + + template< std::size_t I >
+ 477 + + writer::state
+ 478 + + operator()( std::integral_constant<std::size_t, I> ) const
+ 479 + + {
+ 480 + + using Ds = described_members<T>;
+ 481 + + using D = mp11::mp_at_c<Ds, I>;
+ 482 + + using M = described_member_t<T, D>;
+ 483 + +
+ 484 + + switch(st)
+ 485 + + {
+ 486 + + case writer::state::obj2: goto do_obj2;
+ 487 + + case writer::state::obj3: goto do_obj3;
+ 488 + + case writer::state::obj4: goto do_obj4;
+ 489 + + default: break;
+ 490 + + }
+ 491 + +
+ 492 + + {
+ 493 + + string_view const sv = D::name;
+ 494 + + w.cs0_ = { sv.data(), sv.size() };
+ 495 + + }
+ 496 + + if( true )
+ 497 + + {
+ 498 + + if(BOOST_JSON_UNLIKELY( !write_string(w, ss) ))
+ 499 + + return writer::state::obj2;
+ 500 + + }
+ 501 + + else
+ 502 + + {
+ 503 + + do_obj2:
+ 504 + + if(BOOST_JSON_UNLIKELY( !resume_string(w, ss) ))
+ 505 + + return writer::state::obj2;
+ 506 + + }
+ 507 + + do_obj3:
+ 508 + + if(BOOST_JSON_LIKELY(ss))
+ 509 + + ss.append(':');
+ 510 + + else
+ 511 + + return writer::state::obj3;
+ 512 + + do_obj4:
+ 513 + + w.p_ = std::addressof( pt->* D::pointer );
+ 514 + + if(BOOST_JSON_UNLIKELY((
+ 515 + + !write_impl<M, StackEmpty>(w, ss) )))
+ 516 + + return writer::state::obj4;
+ 517 + +
+ 518 + + return writer::state{};
+ 519 + + }
+ 520 + + };
+ 521 + +
+ 522 + + template<class T, bool StackEmpty>
+ 523 + + BOOST_FORCEINLINE
+ 524 + + bool
+ 525 + + write_impl(described_class_conversion_tag, writer& w, stream& ss0)
+ 526 + + {
+ 527 + + using Ds = described_members<T>;
+ 528 + +
+ 529 + + T const* pt;
+ 530 + + local_stream ss(ss0);
+ 531 + + std::size_t cur;
+ 532 + + constexpr std::size_t N = mp11::mp_size<Ds>::value;
+ 533 + + writer::state st;
+ 534 + + #if defined(_MSC_VER)
+ 535 + + # pragma warning( push )
+ 536 + + # pragma warning( disable : 4127 )
+ 537 + + #endif
+ 538 + + if(StackEmpty || w.st_.empty())
+ 539 + + #if defined(_MSC_VER)
+ 540 + + # pragma warning( pop )
+ 541 + + #endif
+ 542 + + {
+ 543 + + BOOST_ASSERT( w.p_ );
+ 544 + + pt = reinterpret_cast<T const*>(w.p_);
+ 545 + + cur = 0;
+ 546 + + }
+ 547 + + else
+ 548 + + {
+ 549 + + w.st_.pop(st);
+ 550 + + w.st_.pop(cur);
+ 551 + + w.st_.pop(pt);
+ 552 + + switch(st)
+ 553 + + {
+ 554 + + default:
+ 555 + + case writer::state::obj1: goto do_obj1;
+ 556 + + case writer::state::obj2: // fall through
+ 557 + + case writer::state::obj3: // fall through
+ 558 + + case writer::state::obj4: goto do_obj2;
+ 559 + + case writer::state::obj5: goto do_obj5;
+ 560 + + case writer::state::obj6: goto do_obj6;
+ 561 + + break;
+ 562 + + }
+ 563 + + }
+ 564 + + do_obj1:
+ 565 + + if(BOOST_JSON_LIKELY( ss ))
+ 566 + + ss.append('{');
+ 567 + + else
+ 568 + + return w.suspend(writer::state::obj1, cur, pt);
+ 569 + + if(BOOST_JSON_UNLIKELY( cur == N ))
+ 570 + + goto do_obj6;
+ 571 + + for(;;)
+ 572 + + {
+ 573 + + st = {};
+ 574 + + do_obj2:
+ 575 + + st = mp11::mp_with_index<N>(
+ 576 + + cur,
+ 577 + + serialize_struct_elem_helper<T, StackEmpty>{w, ss, pt, st});
+ 578 + + if(BOOST_JSON_UNLIKELY( st != writer::state{} ))
+ 579 + + return w.suspend(st, cur, pt);
+ 580 + + ++cur;
+ 581 + + if(BOOST_JSON_UNLIKELY(cur == N))
+ 582 + + break;
+ 583 + + do_obj5:
+ 584 + + if(BOOST_JSON_LIKELY(ss))
+ 585 + + ss.append(',');
+ 586 + + else
+ 587 + + return w.suspend(writer::state::obj5, cur, pt);
+ 588 + + }
+ 589 + + do_obj6:
+ 590 + + if(BOOST_JSON_LIKELY( ss ))
+ 591 + + {
+ 592 + + ss.append('}');
+ 593 + + return true;
+ 594 + + }
+ 595 + + return w.suspend(writer::state::obj6, cur, pt);
+ 596 + + }
+ 597 + +
+ 598 + + template<class T, bool StackEmpty>
+ 599 + + BOOST_FORCEINLINE
+ 600 + + bool
+ 601 + + write_impl(described_enum_conversion_tag, writer& w, stream& ss)
+ 602 + + {
+ 603 + + #ifdef BOOST_DESCRIBE_CXX14
+ 604 + + using Integer = typename std::underlying_type<T>::type;
+ 605 + +
+ 606 + + #if defined(_MSC_VER)
+ 607 + + # pragma warning( push )
+ 608 + + # pragma warning( disable : 4127 )
+ 609 + + #endif
+ 610 + + if(StackEmpty || w.st_.empty())
+ 611 + + #if defined(_MSC_VER)
+ 612 + + # pragma warning( pop )
+ 613 + + #endif
+ 614 + + {
+ 615 + + BOOST_ASSERT( w.p_ );
+ 616 + + T const* pt = reinterpret_cast<T const*>(w.p_);
+ 617 + + char const* const name = describe::enum_to_string(*pt, nullptr);
+ 618 + + if( name )
+ 619 + + {
+ 620 + + string_view const sv = name;
+ 621 + + w.cs0_ = { sv.data(), sv.size() };
+ 622 + + return write_string(w, ss);
+ 623 + + }
+ 624 + + else
+ 625 + + {
+ 626 + + Integer n = static_cast<Integer>(*pt);
+ 627 + + w.p_ = &n;
+ 628 + + return write_impl<Integer, true>(w, ss);
+ 629 + + }
+ 630 + + }
+ 631 + + else
+ 632 + + {
+ 633 + + writer::state st;
+ 634 + + w.st_.peek(st);
+ 635 + + if( st == writer::state::lit )
+ 636 + + return write_impl<Integer, false>(w, ss);
+ 637 + + else
+ 638 + + return resume_string(w, ss);
+ 639 + + }
+ 640 + + #else // BOOST_DESCRIBE_CXX14
+ 641 + + (void)w;
+ 642 + + (void)ss;
+ 643 + + static_assert(
+ 644 + + !std::is_same<T, T>::value,
+ 645 + + "described enums require C++14 support");
+ 646 + + return false;
+ 647 + + #endif // BOOST_DESCRIBE_CXX14
+ 648 + + }
+ 649 + +
+ 650 + + template< class T, bool StackEmpty >
+ 651 + + struct serialize_variant_elem_helper
+ 652 + + {
+ 653 + + writer& w;
+ 654 + + stream& ss;
+ 655 + +
+ 656 + + template<class Elem>
+ 657 + + bool
+ 658 + + operator()(Elem const& x) const
+ 659 + + {
+ 660 + + w.p_ = std::addressof(x);
+ 661 + + return write_impl<Elem, true>(w, ss);
+ 662 + + }
+ 663 + + };
+ 664 + +
+ 665 + + template< class T >
+ 666 + + struct serialize_variant_elem_helper<T, false>
+ 667 + + {
+ 668 + + writer& w;
+ 669 + + stream& ss;
+ 670 + +
+ 671 + + template< std::size_t I >
+ 672 + + bool
+ 673 + + operator()( std::integral_constant<std::size_t, I> ) const
+ 674 + + {
+ 675 + + using std::get;
+ 676 + + using Elem = remove_cvref<decltype(get<I>(
+ 677 + + std::declval<T const&>() ))>;
+ 678 + + return write_impl<Elem, false>(w, ss);
+ 679 + + }
+ 680 + + };
+ 681 + +
+ 682 + + template<class T, bool StackEmpty>
+ 683 + + BOOST_FORCEINLINE
+ 684 + + bool
+ 685 + + write_impl(variant_conversion_tag, writer& w, stream& ss)
+ 686 + + {
+ 687 + + T const* pt;
+ 688 + +
+ 689 + + using Index = remove_cvref<decltype( pt->index() )>;
+ 690 + +
+ 691 + + #if defined(_MSC_VER)
+ 692 + + # pragma warning( push )
+ 693 + + # pragma warning( disable : 4127 )
+ 694 + + #endif
+ 695 + + if(StackEmpty || w.st_.empty())
+ 696 + + #if defined(_MSC_VER)
+ 697 + + # pragma warning( pop )
+ 698 + + #endif
+ 699 + + {
+ 700 + + BOOST_ASSERT( w.p_ );
+ 701 + + pt = reinterpret_cast<T const*>(w.p_);
+ 702 + + if(BOOST_JSON_LIKELY((
+ 703 + + visit(serialize_variant_elem_helper<T, true>{w, ss}, *pt))))
+ 704 + + return true;
+ 705 + +
+ 706 + + Index const ix = pt->index();
+ 707 + + w.st_.push(ix);
+ 708 + + return false;
+ 709 + + }
+ 710 + + else
+ 711 + + {
+ 712 + + Index ix;
+ 713 + + w.st_.pop(ix);
+ 714 + +
+ 715 + + constexpr std::size_t N = mp11::mp_size<T>::value;
+ 716 + + if(BOOST_JSON_LIKELY(( mp11::mp_with_index<N>(
+ 717 + + ix,
+ 718 + + serialize_variant_elem_helper<T, false>{w, ss}))))
+ 719 + + return true;
+ 720 + +
+ 721 + + w.st_.push(ix);
+ 722 + + return false;
+ 723 + + }
+ 724 + + }
+ 725 + +
+ 726 + + template<class T, bool StackEmpty>
+ 727 + + BOOST_FORCEINLINE
+ 728 + + bool
+ 729 + + write_impl(optional_conversion_tag, writer& w, stream& ss)
+ 730 + + {
+ 731 + + using Elem = value_result_type<T>;
+ 732 + +
+ 733 + + bool done;
+ 734 + + bool has_value;
+ 735 + +
+ 736 + + #if defined(_MSC_VER)
+ 737 + + # pragma warning( push )
+ 738 + + # pragma warning( disable : 4127 )
+ 739 + + #endif
+ 740 + + if(StackEmpty || w.st_.empty())
+ 741 + + #if defined(_MSC_VER)
+ 742 + + # pragma warning( pop )
+ 743 + + #endif
+ 744 + + {
+ 745 + + BOOST_ASSERT( w.p_ );
+ 746 + + T const* pt = reinterpret_cast<T const*>(w.p_);
+ 747 + + has_value = static_cast<bool>(*pt);
+ 748 + + if( has_value )
+ 749 + + {
+ 750 + + w.p_ = std::addressof( *(*pt) );
+ 751 + + done = write_impl<Elem, true>(w, ss);
+ 752 + + }
+ 753 + + else
+ 754 + + {
+ 755 + + w.p_ = nullptr;
+ 756 + + done = write_impl<std::nullptr_t, true>(w, ss);;
+ 757 + + }
+ 758 + + }
+ 759 + + else
+ 760 + + {
+ 761 + + w.st_.pop(has_value);
+ 762 + +
+ 763 + + if( has_value )
+ 764 + + done = write_impl<Elem, false>(w, ss);
+ 765 + + else
+ 766 + + done = write_impl<std::nullptr_t, false>(w, ss);
+ 767 + + }
+ 768 + +
+ 769 + + if(BOOST_JSON_UNLIKELY( !done ))
+ 770 + + w.st_.push(has_value);
+ 771 + +
+ 772 + + return done;
+ 773 + + }
+ 774 + +
+ 775 + + template<class T, bool StackEmpty>
+ 776 + + BOOST_FORCEINLINE
+ 777 + + bool
+ 778 + + write_impl(path_conversion_tag, writer& w, stream& ss)
+ 779 + + {
+ 780 + + #if defined(_MSC_VER)
+ 781 + + # pragma warning( push )
+ 782 + + # pragma warning( disable : 4127 )
+ 783 + + #endif
+ 784 + + if(StackEmpty || w.st_.empty())
+ 785 + + #if defined(_MSC_VER)
+ 786 + + # pragma warning( pop )
+ 787 + + #endif
+ 788 + + {
+ 789 + + BOOST_ASSERT( w.p_ );
+ 790 + + T const* pt = reinterpret_cast<T const*>(w.p_);
+ 791 + +
+ 792 + + std::string const s = pt->generic_string();
+ 793 + + w.cs0_ = { s.data(), s.size() };
+ 794 + + if(BOOST_JSON_LIKELY( write_string(w, ss) ))
+ 795 + + return true;
+ 796 + +
+ 797 + + std::size_t const used = w.cs0_.used( s.data() );
+ 798 + + w.st_.push( used );
+ 799 + + w.st_.push( std::move(s) );
+ 800 + + return false;
+ 801 + + }
+ 802 + + else
+ 803 + + {
+ 804 + + std::string s;
+ 805 + + std::size_t used;
+ 806 + + w.st_.pop( s );
+ 807 + + w.st_.pop( used );
+ 808 + +
+ 809 + + w.cs0_ = { s.data(), s.size() };
+ 810 + + w.cs0_.skip(used);
+ 811 + +
+ 812 + + if(BOOST_JSON_LIKELY( resume_string(w, ss) ))
+ 813 + + return true;
+ 814 + +
+ 815 + + used = w.cs0_.used( s.data() );
+ 816 + + w.st_.push( used );
+ 817 + + w.st_.push( std::move(s) );
+ 818 + + return false;
+ 819 + + }
+ 820 + + }
+ 821 + +
+ 822 + + template<class T, bool StackEmpty>
+ 823 + + bool
+ 824 + +35604 write_impl(writer& w, stream& ss)
+ 825 + + {
+ 826 + + using cat = detail::generic_conversion_category<T>;
+ 827 + +35603 return write_impl<T, StackEmpty>( cat(), w, ss );
+ 828 + + }
+ 829 + +
+ 830 + + } // namespace detail
+ 831 + +
+ 832 + + template<class T>
+ 833 + + void
+ 834 + +219 serializer::reset(T const* p) noexcept
+ 835 + + {
+ 836 + + BOOST_CORE_STATIC_ASSERT( !std::is_pointer<T>::value );
+ 837 + + BOOST_CORE_STATIC_ASSERT( std::is_object<T>::value );
+ 838 + +
+ 839 + +219 p_ = p;
+ 840 + +219 fn0_ = &detail::write_impl<T, true>;
+ 841 + +219 fn1_ = &detail::write_impl<T, false>;
+ 842 + +219 st_.clear();
+ 843 + +219 done_ = false;
+ 844 + +219 }
+ 845 + +
+ 846 + + } // namespace json
+ 847 + + } // namespace boost
+ 848 + +
+ 849 + + #endif // BOOST_JSON_IMPL_SERIALIZER_HPP
+ 850 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.serializer.ipp.a6e01f5c62a1e98844cee0136d1d1512.html b/json/gcovr/index.serializer.ipp.a6e01f5c62a1e98844cee0136d1d1512.html new file mode 100644 index 00000000..c085661b --- /dev/null +++ b/json/gcovr/index.serializer.ipp.a6e01f5c62a1e98844cee0136d1d1512.html @@ -0,0 +1,6662 @@ + + + + + + impl/serializer.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/serializer.ipp

+
+ + 100.0% Lines (261/261) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/serializer.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_SERIALIZER_IPP
+ 11 + + #define BOOST_JSON_IMPL_SERIALIZER_IPP
+ 12 + +
+ 13 + + #include <boost/core/detail/static_assert.hpp>
+ 14 + + #include <boost/json/serializer.hpp>
+ 15 + + #include <boost/json/detail/format.hpp>
+ 16 + + #include <boost/json/detail/sse2.hpp>
+ 17 + +
+ 18 + + #ifdef _MSC_VER
+ 19 + + #pragma warning(push)
+ 20 + + #pragma warning(disable: 4127) // conditional expression is constant
+ 21 + + #endif
+ 22 + +
+ 23 + + namespace boost {
+ 24 + + namespace json {
+ 25 + + namespace detail {
+ 26 + +
+ 27 + + struct int64_formatter
+ 28 + + {
+ 29 + + std::int64_t i;
+ 30 + +
+ 31 + + std::size_t
+ 32 + +3188 operator()(char* dst) const noexcept
+ 33 + + {
+ 34 + +3188 return format_int64(dst, i);
+ 35 + + }
+ 36 + + };
+ 37 + +
+ 38 + + struct uint64_formatter
+ 39 + + {
+ 40 + + std::uint64_t u;
+ 41 + +
+ 42 + + std::size_t
+ 43 + +425 operator()(char* dst) const noexcept
+ 44 + + {
+ 45 + +425 return format_uint64(dst, u);
+ 46 + + }
+ 47 + + };
+ 48 + +
+ 49 + + struct double_formatter
+ 50 + + {
+ 51 + + double d;
+ 52 + + bool allow_infinity_and_nan;
+ 53 + +
+ 54 + + std::size_t
+ 55 + +477 operator()(char* dst) const noexcept
+ 56 + + {
+ 57 + +477 return format_double(dst, d, allow_infinity_and_nan);
+ 58 + + }
+ 59 + + };
+ 60 + +
+ 61 + +21245 writer::
+ 62 + + writer(
+ 63 + + storage_ptr sp,
+ 64 + + unsigned char* buf,
+ 65 + + std::size_t buf_size,
+ 66 + +21245 serialize_options const& opts) noexcept
+ 67 + +21245 : st_(
+ 68 + +21245 std::move(sp),
+ 69 + + buf,
+ 70 + + buf_size)
+ 71 + +21245 , opts_(opts)
+ 72 + + {
+ 73 + + // ensure room for \uXXXX escape plus one
+ 74 + + BOOST_CORE_STATIC_ASSERT( sizeof(buf_) >= 7 );
+ 75 + +21245 }
+ 76 + +
+ 77 + + bool
+ 78 + + BOOST_FORCEINLINE
+ 79 + + write_buffer(writer& w, stream& ss0)
+ 80 + + {
+ 81 + +1444 local_stream ss(ss0);
+ 82 + +2578 auto const n = ss.remain();
+ 83 + +2578 if( n < w.cs0_.remain() )
+ 84 + + {
+ 85 + +1334 ss.append(w.cs0_.data(), n);
+ 86 + +1334 w.cs0_.skip(n);
+ 87 + +1334 return w.suspend(writer::state::lit);
+ 88 + + }
+ 89 + +1244 ss.append( w.cs0_.data(), w.cs0_.remain() );
+ 90 + +1244 return true;
+ 91 + +2578 }
+ 92 + +
+ 93 + + template< class F >
+ 94 + + bool
+ 95 + +4090 write_buffer(writer& w, stream& ss0, F f)
+ 96 + + {
+ 97 + +4090 BOOST_ASSERT( w.st_.empty() );
+ 98 + +
+ 99 + +4090 local_stream ss(ss0);
+ 100 + +4090 if(BOOST_JSON_LIKELY( ss.remain() >= detail::max_number_chars ))
+ 101 + + {
+ 102 + +2956 ss.advance( f(ss.data()) );
+ 103 + +2956 return true;
+ 104 + + }
+ 105 + +
+ 106 + +1134 w.cs0_ = { w.buf_, f(w.buf_) };
+ 107 + +1134 return write_buffer(w, ss);
+ 108 + +4090 }
+ 109 + +
+ 110 + + template<literals Lit>
+ 111 + + bool
+ 112 + +4725 write_literal(writer& w, stream& ss)
+ 113 + + {
+ 114 + +4725 constexpr std::size_t index = literal_index(Lit);
+ 115 + +4725 constexpr char const* literal = literal_strings[index];
+ 116 + +4725 constexpr std::size_t sz = literal_sizes[index];
+ 117 + +
+ 118 + +4725 std::size_t const n = ss.remain();
+ 119 + +4725 if(BOOST_JSON_LIKELY( n >= sz ))
+ 120 + + {
+ 121 + +4613 ss.append( literal, sz );
+ 122 + +4613 return true;
+ 123 + + }
+ 124 + +
+ 125 + +112 ss.append(literal, n);
+ 126 + +
+ 127 + +112 w.cs0_ = {literal + n, sz - n};
+ 128 + +112 return w.suspend(writer::state::lit);
+ 129 + + }
+ 130 + +
+ 131 + + bool
+ 132 + +197 write_true(writer& w, stream& ss)
+ 133 + + {
+ 134 + +197 return write_literal<literals::true_>(w, ss);
+ 135 + + }
+ 136 + +
+ 137 + + bool
+ 138 + +176 write_false(writer& w, stream& ss)
+ 139 + + {
+ 140 + +176 return write_literal<literals::false_>(w, ss);
+ 141 + + }
+ 142 + +
+ 143 + + bool
+ 144 + +4352 write_null(writer& w, stream& ss)
+ 145 + + {
+ 146 + +4352 return write_literal<literals::null>(w, ss);
+ 147 + + }
+ 148 + +
+ 149 + + bool
+ 150 + +3188 write_int64(writer& w, stream& ss0, std::int64_t i)
+ 151 + + {
+ 152 + +3188 return write_buffer( w, ss0, int64_formatter{i} );
+ 153 + + }
+ 154 + +
+ 155 + + bool
+ 156 + +425 write_uint64(writer& w, stream& ss0, std::uint64_t u)
+ 157 + + {
+ 158 + +425 return write_buffer( w, ss0, uint64_formatter{u} );
+ 159 + + }
+ 160 + +
+ 161 + + bool
+ 162 + +477 write_double(writer& w, stream& ss0, double d)
+ 163 + + {
+ 164 + +954 return write_buffer(
+ 165 + +477 w, ss0, double_formatter{d, w.opts_.allow_infinity_and_nan} );
+ 166 + + }
+ 167 + +
+ 168 + + bool
+ 169 + +1444 resume_buffer(writer& w, stream& ss0)
+ 170 + + {
+ 171 + +1444 BOOST_ASSERT( !w.st_.empty() );
+ 172 + + writer::state st;
+ 173 + +1444 w.st_.pop(st);
+ 174 + +1444 BOOST_ASSERT(st == writer::state::lit);
+ 175 + +
+ 176 + +2888 return write_buffer(w, ss0);
+ 177 + + }
+ 178 + +
+ 179 + + template<bool StackEmpty>
+ 180 + + bool
+ 181 + +44285 do_write_string(writer& w, stream& ss0)
+ 182 + + {
+ 183 + +44285 local_stream ss(ss0);
+ 184 + +44285 local_const_stream cs(w.cs0_);
+ 185 + +9812 if(! StackEmpty && ! w.st_.empty())
+ 186 + + {
+ 187 + + writer::state st;
+ 188 + +9812 w.st_.pop(st);
+ 189 + +9812 switch(st)
+ 190 + + {
+ 191 + +170 default:
+ 192 + +170 case writer::state::str1: goto do_str1;
+ 193 + +268 case writer::state::str2: goto do_str2;
+ 194 + +9082 case writer::state::str3: goto do_str3;
+ 195 + +52 case writer::state::esc1: goto do_esc1;
+ 196 + +48 case writer::state::utf1: goto do_utf1;
+ 197 + +48 case writer::state::utf2: goto do_utf2;
+ 198 + +48 case writer::state::utf3: goto do_utf3;
+ 199 + +48 case writer::state::utf4: goto do_utf4;
+ 200 + +48 case writer::state::utf5: goto do_utf5;
+ 201 + + }
+ 202 + + }
+ 203 + + static constexpr char hex[] = "0123456789abcdef";
+ 204 + + static constexpr char esc[] =
+ 205 + + "uuuuuuuubtnufruuuuuuuuuuuuuuuuuu"
+ 206 + + "\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ 207 + + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0"
+ 208 + + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ 209 + + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ 210 + + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ 211 + + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ 212 + + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+ 213 + +
+ 214 + + // opening quote
+ 215 + +34473 do_str1:
+ 216 + +34643 if(BOOST_JSON_LIKELY(ss))
+ 217 + +34473 ss.append('\x22'); // '"'
+ 218 + + else
+ 219 + +170 return w.suspend(writer::state::str1);
+ 220 + +
+ 221 + + // fast loop,
+ 222 + + // copy unescaped
+ 223 + +34741 do_str2:
+ 224 + +34741 if(BOOST_JSON_LIKELY(ss))
+ 225 + + {
+ 226 + +34485 std::size_t n = cs.remain();
+ 227 + +34485 if(BOOST_JSON_LIKELY(n > 0))
+ 228 + + {
+ 229 + +34441 if(ss.remain() > n)
+ 230 + +25766 n = detail::count_unescaped(
+ 231 + + cs.data(), n);
+ 232 + + else
+ 233 + +8675 n = detail::count_unescaped(
+ 234 + + cs.data(), ss.remain());
+ 235 + +34441 if(n > 0)
+ 236 + + {
+ 237 + +25225 ss.append(cs.data(), n);
+ 238 + +25225 cs.skip(n);
+ 239 + +25225 if(! ss)
+ 240 + +12 return w.suspend(writer::state::str2);
+ 241 + + }
+ 242 + + }
+ 243 + + else
+ 244 + + {
+ 245 + +44 ss.append('\x22'); // '"'
+ 246 + +44 return true;
+ 247 + + }
+ 248 + + }
+ 249 + + else
+ 250 + + {
+ 251 + +256 return w.suspend(writer::state::str2);
+ 252 + + }
+ 253 + +
+ 254 + + // slow loop,
+ 255 + + // handle escapes
+ 256 + +43707 do_str3:
+ 257 + +31461016 while(BOOST_JSON_LIKELY(ss))
+ 258 + + {
+ 259 + +31451934 if(BOOST_JSON_LIKELY(cs))
+ 260 + + {
+ 261 + +31417505 auto const ch = *cs;
+ 262 + +31417505 auto const c = esc[static_cast<
+ 263 + + unsigned char>(ch)];
+ 264 + +31417505 ++cs;
+ 265 + +31417505 if(! c)
+ 266 + + {
+ 267 + +31416777 ss.append(ch);
+ 268 + + }
+ 269 + +728 else if(c != 'u')
+ 270 + + {
+ 271 + +376 ss.append('\\');
+ 272 + +376 if(BOOST_JSON_LIKELY(ss))
+ 273 + + {
+ 274 + +324 ss.append(c);
+ 275 + + }
+ 276 + + else
+ 277 + + {
+ 278 + +52 w.buf_[0] = c;
+ 279 + +52 return w.suspend(
+ 280 + +52 writer::state::esc1);
+ 281 + + }
+ 282 + + }
+ 283 + + else
+ 284 + + {
+ 285 + +352 if(BOOST_JSON_LIKELY(
+ 286 + + ss.remain() >= 6))
+ 287 + + {
+ 288 + +208 ss.append("\\u00", 4);
+ 289 + +208 ss.append(hex[static_cast<
+ 290 + +208 unsigned char>(ch) >> 4]);
+ 291 + +208 ss.append(hex[static_cast<
+ 292 + +208 unsigned char>(ch) & 15]);
+ 293 + + }
+ 294 + + else
+ 295 + + {
+ 296 + +144 ss.append('\\');
+ 297 + +144 w.buf_[0] = hex[static_cast<
+ 298 + +144 unsigned char>(ch) >> 4];
+ 299 + +144 w.buf_[1] = hex[static_cast<
+ 300 + +144 unsigned char>(ch) & 15];
+ 301 + +144 goto do_utf1;
+ 302 + + }
+ 303 + + }
+ 304 + + }
+ 305 + + else
+ 306 + + {
+ 307 + +34429 ss.append('\x22'); // '"'
+ 308 + +34429 return true;
+ 309 + + }
+ 310 + + }
+ 311 + +9082 return w.suspend(writer::state::str3);
+ 312 + +
+ 313 + +52 do_esc1:
+ 314 + +52 BOOST_ASSERT(ss);
+ 315 + +52 ss.append(w.buf_[0]);
+ 316 + +52 goto do_str3;
+ 317 + +
+ 318 + +192 do_utf1:
+ 319 + +192 if(BOOST_JSON_LIKELY(ss))
+ 320 + +144 ss.append('u');
+ 321 + + else
+ 322 + +48 return w.suspend(writer::state::utf1);
+ 323 + +192 do_utf2:
+ 324 + +192 if(BOOST_JSON_LIKELY(ss))
+ 325 + +144 ss.append('0');
+ 326 + + else
+ 327 + +48 return w.suspend(writer::state::utf2);
+ 328 + +192 do_utf3:
+ 329 + +192 if(BOOST_JSON_LIKELY(ss))
+ 330 + +144 ss.append('0');
+ 331 + + else
+ 332 + +48 return w.suspend(writer::state::utf3);
+ 333 + +192 do_utf4:
+ 334 + +192 if(BOOST_JSON_LIKELY(ss))
+ 335 + +144 ss.append(w.buf_[0]);
+ 336 + + else
+ 337 + +48 return w.suspend(writer::state::utf4);
+ 338 + +192 do_utf5:
+ 339 + +192 if(BOOST_JSON_LIKELY(ss))
+ 340 + +144 ss.append(w.buf_[1]);
+ 341 + + else
+ 342 + +48 return w.suspend(writer::state::utf5);
+ 343 + +144 goto do_str3;
+ 344 + +44285 }
+ 345 + +
+ 346 + + bool
+ 347 + +19827 write_string(writer& w, stream& ss0)
+ 348 + + {
+ 349 + +19827 return do_write_string<true>(w, ss0);
+ 350 + + }
+ 351 + +
+ 352 + + bool
+ 353 + +408 resume_string(writer& w, stream& ss0)
+ 354 + + {
+ 355 + +408 return do_write_string<false>(w, ss0);
+ 356 + + }
+ 357 + +
+ 358 + + template<bool StackEmpty>
+ 359 + + bool
+ 360 + + write_value(writer& w, stream& ss);
+ 361 + +
+ 362 + + template< class T, bool StackEmpty >
+ 363 + + BOOST_FORCEINLINE
+ 364 + + bool
+ 365 + + write_impl(no_conversion_tag, writer& w, stream& ss)
+ 366 + + {
+ 367 + +34536 return write_value<StackEmpty>(w, ss);
+ 368 + + }
+ 369 + +
+ 370 + + template<bool StackEmpty>
+ 371 + + bool
+ 372 + +6041 write_array(writer& w, stream& ss)
+ 373 + + {
+ 374 + +6040 return write_impl<array, StackEmpty>(sequence_conversion_tag(), w, ss);
+ 375 + + }
+ 376 + +
+ 377 + + template<bool StackEmpty>
+ 378 + + bool
+ 379 + +27194 write_object(writer& w, stream& ss)
+ 380 + + {
+ 381 + +27194 return write_impl<object, StackEmpty>(map_like_conversion_tag(), w, ss);
+ 382 + + }
+ 383 + +
+ 384 + + template<bool StackEmpty>
+ 385 + + bool
+ 386 + +66927 write_value(writer& w, stream& ss)
+ 387 + + {
+ 388 + +22905 if(StackEmpty || w.st_.empty())
+ 389 + + {
+ 390 + +44503 BOOST_ASSERT( w.p_ );
+ 391 + +44503 auto const pv = reinterpret_cast<value const*>(w.p_);
+ 392 + +44503 switch(pv->kind())
+ 393 + + {
+ 394 + +18083 default:
+ 395 + + case kind::object:
+ 396 + +18083 w.p_ = &pv->get_object();
+ 397 + +18083 return write_object<true>(w, ss);
+ 398 + +
+ 399 + +3400 case kind::array:
+ 400 + +3400 w.p_ = &pv->get_array();
+ 401 + +3400 return write_array<true>(w, ss);
+ 402 + +
+ 403 + +14643 case kind::string:
+ 404 + + {
+ 405 + +14643 auto const& js = pv->get_string();
+ 406 + +14643 w.cs0_ = { js.data(), js.size() };
+ 407 + +14643 return do_write_string<true>(w, ss);
+ 408 + + }
+ 409 + +
+ 410 + +3182 case kind::int64:
+ 411 + +3182 return write_int64( w, ss, pv->get_int64() );
+ 412 + +91 case kind::uint64:
+ 413 + +91 return write_uint64( w, ss, pv->get_uint64() );
+ 414 + +467 case kind::double_:
+ 415 + +467 return write_double( w, ss, pv->get_double() );
+ 416 + +
+ 417 + +306 case kind::bool_:
+ 418 + +306 if( pv->get_bool() )
+ 419 + +139 return write_true(w, ss);
+ 420 + + else
+ 421 + +167 return write_false(w, ss);
+ 422 + +
+ 423 + +4331 case kind::null:
+ 424 + +4331 return write_null(w, ss);
+ 425 + + }
+ 426 + + }
+ 427 + + else
+ 428 + + {
+ 429 + + writer::state st;
+ 430 + +22424 w.st_.peek(st);
+ 431 + +22424 switch(st)
+ 432 + + {
+ 433 + +1324 default:
+ 434 + + case writer::state::lit:
+ 435 + +1324 return resume_buffer(w, ss);
+ 436 + +
+ 437 + +9404 case writer::state::str1: case writer::state::str2:
+ 438 + + case writer::state::str3: case writer::state::esc1:
+ 439 + + case writer::state::utf1: case writer::state::utf2:
+ 440 + + case writer::state::utf3: case writer::state::utf4:
+ 441 + + case writer::state::utf5:
+ 442 + +9404 return do_write_string<false>(w, ss);
+ 443 + +
+ 444 + +2636 case writer::state::arr1: case writer::state::arr2:
+ 445 + + case writer::state::arr3: case writer::state::arr4:
+ 446 + +2636 return write_array<StackEmpty>(w, ss);
+ 447 + +
+ 448 + +9060 case writer::state::obj1: case writer::state::obj2:
+ 449 + + case writer::state::obj3: case writer::state::obj4:
+ 450 + + case writer::state::obj5: case writer::state::obj6:
+ 451 + +9060 return write_object<StackEmpty>(w, ss);
+ 452 + + }
+ 453 + + }
+ 454 + + }
+ 455 + +
+ 456 + + } // namespace detail
+ 457 + +
+ 458 + +2348 serializer::
+ 459 + +2348 serializer(serialize_options const& opts) noexcept
+ 460 + +2348 : serializer({}, nullptr, 0, opts)
+ 461 + +2348 {}
+ 462 + +
+ 463 + +21245 serializer::
+ 464 + + serializer(
+ 465 + + storage_ptr sp,
+ 466 + + unsigned char* buf,
+ 467 + + std::size_t buf_size,
+ 468 + +21245 serialize_options const& opts) noexcept
+ 469 + +21245 : detail::writer(std::move(sp), buf, buf_size, opts)
+ 470 + +21245 {}
+ 471 + +
+ 472 + + void
+ 473 + +20961 serializer::
+ 474 + + reset(value const* p) noexcept
+ 475 + + {
+ 476 + +20961 p_ = p;
+ 477 + +20961 fn0_ = &detail::write_value<true>;
+ 478 + +20961 fn1_ = &detail::write_value<false>;
+ 479 + +20961 st_.clear();
+ 480 + +20961 done_ = false;
+ 481 + +20961 }
+ 482 + +
+ 483 + + void
+ 484 + +5 serializer::
+ 485 + + reset(array const* p) noexcept
+ 486 + + {
+ 487 + +5 p_ = p;
+ 488 + +5 fn0_ = &detail::write_array<true>;
+ 489 + +5 fn1_ = &detail::write_array<false>;
+ 490 + +5 st_.clear();
+ 491 + +5 done_ = false;
+ 492 + +5 }
+ 493 + +
+ 494 + + void
+ 495 + +51 serializer::
+ 496 + + reset(object const* p) noexcept
+ 497 + + {
+ 498 + +51 p_ = p;
+ 499 + +51 fn0_ = &detail::write_object<true>;
+ 500 + +51 fn1_ = &detail::write_object<false>;
+ 501 + +51 st_.clear();
+ 502 + +51 done_ = false;
+ 503 + +51 }
+ 504 + +
+ 505 + + void
+ 506 + +2 serializer::
+ 507 + + reset(string const* p) noexcept
+ 508 + + {
+ 509 + +2 cs0_ = { p->data(), p->size() };
+ 510 + +2 fn0_ = &detail::do_write_string<true>;
+ 511 + +2 fn1_ = &detail::do_write_string<false>;
+ 512 + +2 st_.clear();
+ 513 + +2 done_ = false;
+ 514 + +2 }
+ 515 + +
+ 516 + + void
+ 517 + +1 serializer::
+ 518 + + reset(string_view sv) noexcept
+ 519 + + {
+ 520 + +1 cs0_ = { sv.data(), sv.size() };
+ 521 + +1 fn0_ = &detail::do_write_string<true>;
+ 522 + +1 fn1_ = &detail::do_write_string<false>;
+ 523 + +1 st_.clear();
+ 524 + +1 done_ = false;
+ 525 + +1 }
+ 526 + +
+ 527 + + void
+ 528 + +6 serializer::reset(std::nullptr_t) noexcept
+ 529 + + {
+ 530 + +6 p_ = nullptr;
+ 531 + +6 fn0_ = &detail::write_impl<std::nullptr_t, true>;
+ 532 + +6 fn1_ = &detail::write_impl<std::nullptr_t, false>;
+ 533 + +6 st_.clear();
+ 534 + +6 done_ = false;
+ 535 + +6 }
+ 536 + +
+ 537 + + string_view
+ 538 + +32983 serializer::
+ 539 + + read(char* dest, std::size_t size)
+ 540 + + {
+ 541 + +32983 if( !fn0_ )
+ 542 + +6 reset(nullptr);
+ 543 + +
+ 544 + +32983 if(BOOST_JSON_UNLIKELY(size == 0))
+ 545 + +1 return {dest, 0};
+ 546 + +
+ 547 + +32982 detail::stream ss(dest, size);
+ 548 + +32982 if(st_.empty())
+ 549 + +21244 fn0_(*this, ss);
+ 550 + + else
+ 551 + +11738 fn1_(*this, ss);
+ 552 + +32980 if(st_.empty())
+ 553 + + {
+ 554 + +21242 done_ = true;
+ 555 + +21242 fn0_ = nullptr;
+ 556 + +21242 p_ = nullptr;
+ 557 + + }
+ 558 + +32980 return string_view(
+ 559 + +32980 dest, ss.used(dest));
+ 560 + + }
+ 561 + +
+ 562 + + } // namespace json
+ 563 + + } // namespace boost
+ 564 + +
+ 565 + + #ifdef _MSC_VER
+ 566 + + #pragma warning(pop)
+ 567 + + #endif
+ 568 + +
+ 569 + + #endif
+ 570 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.shared_resource.hpp.1927ca08c89a37cdfbf293076af47ff7.html b/json/gcovr/index.shared_resource.hpp.1927ca08c89a37cdfbf293076af47ff7.html new file mode 100644 index 00000000..65964ec2 --- /dev/null +++ b/json/gcovr/index.shared_resource.hpp.1927ca08c89a37cdfbf293076af47ff7.html @@ -0,0 +1,2806 @@ + + + + + + detail/shared_resource.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/shared_resource.hpp

+
+ + 100.0% Lines (9/9) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/shared_resource.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_SHARED_RESOURCE_HPP
+ 11 + + #define BOOST_JSON_DETAIL_SHARED_RESOURCE_HPP
+ 12 + +
+ 13 + + #include <boost/container/pmr/memory_resource.hpp>
+ 14 + + #include <atomic>
+ 15 + + #include <utility>
+ 16 + +
+ 17 + + namespace boost {
+ 18 + + namespace json {
+ 19 + + namespace detail {
+ 20 + +
+ 21 + + #ifdef _MSC_VER
+ 22 + + #pragma warning(push)
+ 23 + + #pragma warning(disable: 4275) // non dll-interface class used as base for dll-interface class
+ 24 + + #endif
+ 25 + +
+ 26 + + struct BOOST_SYMBOL_VISIBLE
+ 27 + + shared_resource
+ 28 + + : container::pmr::memory_resource
+ 29 + + {
+ 30 + + BOOST_JSON_DECL
+ 31 + + shared_resource();
+ 32 + +
+ 33 + + BOOST_JSON_DECL
+ 34 + + ~shared_resource();
+ 35 + +
+ 36 + + std::atomic<std::size_t> refs{ 1 };
+ 37 + + };
+ 38 + +
+ 39 + + template<class T>
+ 40 + + class shared_resource_impl final
+ 41 + + : public shared_resource
+ 42 + + {
+ 43 + + T t;
+ 44 + +
+ 45 + + public:
+ 46 + + template<class... Args>
+ 47 + +21 shared_resource_impl(
+ 48 + + Args&&... args)
+ 49 + +21 : t(std::forward<Args>(args)...)
+ 50 + + {
+ 51 + +21 }
+ 52 + +
+ 53 + + void*
+ 54 + +49 do_allocate(
+ 55 + + std::size_t n,
+ 56 + + std::size_t align) override
+ 57 + + {
+ 58 + +49 return t.allocate(n, align);
+ 59 + + }
+ 60 + +
+ 61 + + void
+ 62 + +49 do_deallocate(
+ 63 + + void* p,
+ 64 + + std::size_t n,
+ 65 + + std::size_t align) override
+ 66 + + {
+ 67 + +49 return t.deallocate(p, n, align);
+ 68 + + }
+ 69 + +
+ 70 + + bool
+ 71 + +12 do_is_equal(
+ 72 + + memory_resource const&) const noexcept override
+ 73 + + {
+ 74 + + // VFALCO Is always false ok?
+ 75 + +12 return false;
+ 76 + + }
+ 77 + + };
+ 78 + +
+ 79 + + #ifdef _MSC_VER
+ 80 + + #pragma warning(pop)
+ 81 + + #endif
+ 82 + +
+ 83 + + } // detail
+ 84 + + } // namespace json
+ 85 + + } // namespace boost
+ 86 + +
+ 87 + + #endif
+ 88 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.shared_resource.ipp.f07eb9144ccb01dab822bc01a22dda0d.html b/json/gcovr/index.shared_resource.ipp.f07eb9144ccb01dab822bc01a22dda0d.html new file mode 100644 index 00000000..6c41cec0 --- /dev/null +++ b/json/gcovr/index.shared_resource.ipp.f07eb9144ccb01dab822bc01a22dda0d.html @@ -0,0 +1,2406 @@ + + + + + + detail/impl/shared_resource.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/impl/shared_resource.ipp

+
+ + 100.0% Lines (6/6) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/impl/shared_resource.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_IMPL_SHARED_RESOURCE_IPP
+ 11 + + #define BOOST_JSON_DETAIL_IMPL_SHARED_RESOURCE_IPP
+ 12 + +
+ 13 + + #include <boost/json/detail/shared_resource.hpp>
+ 14 + +
+ 15 + + namespace boost {
+ 16 + + namespace json {
+ 17 + + namespace detail {
+ 18 + +
+ 19 + + // these are here so that ~memory_resource
+ 20 + + // is emitted in the library instead of
+ 21 + + // the user's TU.
+ 22 + +
+ 23 + +21 shared_resource::
+ 24 + +21 shared_resource()
+ 25 + + {
+ 26 + +21 }
+ 27 + +
+ 28 + +21 shared_resource::
+ 29 + +21 ~shared_resource()
+ 30 + + {
+ 31 + +21 }
+ 32 + +
+ 33 + + } // detail
+ 34 + + } // namespace json
+ 35 + + } // namespace boost
+ 36 + +
+ 37 + + #endif
+ 38 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.sse2.hpp.6a507d81ac7c10f52d533f58d85ac238.html b/json/gcovr/index.sse2.hpp.6a507d81ac7c10f52d533f58d85ac238.html new file mode 100644 index 00000000..bcc0fa5e --- /dev/null +++ b/json/gcovr/index.sse2.hpp.6a507d81ac7c10f52d533f58d85ac238.html @@ -0,0 +1,6478 @@ + + + + + + detail/sse2.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/sse2.hpp

+
+ + 97.8% Lines (134/137) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/sse2.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Peter Dimov (pdimov at gmail dot com),
+ 3 + + // Vinnie Falco (vinnie.falco@gmail.com)
+ 4 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 5 + + //
+ 6 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 7 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 8 + + //
+ 9 + + // Official repository: https://github.com/boostorg/json
+ 10 + + //
+ 11 + +
+ 12 + + #ifndef BOOST_JSON_DETAIL_SSE2_HPP
+ 13 + + #define BOOST_JSON_DETAIL_SSE2_HPP
+ 14 + +
+ 15 + + #include <boost/json/detail/config.hpp>
+ 16 + + #include <boost/json/detail/utf8.hpp>
+ 17 + + #include <cstddef>
+ 18 + + #include <cstring>
+ 19 + + #ifdef BOOST_JSON_USE_SSE2
+ 20 + + # include <emmintrin.h>
+ 21 + + # include <xmmintrin.h>
+ 22 + + # ifdef _MSC_VER
+ 23 + + # include <intrin.h>
+ 24 + + # endif
+ 25 + + #endif
+ 26 + +
+ 27 + + namespace boost {
+ 28 + + namespace json {
+ 29 + + namespace detail {
+ 30 + +
+ 31 + + #ifdef BOOST_JSON_USE_SSE2
+ 32 + +
+ 33 + + template<bool AllowBadUTF8>
+ 34 + + inline
+ 35 + + const char*
+ 36 + +2177 count_valid(
+ 37 + + char const* p,
+ 38 + + const char* end) noexcept
+ 39 + + {
+ 40 + +2177 __m128i const q1 = _mm_set1_epi8( '\x22' ); // '"'
+ 41 + +2177 __m128i const q2 = _mm_set1_epi8( '\\' ); // '\\'
+ 42 + +2177 __m128i const q3 = _mm_set1_epi8( 0x1F );
+ 43 + +
+ 44 + +2415 while(end - p >= 16)
+ 45 + + {
+ 46 + +924 __m128i v1 = _mm_loadu_si128( (__m128i const*)p );
+ 47 + +924 __m128i v2 = _mm_cmpeq_epi8( v1, q1 ); // quote
+ 48 + +924 __m128i v3 = _mm_cmpeq_epi8( v1, q2 ); // backslash
+ 49 + +924 __m128i v4 = _mm_or_si128( v2, v3 ); // combine quotes and backslash
+ 50 + +924 __m128i v5 = _mm_min_epu8( v1, q3 );
+ 51 + +924 __m128i v6 = _mm_cmpeq_epi8( v5, v1 ); // controls
+ 52 + +924 __m128i v7 = _mm_or_si128( v4, v6 ); // combine with control
+ 53 + +
+ 54 + +924 int w = _mm_movemask_epi8( v7 );
+ 55 + +
+ 56 + +924 if( w != 0 )
+ 57 + + {
+ 58 + + int m;
+ 59 + + #if defined(__GNUC__) || defined(__clang__)
+ 60 + +686 m = __builtin_ffs( w ) - 1;
+ 61 + + #else
+ 62 + + unsigned long index;
+ 63 + + _BitScanForward( &index, w );
+ 64 + + m = index;
+ 65 + + #endif
+ 66 + +686 return p + m;
+ 67 + + }
+ 68 + +
+ 69 + +238 p += 16;
+ 70 + + }
+ 71 + +
+ 72 + +3738 while(p != end)
+ 73 + + {
+ 74 + +3689 const unsigned char c = *p;
+ 75 + +3689 if(c == '\x22' || c == '\\' || c < 0x20)
+ 76 + + break;
+ 77 + +2247 ++p;
+ 78 + + }
+ 79 + +
+ 80 + +1491 return p;
+ 81 + + }
+ 82 + +
+ 83 + + template<>
+ 84 + + inline
+ 85 + + const char*
+ 86 + +162602 count_valid<false>(
+ 87 + + char const* p,
+ 88 + + const char* end) noexcept
+ 89 + + {
+ 90 + +162602 __m128i const q1 = _mm_set1_epi8( '\x22' ); // '"'
+ 91 + +162602 __m128i const q2 = _mm_set1_epi8( '\\' );
+ 92 + +162602 __m128i const q3 = _mm_set1_epi8( 0x20 );
+ 93 + +
+ 94 + +12202131 while(end - p >= 16)
+ 95 + + {
+ 96 + +12090929 __m128i v1 = _mm_loadu_si128( (__m128i const*)p );
+ 97 + +
+ 98 + +12090929 __m128i v2 = _mm_cmpeq_epi8( v1, q1 );
+ 99 + +12090929 __m128i v3 = _mm_cmpeq_epi8( v1, q2 );
+ 100 + +12090929 __m128i v4 = _mm_cmplt_epi8( v1, q3 );
+ 101 + +
+ 102 + +12090929 __m128i v5 = _mm_or_si128( v2, v3 );
+ 103 + +12090929 __m128i v6 = _mm_or_si128( v5, v4 );
+ 104 + +
+ 105 + +12090929 int w = _mm_movemask_epi8( v6 );
+ 106 + +
+ 107 + +12090929 if( w != 0 )
+ 108 + + {
+ 109 + + int m;
+ 110 + + #if defined(__GNUC__) || defined(__clang__)
+ 111 + +51400 m = __builtin_ffs( w ) - 1;
+ 112 + + #else
+ 113 + + unsigned long index;
+ 114 + + _BitScanForward( &index, w );
+ 115 + + m = index;
+ 116 + + #endif
+ 117 + +51400 p += m;
+ 118 + +51400 break;
+ 119 + + }
+ 120 + +
+ 121 + +12039529 p += 16;
+ 122 + + }
+ 123 + +
+ 124 + +479946 while(p != end)
+ 125 + + {
+ 126 + +449775 const unsigned char c = *p;
+ 127 + +449775 if(c == '\x22' || c == '\\' || c < 0x20)
+ 128 + + break;
+ 129 + +320806 if(c < 0x80)
+ 130 + + {
+ 131 + +307616 ++p;
+ 132 + +307616 continue;
+ 133 + + }
+ 134 + + // validate utf-8
+ 135 + +13190 uint16_t first = classify_utf8(c);
+ 136 + +13190 uint8_t len = first & 0xFF;
+ 137 + +13190 if(BOOST_JSON_UNLIKELY(end - p < len))
+ 138 + +1905 break;
+ 139 + +11285 if(BOOST_JSON_UNLIKELY(! is_valid_utf8(p, first)))
+ 140 + +1557 break;
+ 141 + +9728 p += len;
+ 142 + + }
+ 143 + +
+ 144 + +162602 return p;
+ 145 + + }
+ 146 + +
+ 147 + + #else
+ 148 + +
+ 149 + + template<bool AllowBadUTF8>
+ 150 + + char const*
+ 151 + + count_valid(
+ 152 + + char const* p,
+ 153 + + char const* end) noexcept
+ 154 + + {
+ 155 + + while(p != end)
+ 156 + + {
+ 157 + + const unsigned char c = *p;
+ 158 + + if(c == '\x22' || c == '\\' || c < 0x20)
+ 159 + + break;
+ 160 + + ++p;
+ 161 + + }
+ 162 + +
+ 163 + + return p;
+ 164 + + }
+ 165 + +
+ 166 + + template<>
+ 167 + + inline
+ 168 + + char const*
+ 169 + + count_valid<false>(
+ 170 + + char const* p,
+ 171 + + char const* end) noexcept
+ 172 + + {
+ 173 + + while(p != end)
+ 174 + + {
+ 175 + + const unsigned char c = *p;
+ 176 + + if(c == '\x22' || c == '\\' || c < 0x20)
+ 177 + + break;
+ 178 + + if(c < 0x80)
+ 179 + + {
+ 180 + + ++p;
+ 181 + + continue;
+ 182 + + }
+ 183 + + // validate utf-8
+ 184 + + uint16_t first = classify_utf8(c);
+ 185 + + uint8_t len = first & 0xFF;
+ 186 + + if(BOOST_JSON_UNLIKELY(end - p < len))
+ 187 + + break;
+ 188 + + if(BOOST_JSON_UNLIKELY(! is_valid_utf8(p, first)))
+ 189 + + break;
+ 190 + + p += len;
+ 191 + + }
+ 192 + +
+ 193 + + return p;
+ 194 + + }
+ 195 + +
+ 196 + + #endif
+ 197 + +
+ 198 + + // KRYSTIAN NOTE: does not stop to validate
+ 199 + + // count_unescaped
+ 200 + +
+ 201 + + #ifdef BOOST_JSON_USE_SSE2
+ 202 + +
+ 203 + + inline
+ 204 + + size_t
+ 205 + +34441 count_unescaped(
+ 206 + + char const* s,
+ 207 + + size_t n) noexcept
+ 208 + + {
+ 209 + +
+ 210 + +34441 __m128i const q1 = _mm_set1_epi8( '\x22' ); // '"'
+ 211 + +34441 __m128i const q2 = _mm_set1_epi8( '\\' ); // '\\'
+ 212 + +34441 __m128i const q3 = _mm_set1_epi8( 0x1F );
+ 213 + +
+ 214 + +34441 char const * s0 = s;
+ 215 + +
+ 216 + +4096152 while( n >= 16 )
+ 217 + + {
+ 218 + +4061711 __m128i v1 = _mm_loadu_si128( (__m128i const*)s );
+ 219 + +4061711 __m128i v2 = _mm_cmpeq_epi8( v1, q1 ); // quote
+ 220 + +4061711 __m128i v3 = _mm_cmpeq_epi8( v1, q2 ); // backslash
+ 221 + +4061711 __m128i v4 = _mm_or_si128( v2, v3 ); // combine quotes and backslash
+ 222 + +4061711 __m128i v5 = _mm_min_epu8( v1, q3 );
+ 223 + +4061711 __m128i v6 = _mm_cmpeq_epi8( v5, v1 ); // controls
+ 224 + +4061711 __m128i v7 = _mm_or_si128( v4, v6 ); // combine with control
+ 225 + +
+ 226 + +4061711 int w = _mm_movemask_epi8( v7 );
+ 227 + +
+ 228 + +4061711 if( w != 0 )
+ 229 + + {
+ 230 + + int m;
+ 231 + + #if defined(__GNUC__) || defined(__clang__)
+ 232 + + m = __builtin_ffs( w ) - 1;
+ 233 + + #else
+ 234 + + unsigned long index;
+ 235 + + _BitScanForward( &index, w );
+ 236 + + m = index;
+ 237 + + #endif
+ 238 + +
+ 239 + + s += m;
+ 240 + + break;
+ 241 + + }
+ 242 + +
+ 243 + +4061711 s += 16;
+ 244 + +4061711 n -= 16;
+ 245 + + }
+ 246 + +
+ 247 + +34441 return s - s0;
+ 248 + + }
+ 249 + +
+ 250 + + #else
+ 251 + +
+ 252 + + inline
+ 253 + + std::size_t
+ 254 + + count_unescaped(
+ 255 + + char const*,
+ 256 + + std::size_t) noexcept
+ 257 + + {
+ 258 + + return 0;
+ 259 + + }
+ 260 + +
+ 261 + + #endif
+ 262 + +
+ 263 + + // count_digits
+ 264 + +
+ 265 + + #ifdef BOOST_JSON_USE_SSE2
+ 266 + +
+ 267 + + // assumes p..p+15 are valid
+ 268 + +2024516 inline int count_digits( char const* p ) noexcept
+ 269 + + {
+ 270 + +2024516 __m128i v1 = _mm_loadu_si128( (__m128i const*)p );
+ 271 + +4049032 v1 = _mm_add_epi8(v1, _mm_set1_epi8(70));
+ 272 + +4049032 v1 = _mm_cmplt_epi8(v1, _mm_set1_epi8(118));
+ 273 + +
+ 274 + +2024516 int m = _mm_movemask_epi8(v1);
+ 275 + +
+ 276 + + int n;
+ 277 + +
+ 278 + +2024516 if( m == 0 )
+ 279 + + {
+ 280 + +2012400 n = 16;
+ 281 + + }
+ 282 + + else
+ 283 + + {
+ 284 + + #if defined(__GNUC__) || defined(__clang__)
+ 285 + +12116 n = __builtin_ffs( m ) - 1;
+ 286 + + #else
+ 287 + + unsigned long index;
+ 288 + + _BitScanForward( &index, m );
+ 289 + + n = static_cast<int>(index);
+ 290 + + #endif
+ 291 + + }
+ 292 + +
+ 293 + +2024516 return n;
+ 294 + + }
+ 295 + +
+ 296 + + #else
+ 297 + +
+ 298 + + // assumes p..p+15 are valid
+ 299 + + inline int count_digits( char const* p ) noexcept
+ 300 + + {
+ 301 + + int n = 0;
+ 302 + +
+ 303 + + for( ; n < 16; ++n )
+ 304 + + {
+ 305 + + unsigned char const d = *p++ - '0';
+ 306 + + if(d > 9) break;
+ 307 + + }
+ 308 + +
+ 309 + + return n;
+ 310 + + }
+ 311 + +
+ 312 + + #endif
+ 313 + +
+ 314 + + // parse_unsigned
+ 315 + +
+ 316 + +2019313 inline uint64_t parse_unsigned( uint64_t r, char const * p, std::size_t n ) noexcept
+ 317 + + {
+ 318 + +10064473 while( n >= 4 )
+ 319 + + {
+ 320 + + // faster on on clang for x86,
+ 321 + + // slower on gcc
+ 322 + + #ifdef __clang__
+ 323 + + r = r * 10 + p[0] - '0';
+ 324 + + r = r * 10 + p[1] - '0';
+ 325 + + r = r * 10 + p[2] - '0';
+ 326 + + r = r * 10 + p[3] - '0';
+ 327 + + #else
+ 328 + + uint32_t v;
+ 329 + +8045160 std::memcpy( &v, p, 4 );
+ 330 + +8045160 endian::native_to_little_inplace(v);
+ 331 + +
+ 332 + +8045160 v -= 0x30303030;
+ 333 + +
+ 334 + +8045160 unsigned w0 = v & 0xFF;
+ 335 + +8045160 unsigned w1 = (v >> 8) & 0xFF;
+ 336 + +8045160 unsigned w2 = (v >> 16) & 0xFF;
+ 337 + +8045160 unsigned w3 = (v >> 24);
+ 338 + +
+ 339 + +8045160 r = (((r * 10 + w0) * 10 + w1) * 10 + w2) * 10 + w3;
+ 340 + + #endif
+ 341 + +8045160 p += 4;
+ 342 + +8045160 n -= 4;
+ 343 + + }
+ 344 + +
+ 345 + +2019313 switch( n )
+ 346 + + {
+ 347 + +2010658 case 0:
+ 348 + +2010658 break;
+ 349 + +5484 case 1:
+ 350 + +5484 r = r * 10 + p[0] - '0';
+ 351 + +5484 break;
+ 352 + +1714 case 2:
+ 353 + +1714 r = r * 10 + p[0] - '0';
+ 354 + +1714 r = r * 10 + p[1] - '0';
+ 355 + +1714 break;
+ 356 + +1457 case 3:
+ 357 + +1457 r = r * 10 + p[0] - '0';
+ 358 + +1457 r = r * 10 + p[1] - '0';
+ 359 + +1457 r = r * 10 + p[2] - '0';
+ 360 + +1457 break;
+ 361 + + }
+ 362 + +2019313 return r;
+ 363 + + }
+ 364 + +
+ 365 + + // KRYSTIAN: this function is unused
+ 366 + + // count_leading
+ 367 + +
+ 368 + + /*
+ 369 + + #ifdef BOOST_JSON_USE_SSE2
+ 370 + +
+ 371 + + // assumes p..p+15
+ 372 + + inline std::size_t count_leading( char const * p, char ch ) noexcept
+ 373 + + {
+ 374 + + __m128i const q1 = _mm_set1_epi8( ch );
+ 375 + +
+ 376 + + __m128i v = _mm_loadu_si128( (__m128i const*)p );
+ 377 + +
+ 378 + + __m128i w = _mm_cmpeq_epi8( v, q1 );
+ 379 + +
+ 380 + + int m = _mm_movemask_epi8( w ) ^ 0xFFFF;
+ 381 + +
+ 382 + + std::size_t n;
+ 383 + +
+ 384 + + if( m == 0 )
+ 385 + + {
+ 386 + + n = 16;
+ 387 + + }
+ 388 + + else
+ 389 + + {
+ 390 + + #if defined(__GNUC__) || defined(__clang__)
+ 391 + + n = __builtin_ffs( m ) - 1;
+ 392 + + #else
+ 393 + + unsigned long index;
+ 394 + + _BitScanForward( &index, m );
+ 395 + + n = index;
+ 396 + + #endif
+ 397 + + }
+ 398 + +
+ 399 + + return n;
+ 400 + + }
+ 401 + +
+ 402 + + #else
+ 403 + +
+ 404 + + // assumes p..p+15
+ 405 + + inline std::size_t count_leading( char const * p, char ch ) noexcept
+ 406 + + {
+ 407 + + std::size_t n = 0;
+ 408 + +
+ 409 + + for( ; n < 16 && *p == ch; ++p, ++n );
+ 410 + +
+ 411 + + return n;
+ 412 + + }
+ 413 + +
+ 414 + + #endif
+ 415 + + */
+ 416 + +
+ 417 + + // count_whitespace
+ 418 + +
+ 419 + + #ifdef BOOST_JSON_USE_SSE2
+ 420 + +
+ 421 + +4701007 inline const char* count_whitespace( char const* p, const char* end ) noexcept
+ 422 + + {
+ 423 + +4701007 if( p == end )
+ 424 + + {
+ 425 + +2133783 return p;
+ 426 + + }
+ 427 + +
+ 428 + +2567224 if( static_cast<unsigned char>( *p ) > 0x20 )
+ 429 + + {
+ 430 + +2484431 return p;
+ 431 + + }
+ 432 + +
+ 433 + +82793 __m128i const q1 = _mm_set1_epi8( ' ' );
+ 434 + +82793 __m128i const q2 = _mm_set1_epi8( '\n' );
+ 435 + +82793 __m128i const q3 = _mm_set1_epi8( 4 ); // '\t' | 4 == '\r'
+ 436 + +82793 __m128i const q4 = _mm_set1_epi8( '\r' );
+ 437 + +
+ 438 + +183300 while( end - p >= 16 )
+ 439 + + {
+ 440 + +105374 __m128i v0 = _mm_loadu_si128( (__m128i const*)p );
+ 441 + +
+ 442 + +316122 __m128i w0 = _mm_or_si128(
+ 443 + + _mm_cmpeq_epi8( v0, q1 ),
+ 444 + + _mm_cmpeq_epi8( v0, q2 ));
+ 445 + +105374 __m128i v1 = _mm_or_si128( v0, q3 );
+ 446 + +105374 __m128i w1 = _mm_cmpeq_epi8( v1, q4 );
+ 447 + +105374 __m128i w2 = _mm_or_si128( w0, w1 );
+ 448 + +
+ 449 + +105374 int m = _mm_movemask_epi8( w2 ) ^ 0xFFFF;
+ 450 + +
+ 451 + +105374 if( m != 0 )
+ 452 + + {
+ 453 + + #if defined(__GNUC__) || defined(__clang__)
+ 454 + +4867 std::size_t c = __builtin_ffs( m ) - 1;
+ 455 + + #else
+ 456 + + unsigned long index;
+ 457 + + _BitScanForward( &index, m );
+ 458 + + std::size_t c = index;
+ 459 + + #endif
+ 460 + +
+ 461 + +4867 p += c;
+ 462 + +4867 return p;
+ 463 + + }
+ 464 + +
+ 465 + +100507 p += 16;
+ 466 + + }
+ 467 + +
+ 468 + +462520 while( p != end )
+ 469 + + {
+ 470 + +401661 if( *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n' )
+ 471 + + {
+ 472 + +17067 return p;
+ 473 + + }
+ 474 + +
+ 475 + +384594 ++p;
+ 476 + + }
+ 477 + +
+ 478 + +60859 return p;
+ 479 + + }
+ 480 + +
+ 481 + + /*
+ 482 + +
+ 483 + + // slightly faster on msvc-14.2, slightly slower on clang-win
+ 484 + +
+ 485 + + inline std::size_t count_whitespace( char const * p, std::size_t n ) noexcept
+ 486 + + {
+ 487 + + char const * p0 = p;
+ 488 + +
+ 489 + + while( n > 0 )
+ 490 + + {
+ 491 + + char ch = *p;
+ 492 + +
+ 493 + + if( ch == '\n' || ch == '\r' )
+ 494 + + {
+ 495 + + ++p;
+ 496 + + --n;
+ 497 + + continue;
+ 498 + + }
+ 499 + +
+ 500 + + if( ch != ' ' && ch != '\t' )
+ 501 + + {
+ 502 + + break;
+ 503 + + }
+ 504 + +
+ 505 + + ++p;
+ 506 + + --n;
+ 507 + +
+ 508 + + while( n >= 16 )
+ 509 + + {
+ 510 + + std::size_t n2 = count_leading( p, ch );
+ 511 + +
+ 512 + + p += n2;
+ 513 + + n -= n2;
+ 514 + +
+ 515 + + if( n2 < 16 )
+ 516 + + {
+ 517 + + break;
+ 518 + + }
+ 519 + + }
+ 520 + + }
+ 521 + +
+ 522 + + return p - p0;
+ 523 + + }
+ 524 + + */
+ 525 + +
+ 526 + + #else
+ 527 + +
+ 528 + + inline const char* count_whitespace( char const* p, const char* end ) noexcept
+ 529 + + {
+ 530 + +
+ 531 + + for(; p != end; ++p)
+ 532 + + {
+ 533 + + char const c = *p;
+ 534 + + if( c != ' ' && c != '\n' && c != '\r' && c != '\t' ) break;
+ 535 + + }
+ 536 + +
+ 537 + + return p;
+ 538 + + }
+ 539 + +
+ 540 + + #endif
+ 541 + +
+ 542 + + } // detail
+ 543 + + } // namespace json
+ 544 + + } // namespace boost
+ 545 + +
+ 546 + + #endif
+ 547 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.stack.hpp.2c1d90a4d04ade6bea988474789a22e6.html b/json/gcovr/index.stack.hpp.2c1d90a4d04ade6bea988474789a22e6.html new file mode 100644 index 00000000..ed1aafe7 --- /dev/null +++ b/json/gcovr/index.stack.hpp.2c1d90a4d04ade6bea988474789a22e6.html @@ -0,0 +1,3110 @@ + + + + + + detail/stack.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/stack.hpp

+
+ + 100.0% Lines (13/13) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/stack.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_STACK_HPP
+ 11 + + #define BOOST_JSON_DETAIL_STACK_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/json/storage_ptr.hpp>
+ 15 + + #include <boost/mp11/integral.hpp>
+ 16 + + #include <cstring>
+ 17 + + #include <type_traits>
+ 18 + +
+ 19 + + namespace boost {
+ 20 + + namespace json {
+ 21 + + namespace detail {
+ 22 + +
+ 23 + + #if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
+ 24 + +
+ 25 + + template<class T>
+ 26 + + struct is_trivially_copy_assignable
+ 27 + + : mp11::mp_bool<
+ 28 + + std::is_copy_assignable<T>::value &&
+ 29 + + std::has_trivial_copy_assign<T>::value >
+ 30 + + {};
+ 31 + +
+ 32 + + #else
+ 33 + +
+ 34 + + using std::is_trivially_copy_assignable;
+ 35 + +
+ 36 + + #endif
+ 37 + +
+ 38 + + class stack
+ 39 + + {
+ 40 + + template< class T = void >
+ 41 + + struct non_trivial;
+ 42 + +
+ 43 + + storage_ptr sp_;
+ 44 + + std::size_t cap_ = 0;
+ 45 + + std::size_t size_ = 0;
+ 46 + + non_trivial<>* head_ = nullptr;
+ 47 + + unsigned char* base_ = nullptr;
+ 48 + + unsigned char* buf_ = nullptr;
+ 49 + +
+ 50 + + public:
+ 51 + + BOOST_JSON_DECL
+ 52 + + ~stack();
+ 53 + +
+ 54 + +2164605 stack() = default;
+ 55 + +
+ 56 + + stack(
+ 57 + + storage_ptr sp,
+ 58 + + unsigned char* buf,
+ 59 + + std::size_t buf_size) noexcept;
+ 60 + +
+ 61 + + bool
+ 62 + +3260464 empty() const noexcept
+ 63 + + {
+ 64 + +3260464 return size_ == 0;
+ 65 + + }
+ 66 + +
+ 67 + + BOOST_JSON_DECL
+ 68 + + void
+ 69 + + clear() noexcept;
+ 70 + +
+ 71 + + void
+ 72 + +173075 reserve(std::size_t n)
+ 73 + + {
+ 74 + +173075 if(n > cap_)
+ 75 + +115792 reserve_impl(n);
+ 76 + +173075 }
+ 77 + +
+ 78 + + template<class T>
+ 79 + + void
+ 80 + +47896 push(T&& t)
+ 81 + + {
+ 82 + + using U = remove_cvref<T>;
+ 83 + +47896 push( static_cast<T&&>(t), is_trivially_copy_assignable<U>() );
+ 84 + +47894 }
+ 85 + +
+ 86 + + template<class T>
+ 87 + + void
+ 88 + + push_unchecked(
+ 89 + + T const& t);
+ 90 + +
+ 91 + + template<class T>
+ 92 + + void
+ 93 + + peek(T& t);
+ 94 + +
+ 95 + + template<class T>
+ 96 + + void
+ 97 + +328590 pop(T& t)
+ 98 + + {
+ 99 + + using U = remove_cvref<T>;
+ 100 + +328590 pop( t, is_trivially_copy_assignable<U>() );
+ 101 + +328590 }
+ 102 + +
+ 103 + + private:
+ 104 + + template<class T> void push(
+ 105 + + T const& t, std::true_type);
+ 106 + + template<class T> void push(
+ 107 + + T&& t, std::false_type);
+ 108 + + template<class T> void pop(
+ 109 + + T& t, std::true_type);
+ 110 + + template<class T> void pop(
+ 111 + + T& t, std::false_type);
+ 112 + +
+ 113 + + BOOST_JSON_DECL
+ 114 + + void
+ 115 + + reserve_impl(
+ 116 + + std::size_t n);
+ 117 + + };
+ 118 + +
+ 119 + + } // detail
+ 120 + + } // namespace json
+ 121 + + } // namespace boost
+ 122 + +
+ 123 + + #include <boost/json/detail/impl/stack.hpp>
+ 124 + +
+ 125 + + #endif
+ 126 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.stack.hpp.c6cfbf398aba6b34d13f47ba0d19bf6a.html b/json/gcovr/index.stack.hpp.c6cfbf398aba6b34d13f47ba0d19bf6a.html new file mode 100644 index 00000000..3cb28130 --- /dev/null +++ b/json/gcovr/index.stack.hpp.c6cfbf398aba6b34d13f47ba0d19bf6a.html @@ -0,0 +1,3486 @@ + + + + + + detail/impl/stack.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/impl/stack.hpp

+
+ + 100.0% Lines (55/55) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/impl/stack.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_IMPL_STACK_HPP
+ 11 + + #define BOOST_JSON_DETAIL_IMPL_STACK_HPP
+ 12 + +
+ 13 + + #include <boost/core/detail/static_assert.hpp>
+ 14 + + #include <memory>
+ 15 + +
+ 16 + + namespace boost {
+ 17 + + namespace json {
+ 18 + + namespace detail {
+ 19 + +
+ 20 + + template<>
+ 21 + + struct stack::non_trivial<void>
+ 22 + + {
+ 23 + + using relocate_t = non_trivial* (*) (non_trivial*, void*);
+ 24 + +
+ 25 + + relocate_t rel;
+ 26 + + non_trivial* next;
+ 27 + + std::size_t offset;
+ 28 + +
+ 29 + + BOOST_JSON_DECL
+ 30 + + non_trivial<>*
+ 31 + + destroy() noexcept;
+ 32 + +
+ 33 + + BOOST_JSON_DECL
+ 34 + + non_trivial*
+ 35 + + relocate(void* dst) noexcept;
+ 36 + +
+ 37 + + protected:
+ 38 + + ~non_trivial() = default;
+ 39 + + };
+ 40 + +
+ 41 + + template< class T >
+ 42 + + struct stack::non_trivial
+ 43 + + : stack::non_trivial<void>
+ 44 + + {
+ 45 + + T obj;
+ 46 + +
+ 47 + + explicit
+ 48 + +4 non_trivial(T t, non_trivial<>* next, std::size_t offset)
+ 49 + +4 : non_trivial<void>{relocate, next, offset}, obj( std::move(t) )
+ 50 + +4 {}
+ 51 + +
+ 52 + + static
+ 53 + + non_trivial<>*
+ 54 + +4 relocate(non_trivial<>* src, void* dest) noexcept
+ 55 + + {
+ 56 + +4 non_trivial* self = static_cast<non_trivial*>(src);
+ 57 + +4 non_trivial<>* result = nullptr;
+ 58 + +4 if( dest )
+ 59 + +3 result = ::new(dest) non_trivial( std::move(*self) );
+ 60 + +4 self->~non_trivial();
+ 61 + +4 return result;
+ 62 + + }
+ 63 + + };
+ 64 + +
+ 65 + + template<class T>
+ 66 + + void
+ 67 + +332068 stack::
+ 68 + + push_unchecked(T const& t)
+ 69 + + {
+ 70 + +332068 constexpr std::size_t n = sizeof(T);
+ 71 + + BOOST_CORE_STATIC_ASSERT( is_trivially_copy_assignable<T>::value );
+ 72 + +332068 BOOST_ASSERT( n <= cap_ - size_ );
+ 73 + +332068 std::memcpy( base_ + size_, &t, n );
+ 74 + +332068 size_ += n;
+ 75 + +332068 }
+ 76 + +
+ 77 + + template<class T>
+ 78 + + void
+ 79 + +795418 stack::
+ 80 + + peek(T& t)
+ 81 + + {
+ 82 + +795418 constexpr std::size_t n = sizeof(T);
+ 83 + + BOOST_CORE_STATIC_ASSERT( is_trivially_copy_assignable<T>::value );
+ 84 + +795418 BOOST_ASSERT( size_ >= n );
+ 85 + +795418 std::memcpy( &t, base_ + size_ - n, n );
+ 86 + +795418 }
+ 87 + +
+ 88 + + //--------------------------------------
+ 89 + +
+ 90 + + // trivial
+ 91 + + template<class T>
+ 92 + + void
+ 93 + +47892 stack::
+ 94 + + push(T const& t, std::true_type)
+ 95 + + {
+ 96 + +47892 if( sizeof(T) > cap_ - size_ )
+ 97 + +8953 reserve_impl( sizeof(T) + size_ );
+ 98 + +47890 push_unchecked(t);
+ 99 + +47890 }
+ 100 + +
+ 101 + + // non-trivial
+ 102 + + template<class T>
+ 103 + + void
+ 104 + +4 stack::
+ 105 + + push(T&& t, std::false_type)
+ 106 + + {
+ 107 + + BOOST_CORE_STATIC_ASSERT( ! is_trivially_copy_assignable<T>::value );
+ 108 + +
+ 109 + + using Holder = non_trivial< remove_cvref<T> >;
+ 110 + +4 constexpr std::size_t size = sizeof(Holder);
+ 111 + +4 constexpr std::size_t alignment = alignof(Holder);
+ 112 + +
+ 113 + + void* ptr;
+ 114 + + std::size_t offset;
+ 115 + + do
+ 116 + + {
+ 117 + +7 std::size_t space = cap_ - size_;
+ 118 + +7 unsigned char* buf = base_ + size_;
+ 119 + +7 ptr = buf;
+ 120 + +7 if( std::align(alignment, size, ptr, space) )
+ 121 + + {
+ 122 + +4 offset = (reinterpret_cast<unsigned char*>(ptr) - buf) + size;
+ 123 + +4 break;
+ 124 + + }
+ 125 + +
+ 126 + +3 reserve_impl(size_ + size + alignment - 1);
+ 127 + +3 }
+ 128 + + while(true);
+ 129 + +4 BOOST_ASSERT(
+ 130 + + (reinterpret_cast<unsigned char*>(ptr) + size - offset) ==
+ 131 + + (base_ + size_) );
+ 132 + +
+ 133 + +4 head_ = ::new(ptr) Holder( static_cast<T&&>(t), head_, offset );
+ 134 + +4 size_ += offset;
+ 135 + +4 }
+ 136 + +
+ 137 + + // trivial
+ 138 + + template<class T>
+ 139 + + void
+ 140 + +328587 stack::
+ 141 + + pop(T& t, std::true_type)
+ 142 + + {
+ 143 + +328587 BOOST_ASSERT( size_ >= sizeof(T) );
+ 144 + +328587 peek(t);
+ 145 + +328587 size_ -= sizeof(T);
+ 146 + +328587 }
+ 147 + +
+ 148 + + // non-trivial
+ 149 + + template<class T>
+ 150 + + void
+ 151 + +3 stack::
+ 152 + + pop(T& t, std::false_type)
+ 153 + + {
+ 154 + +3 auto next = head_->next;
+ 155 + +3 auto offset = head_->offset;
+ 156 + +
+ 157 + + using U = remove_cvref<T>;
+ 158 + + using Holder = non_trivial<U>;
+ 159 + +3 auto const head = static_cast<Holder*>(head_);
+ 160 + +
+ 161 + +3 t = std::move( head->obj );
+ 162 + +3 head->~Holder();
+ 163 + +
+ 164 + +3 head_ = next;
+ 165 + +3 size_ -= offset;
+ 166 + +3 }
+ 167 + +
+ 168 + + } // detail
+ 169 + + } // json
+ 170 + + } // boost
+ 171 + +
+ 172 + + #endif
+ 173 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.stack.ipp.3a9e0e01201646e2f48328d15e4e2602.html b/json/gcovr/index.stack.ipp.3a9e0e01201646e2f48328d15e4e2602.html new file mode 100644 index 00000000..ff6bf3da --- /dev/null +++ b/json/gcovr/index.stack.ipp.3a9e0e01201646e2f48328d15e4e2602.html @@ -0,0 +1,2918 @@ + + + + + + detail/impl/stack.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/impl/stack.ipp

+
+ + 100.0% Lines (43/43) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/impl/stack.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_IMPL_STACK_IPP
+ 11 + + #define BOOST_JSON_DETAIL_IMPL_STACK_IPP
+ 12 + +
+ 13 + + #include <boost/json/detail/stack.hpp>
+ 14 + +
+ 15 + + namespace boost {
+ 16 + + namespace json {
+ 17 + + namespace detail {
+ 18 + +
+ 19 + + stack::non_trivial<>*
+ 20 + +1 stack::non_trivial<>::destroy() noexcept
+ 21 + + {
+ 22 + +1 non_trivial* const result = next;
+ 23 + +1 rel(this, nullptr);
+ 24 + +1 return result;
+ 25 + + }
+ 26 + +
+ 27 + + stack::non_trivial<>*
+ 28 + +3 stack::non_trivial<>::relocate(void* dst) noexcept
+ 29 + + {
+ 30 + +3 return rel(this, dst);
+ 31 + + }
+ 32 + +
+ 33 + +
+ 34 + +2185850 stack::
+ 35 + + ~stack()
+ 36 + + {
+ 37 + +2185850 clear();
+ 38 + +2185850 if(base_ != buf_)
+ 39 + +118086 sp_->deallocate(
+ 40 + +118086 base_, cap_);
+ 41 + +2185850 }
+ 42 + +
+ 43 + +21245 stack::
+ 44 + + stack(
+ 45 + + storage_ptr sp,
+ 46 + + unsigned char* buf,
+ 47 + +21245 std::size_t buf_size) noexcept
+ 48 + +21245 : sp_(std::move(sp))
+ 49 + +21245 , cap_(buf_size)
+ 50 + +21245 , base_(buf)
+ 51 + +21245 , buf_(buf)
+ 52 + + {
+ 53 + +21245 }
+ 54 + +
+ 55 + + void
+ 56 + +6360224 stack::
+ 57 + + clear() noexcept
+ 58 + + {
+ 59 + +6360225 while(head_)
+ 60 + +1 head_ = head_->destroy();
+ 61 + +6360224 size_ = 0;
+ 62 + +6360224 }
+ 63 + +
+ 64 + + void
+ 65 + +124748 stack::
+ 66 + + reserve_impl(std::size_t n)
+ 67 + + {
+ 68 + + // caller checks this
+ 69 + +124748 BOOST_ASSERT(n > cap_);
+ 70 + +
+ 71 + +124748 auto const base = static_cast<unsigned char*>( sp_->allocate(n) );
+ 72 + +124746 if(base_)
+ 73 + + {
+ 74 + + // copy trivials
+ 75 + +6660 std::memcpy(base, base_, size_);
+ 76 + +
+ 77 + + // copy non-trivials
+ 78 + +6660 non_trivial<>* src = head_;
+ 79 + +6660 non_trivial<>** prev = &head_;
+ 80 + +6663 while(src)
+ 81 + + {
+ 82 + +3 std::size_t const buf_offset =
+ 83 + +3 reinterpret_cast<unsigned char*>(src) - base_;
+ 84 + +3 non_trivial<>* dest = src->relocate(base + buf_offset);
+ 85 + +3 *prev = dest;
+ 86 + +3 prev = &dest->next;
+ 87 + +3 src = dest->next;
+ 88 + + }
+ 89 + +
+ 90 + +6660 if(base_ != buf_)
+ 91 + +6660 sp_->deallocate(base_, cap_);
+ 92 + + }
+ 93 + +124746 base_ = base;
+ 94 + +124746 cap_ = n;
+ 95 + +124746 }
+ 96 + +
+ 97 + + } // detail
+ 98 + + } // namespace json
+ 99 + + } // namespace boost
+ 100 + +
+ 101 + + #endif
+ 102 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.static_resource.hpp.7bee809dfe2a5a1cb7dd0c3dd2654987.html b/json/gcovr/index.static_resource.hpp.7bee809dfe2a5a1cb7dd0c3dd2654987.html new file mode 100644 index 00000000..72c1b750 --- /dev/null +++ b/json/gcovr/index.static_resource.hpp.7bee809dfe2a5a1cb7dd0c3dd2654987.html @@ -0,0 +1,3902 @@ + + + + + + static_resource.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

static_resource.hpp

+
+ + 100.0% Lines (3/3) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
static_resource.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2020 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_STATIC_RESOURCE_HPP
+ 11 + + #define BOOST_JSON_STATIC_RESOURCE_HPP
+ 12 + +
+ 13 + + #include <boost/container/pmr/memory_resource.hpp>
+ 14 + + #include <boost/json/detail/config.hpp>
+ 15 + + #include <boost/json/is_deallocate_trivial.hpp>
+ 16 + + #include <cstddef>
+ 17 + +
+ 18 + + namespace boost {
+ 19 + + namespace json {
+ 20 + +
+ 21 + + #ifdef _MSC_VER
+ 22 + + #pragma warning(push)
+ 23 + + #pragma warning(disable: 4275) // non dll-interface class used as base for dll-interface class
+ 24 + + #endif
+ 25 + +
+ 26 + + //----------------------------------------------------------
+ 27 + +
+ 28 + + /** A resource using a caller-owned buffer, with a trivial deallocate.
+ 29 + +
+ 30 + + This memory resource is a special-purpose resource that releases allocated
+ 31 + + memory only when the resource is destroyed (or when @ref release is
+ 32 + + called). It has a trivial deallocate function; that is, the metafunction
+ 33 + + @ref is_deallocate_trivial returns `true`.
+ 34 + +
+ 35 + + The resource is constructed from a caller-owned buffer from which
+ 36 + + subsequent calls to allocate are apportioned. When a memory request cannot
+ 37 + + be satisfied from the free bytes remaining in the buffer, the allocation
+ 38 + + request fails with the exception `std::bad_alloc`.
+ 39 + +
+ 40 + + @par Example
+ 41 + + This parses a JSON text into a value which uses a local stack buffer, then
+ 42 + + prints the result.
+ 43 + +
+ 44 + + @code
+ 45 + + unsigned char buf[ 4000 ];
+ 46 + + static_resource mr( buf );
+ 47 + +
+ 48 + + // Parse the string, using our memory resource
+ 49 + + value const jv = parse( "[1,2,3]", &mr );
+ 50 + +
+ 51 + + // Print the JSON
+ 52 + + std::cout << jv;
+ 53 + + @endcode
+ 54 + +
+ 55 + + @par Thread Safety
+ 56 + + Members of the same instance may not be called concurrently.
+ 57 + +
+ 58 + + @see https://en.wikipedia.org/wiki/Region-based_memory_management
+ 59 + + */
+ 60 + + class
+ 61 + + BOOST_JSON_DECL
+ 62 + + BOOST_SYMBOL_VISIBLE
+ 63 + + static_resource final
+ 64 + + : public container::pmr::memory_resource
+ 65 + + {
+ 66 + + void* p_;
+ 67 + + std::size_t n_;
+ 68 + + std::size_t size_;
+ 69 + +
+ 70 + + public:
+ 71 + + /** Assignment operator.
+ 72 + +
+ 73 + + The type is neither copyable nor movable, so this operator is deleted.
+ 74 + + */
+ 75 + + static_resource& operator=(
+ 76 + + static_resource const&) = delete;
+ 77 + +
+ 78 + + /** Constructors.
+ 79 + +
+ 80 + + These construct the resource to use the specified buffer for subsequent
+ 81 + + calls to allocate. When the buffer is exhausted, allocate will throw
+ 82 + + `std::bad_alloc`.
+ 83 + +
+ 84 + + Ownership of `buffer` is not transferred; the caller is responsible for
+ 85 + + ensuring that its lifetime extends until the resource is destroyed.
+ 86 + +
+ 87 + + Overload **(5)** is the copy constructor. The type is neither copyable
+ 88 + + nor movable, so this overload is deleted.
+ 89 + +
+ 90 + + @par Complexity
+ 91 + + Constant.
+ 92 + +
+ 93 + + @par Exception Safety
+ 94 + + No-throw guarantee.
+ 95 + +
+ 96 + + @param buffer The buffer to use.
+ 97 + + @param size The number of valid bytes pointed to by `buffer`.
+ 98 + +
+ 99 + + @{
+ 100 + + */
+ 101 + + static_resource(
+ 102 + + unsigned char* buffer,
+ 103 + + std::size_t size) noexcept;
+ 104 + +
+ 105 + + #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
+ 106 + + static_resource(
+ 107 + + std::byte* buffer,
+ 108 + + std::size_t size) noexcept
+ 109 + + : static_resource(reinterpret_cast<
+ 110 + + unsigned char*>(buffer), size)
+ 111 + + {
+ 112 + + }
+ 113 + + #endif
+ 114 + +
+ 115 + + /** Overload
+ 116 + +
+ 117 + + @tparam N The size of `buffer`.
+ 118 + + @param buffer
+ 119 + + */
+ 120 + + template<std::size_t N>
+ 121 + + explicit
+ 122 + +3 static_resource(
+ 123 + + unsigned char(&buffer)[N]) noexcept
+ 124 + +3 : static_resource(&buffer[0], N)
+ 125 + + {
+ 126 + +3 }
+ 127 + +
+ 128 + + #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
+ 129 + + /** Overload
+ 130 + +
+ 131 + + @tparam N
+ 132 + + @param buffer
+ 133 + + */
+ 134 + + template<std::size_t N>
+ 135 + + explicit
+ 136 + + static_resource(
+ 137 + + std::byte(&buffer)[N]) noexcept
+ 138 + + : static_resource(&buffer[0], N)
+ 139 + + {
+ 140 + + }
+ 141 + + #endif
+ 142 + +
+ 143 + + #ifndef BOOST_JSON_DOCS
+ 144 + + // Safety net for accidental buffer overflows
+ 145 + + template<std::size_t N>
+ 146 + + static_resource(
+ 147 + + unsigned char(&buffer)[N], std::size_t n) noexcept
+ 148 + + : static_resource(&buffer[0], n)
+ 149 + + {
+ 150 + + // If this goes off, check your parameters
+ 151 + + // closely, chances are you passed an array
+ 152 + + // thinking it was a pointer.
+ 153 + + BOOST_ASSERT(n <= N);
+ 154 + + }
+ 155 + +
+ 156 + + #ifdef __cpp_lib_byte
+ 157 + + // Safety net for accidental buffer overflows
+ 158 + + template<std::size_t N>
+ 159 + + static_resource(
+ 160 + + std::byte(&buffer)[N], std::size_t n) noexcept
+ 161 + + : static_resource(&buffer[0], n)
+ 162 + + {
+ 163 + + // If this goes off, check your parameters
+ 164 + + // closely, chances are you passed an array
+ 165 + + // thinking it was a pointer.
+ 166 + + BOOST_ASSERT(n <= N);
+ 167 + + }
+ 168 + + #endif
+ 169 + + #endif
+ 170 + +
+ 171 + + /// Overload
+ 172 + + static_resource(
+ 173 + + static_resource const&) = delete;
+ 174 + + /// @}
+ 175 + +
+ 176 + + /** Release all allocated memory.
+ 177 + +
+ 178 + + This function resets the buffer provided upon construction so that all
+ 179 + + of the valid bytes are available for subsequent allocation.
+ 180 + +
+ 181 + + @par Complexity
+ 182 + + Constant
+ 183 + +
+ 184 + + @par Exception Safety
+ 185 + + No-throw guarantee.
+ 186 + + */
+ 187 + + void
+ 188 + + release() noexcept;
+ 189 + +
+ 190 + + protected:
+ 191 + + #ifndef BOOST_JSON_DOCS
+ 192 + + void*
+ 193 + + do_allocate(
+ 194 + + std::size_t n,
+ 195 + + std::size_t align) override;
+ 196 + +
+ 197 + + void
+ 198 + + do_deallocate(
+ 199 + + void* p,
+ 200 + + std::size_t n,
+ 201 + + std::size_t align) override;
+ 202 + +
+ 203 + + bool
+ 204 + + do_is_equal(
+ 205 + + memory_resource const& mr
+ 206 + + ) const noexcept override;
+ 207 + + #endif
+ 208 + + };
+ 209 + +
+ 210 + + #ifdef _MSC_VER
+ 211 + + #pragma warning(pop)
+ 212 + + #endif
+ 213 + +
+ 214 + + template<>
+ 215 + + struct is_deallocate_trivial<
+ 216 + + static_resource>
+ 217 + + {
+ 218 + + static constexpr bool value = true;
+ 219 + + };
+ 220 + +
+ 221 + + } // namespace json
+ 222 + + } // namespace boost
+ 223 + +
+ 224 + + #endif
+ 225 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.static_resource.ipp.da4918eee73bb2b38d71ee2c22c5a4b6.html b/json/gcovr/index.static_resource.ipp.da4918eee73bb2b38d71ee2c22c5a4b6.html new file mode 100644 index 00000000..45d1c655 --- /dev/null +++ b/json/gcovr/index.static_resource.ipp.da4918eee73bb2b38d71ee2c22c5a4b6.html @@ -0,0 +1,2702 @@ + + + + + + impl/static_resource.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/static_resource.ipp

+
+ + 81.8% Lines (18/22) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/static_resource.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_STATIC_RESOURCE_IPP
+ 11 + + #define BOOST_JSON_IMPL_STATIC_RESOURCE_IPP
+ 12 + +
+ 13 + + #include <boost/json/static_resource.hpp>
+ 14 + + #include <boost/throw_exception.hpp>
+ 15 + + #include <memory>
+ 16 + +
+ 17 + + namespace boost {
+ 18 + + namespace json {
+ 19 + +
+ 20 + +7 static_resource::
+ 21 + + static_resource(
+ 22 + + unsigned char* buffer,
+ 23 + +7 std::size_t size) noexcept
+ 24 + +7 : p_(buffer)
+ 25 + +7 , n_(size)
+ 26 + +7 , size_(size)
+ 27 + + {
+ 28 + +7 }
+ 29 + +
+ 30 + + void
+ 31 + +1 static_resource::
+ 32 + + release() noexcept
+ 33 + + {
+ 34 + +1 p_ = reinterpret_cast<
+ 35 + +1 char*>(p_) - (size_ - n_);
+ 36 + +1 n_ = size_;
+ 37 + +1 }
+ 38 + +
+ 39 + + void*
+ 40 + +10 static_resource::
+ 41 + + do_allocate(
+ 42 + + std::size_t n,
+ 43 + + std::size_t align)
+ 44 + + {
+ 45 + +10 auto p = std::align(align, n, p_, n_);
+ 46 + +10 if(! p)
+ 47 + +4 throw_exception( std::bad_alloc(), BOOST_CURRENT_LOCATION );
+ 48 + +8 p_ = reinterpret_cast<char*>(p) + n;
+ 49 + +8 n_ -= n;
+ 50 + +8 return p;
+ 51 + + }
+ 52 + +
+ 53 + + void
+ 54 + + static_resource::
+ 55 + + do_deallocate(
+ 56 + + void*,
+ 57 + + std::size_t,
+ 58 + + std::size_t)
+ 59 + + {
+ 60 + + // do nothing
+ 61 + + }
+ 62 + +
+ 63 + + bool
+ 64 + + static_resource::
+ 65 + + do_is_equal(
+ 66 + + memory_resource const& mr) const noexcept
+ 67 + + {
+ 68 + + return this == &mr;
+ 69 + + }
+ 70 + +
+ 71 + + } // namespace json
+ 72 + + } // namespace boost
+ 73 + +
+ 74 + + #endif
+ 75 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.storage_ptr.hpp.ac80baa46fb5bebc8f455223b00c44c4.html b/json/gcovr/index.storage_ptr.hpp.ac80baa46fb5bebc8f455223b00c44c4.html new file mode 100644 index 00000000..e76a3987 --- /dev/null +++ b/json/gcovr/index.storage_ptr.hpp.ac80baa46fb5bebc8f455223b00c44c4.html @@ -0,0 +1,5798 @@ + + + + + + storage_ptr.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

storage_ptr.hpp

+
+ + 100.0% Lines (68/68) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
storage_ptr.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_STORAGE_PTR_HPP
+ 11 + + #define BOOST_JSON_STORAGE_PTR_HPP
+ 12 + +
+ 13 + + #include <boost/core/detail/static_assert.hpp>
+ 14 + + #include <boost/container/pmr/polymorphic_allocator.hpp>
+ 15 + + #include <boost/json/detail/config.hpp>
+ 16 + + #include <boost/json/detail/shared_resource.hpp>
+ 17 + + #include <boost/json/detail/default_resource.hpp>
+ 18 + + #include <boost/json/is_deallocate_trivial.hpp>
+ 19 + + #include <new>
+ 20 + + #include <type_traits>
+ 21 + + #include <utility>
+ 22 + +
+ 23 + + namespace boost {
+ 24 + + namespace json {
+ 25 + +
+ 26 + + /** A smart pointer to a memory resource.
+ 27 + +
+ 28 + + This class is used to hold a pointer to a memory resource. The pointed-to
+ 29 + + resource is always valid. Depending on the means of construction, the
+ 30 + + ownership will be either:
+ 31 + +
+ 32 + + @li Non-owning, when constructing from a raw pointer to
+ 33 + + @ref boost::container::pmr::memory_resource or from a
+ 34 + + @ref boost::container::pmr::polymorphic_allocator. In this case the caller
+ 35 + + is responsible for ensuring that the lifetime of the memory resource
+ 36 + + extends until there are no more calls to allocate or deallocate.
+ 37 + +
+ 38 + + @li Owning, when constructing using the function @ref make_shared_resource.
+ 39 + + In this case ownership is shared; the lifetime of the memory resource
+ 40 + + extends until the last copy of the `storage_ptr` is destroyed.
+ 41 + +
+ 42 + + @par Examples
+ 43 + + These statements create a memory resource on the stack and construct
+ 44 + + a pointer from it without taking ownership:
+ 45 + +
+ 46 + + @code
+ 47 + + monotonic_resource mr; // Create our memory resource on the stack
+ 48 + + storage_ptr sp( &mr ); // Construct a non-owning pointer to the resource
+ 49 + + @endcode
+ 50 + +
+ 51 + + This function creates a pointer to a memory resource using shared ownership
+ 52 + + and returns it. The lifetime of the memory resource extends until the last
+ 53 + + copy of the pointer is destroyed:
+ 54 + +
+ 55 + + @code
+ 56 + + // Create a counted memory resource and return it
+ 57 + + storage_ptr make_storage()
+ 58 + + {
+ 59 + + return make_shared_resource< monotonic_resource >();
+ 60 + + }
+ 61 + + @endcode
+ 62 + +
+ 63 + + @par Thread Safety
+ 64 + + Instances of this type provide the default level of thread safety for all
+ 65 + + C++ objects. Specifically, it conforms to
+ 66 + + [16.4.6.10 Data race avoidance](http://eel.is/c++draft/res.on.data.races).
+ 67 + +
+ 68 + + @see
+ 69 + + @ref make_shared_resource,
+ 70 + + @ref boost::container::pmr::polymorphic_allocator,
+ 71 + + @ref boost::container::pmr::memory_resource.
+ 72 + +
+ 73 + + */
+ 74 + + class storage_ptr
+ 75 + + {
+ 76 + + #ifndef BOOST_JSON_DOCS
+ 77 + + // VFALCO doc toolchain shows this when it shouldn't
+ 78 + + friend struct detail::shared_resource;
+ 79 + + #endif
+ 80 + + using shared_resource =
+ 81 + + detail::shared_resource;
+ 82 + +
+ 83 + + using default_resource =
+ 84 + + detail::default_resource;
+ 85 + +
+ 86 + + std::uintptr_t i_;
+ 87 + +
+ 88 + + shared_resource*
+ 89 + +302 get_shared() const noexcept
+ 90 + + {
+ 91 + + return static_cast<shared_resource*>(
+ 92 + + reinterpret_cast<container::pmr::memory_resource*>(
+ 93 + +302 i_ & ~3));
+ 94 + + }
+ 95 + +
+ 96 + + void
+ 97 + +6352572 addref() const noexcept
+ 98 + + {
+ 99 + +6352572 if(is_shared())
+ 100 + +141 get_shared()->refs.fetch_add(
+ 101 + + 1, std::memory_order_relaxed);
+ 102 + +6352572 }
+ 103 + +
+ 104 + + void
+ 105 + +43989937 release() const noexcept
+ 106 + + {
+ 107 + +43989937 if(is_shared())
+ 108 + + {
+ 109 + +161 auto const p = get_shared();
+ 110 + +161 if(p->refs.fetch_sub(1,
+ 111 + +161 std::memory_order_acq_rel) == 1)
+ 112 + +20 delete p;
+ 113 + + }
+ 114 + +43989937 }
+ 115 + +
+ 116 + + template<class T>
+ 117 + +20 storage_ptr(
+ 118 + + detail::shared_resource_impl<T>* p) noexcept
+ 119 + +20 : i_(reinterpret_cast<std::uintptr_t>(
+ 120 + +20 static_cast<container::pmr::memory_resource*>(p)) + 1 +
+ 121 + + (json::is_deallocate_trivial<T>::value ? 2 : 0))
+ 122 + + {
+ 123 + +20 BOOST_ASSERT(p);
+ 124 + +20 }
+ 125 + +
+ 126 + + public:
+ 127 + + /** Destructor.
+ 128 + +
+ 129 + + If the pointer has shared ownership of the resource, the shared
+ 130 + + ownership is released. If this is the last owned copy, the memory
+ 131 + + resource is destroyed.
+ 132 + +
+ 133 + + @par Complexity
+ 134 + + Constant.
+ 135 + +
+ 136 + + @par Exception Safety
+ 137 + + No-throw guarantee.
+ 138 + + */
+ 139 + +41913287 ~storage_ptr() noexcept
+ 140 + + {
+ 141 + +41913287 release();
+ 142 + +41913287 }
+ 143 + +
+ 144 + + /** Constructors.
+ 145 + +
+ 146 + + @li **(1)** constructs a non-owning pointer that refers to the
+ 147 + + \<\<default_memory_resource,default memory resource\>\>.
+ 148 + +
+ 149 + + @li **(2)** constructs a non-owning pointer that points to the memory
+ 150 + + resource `r`.
+ 151 + +
+ 152 + + @li **(3)** constructs a non-owning pointer that points to the same
+ 153 + + memory resource as `alloc`, obtained by calling `alloc.resource()`.
+ 154 + +
+ 155 + + @li **(4)**, **(5)** construct a pointer to the same memory resource as
+ 156 + + `other`, with the same ownership.
+ 157 + +
+ 158 + + After **(4)** and **(5)** if `other` was owning, then the constructed
+ 159 + + pointer is also owning. In particular, **(4)** transfers ownership to
+ 160 + + the constructed pointer while **(5)** causes it to share ownership with
+ 161 + + `other`. Otherwise, and with other overloads the constructed pointer
+ 162 + + doesn't own its memory resource and the caller is responsible for
+ 163 + + maintaining the lifetime of the pointed-to
+ 164 + + @ref boost::container::pmr::memory_resource.
+ 165 + +
+ 166 + + After **(4)**, `other` will point to the default memory resource.
+ 167 + +
+ 168 + + @par Constraints
+ 169 + + @code
+ 170 + + std::is_convertible< T*, boost::container::pmr::memory_resource* >::value == true
+ 171 + + @endcode
+ 172 + +
+ 173 + + @pre
+ 174 + + @code
+ 175 + + r != nullptr
+ 176 + + @endcode
+ 177 + +
+ 178 + + @par Complexity
+ 179 + + Constant.
+ 180 + +
+ 181 + + @par Exception Safety
+ 182 + + No-throw guarantee.
+ 183 + +
+ 184 + + @{
+ 185 + + */
+ 186 + +14653426 storage_ptr() noexcept
+ 187 + +14653426 : i_(0)
+ 188 + + {
+ 189 + +14653426 }
+ 190 + +
+ 191 + + /** Overload
+ 192 + +
+ 193 + + @tparam T The type of memory resource.
+ 194 + + @param r A non-null pointer to the memory resource to use.
+ 195 + + */
+ 196 + + template<class T
+ 197 + + #ifndef BOOST_JSON_DOCS
+ 198 + + , class = typename std::enable_if<
+ 199 + + std::is_convertible<T*,
+ 200 + + container::pmr::memory_resource*>::value>::type
+ 201 + + #endif
+ 202 + + >
+ 203 + +57222 storage_ptr(T* r) noexcept
+ 204 + +57222 : i_(reinterpret_cast<std::uintptr_t>(
+ 205 + +18 static_cast<container::pmr::memory_resource *>(r)) +
+ 206 + + (json::is_deallocate_trivial<T>::value ? 2 : 0))
+ 207 + + {
+ 208 + +57222 BOOST_ASSERT(r);
+ 209 + +57222 }
+ 210 + +
+ 211 + + /** Overload
+ 212 + +
+ 213 + + @tparam V Any type.
+ 214 + + @param alloc A @ref boost::container::pmr::polymorphic_allocator to
+ 215 + + construct from.
+ 216 + + */
+ 217 + + template<class V>
+ 218 + +10 storage_ptr(
+ 219 + + container::pmr::polymorphic_allocator<V> const& alloc) noexcept
+ 220 + +10 : i_(reinterpret_cast<std::uintptr_t>(
+ 221 + +10 alloc.resource()))
+ 222 + + {
+ 223 + +10 }
+ 224 + +
+ 225 + + /** Overload
+ 226 + +
+ 227 + + @param other Another pointer.
+ 228 + + */
+ 229 + +22965263 storage_ptr(
+ 230 + + storage_ptr&& other) noexcept
+ 231 + +22965263 : i_(detail::exchange(other.i_, 0))
+ 232 + + {
+ 233 + +22965263 }
+ 234 + +
+ 235 + + /** Overload
+ 236 + +
+ 237 + + @param other
+ 238 + + */
+ 239 + +6352571 storage_ptr(
+ 240 + + storage_ptr const& other) noexcept
+ 241 + +6352571 : i_(other.i_)
+ 242 + + {
+ 243 + +6352571 addref();
+ 244 + +6352571 }
+ 245 + + /// @}
+ 246 + +
+ 247 + + /** Assignment operators.
+ 248 + +
+ 249 + + This function assigns a pointer that points to the same memory resource
+ 250 + + as `other`, with the same ownership:
+ 251 + +
+ 252 + + @li If `other` is non-owning, then the assigned-to pointer will be be
+ 253 + + non-owning.
+ 254 + +
+ 255 + + @li If `other` has shared ownership, then **(1)** transfers ownership
+ 256 + + to the assigned-to pointer, while after **(2)** it shares the ownership
+ 257 + + with `other`.
+ 258 + +
+ 259 + + If the assigned-to pointer previously had shared ownership, it is
+ 260 + + released before the function returns.
+ 261 + +
+ 262 + + After **(1)**, `other` will point to the
+ 263 + + \<\<default_memory_resource,default memory resource\>\>.
+ 264 + +
+ 265 + + @par Complexity
+ 266 + + Constant.
+ 267 + +
+ 268 + + @par Exception Safety
+ 269 + + No-throw guarantee.
+ 270 + +
+ 271 + + @param other Another pointer.
+ 272 + +
+ 273 + + @{
+ 274 + + */
+ 275 + + storage_ptr&
+ 276 + +2076649 operator=(
+ 277 + + storage_ptr&& other) noexcept
+ 278 + + {
+ 279 + +2076649 release();
+ 280 + +2076649 i_ = detail::exchange(other.i_, 0);
+ 281 + +2076649 return *this;
+ 282 + + }
+ 283 + +
+ 284 + + storage_ptr&
+ 285 + +1 operator=(
+ 286 + + storage_ptr const& other) noexcept
+ 287 + + {
+ 288 + +1 other.addref();
+ 289 + +1 release();
+ 290 + +1 i_ = other.i_;
+ 291 + +1 return *this;
+ 292 + + }
+ 293 + + /// @}
+ 294 + +
+ 295 + + /** Check if ownership of the memory resource is shared.
+ 296 + +
+ 297 + + This function returns true for memory resources created using @ref
+ 298 + + make_shared_resource.
+ 299 + + */
+ 300 + + bool
+ 301 + +50342510 is_shared() const noexcept
+ 302 + + {
+ 303 + +50342510 return (i_ & 1) != 0;
+ 304 + + }
+ 305 + +
+ 306 + + /** Check if calling `deallocate` on the memory resource has no effect.
+ 307 + +
+ 308 + + This function is used to determine if the deallocate function of the
+ 309 + + pointed to memory resource is trivial. The value of @ref
+ 310 + + is_deallocate_trivial is evaluated and saved when the memory resource
+ 311 + + is constructed and the type is known, before the type is erased.
+ 312 + + */
+ 313 + + bool
+ 314 + +1 is_deallocate_trivial() const noexcept
+ 315 + + {
+ 316 + +1 return (i_ & 2) != 0;
+ 317 + + }
+ 318 + +
+ 319 + + /** Check if ownership of the memory resource is not shared and deallocate is trivial.
+ 320 + +
+ 321 + + This function is used to determine if calls to deallocate can
+ 322 + + effectively be skipped. Equivalent to `! is_shared() &&
+ 323 + + is_deallocate_trivial()`.
+ 324 + + */
+ 325 + + bool
+ 326 + +4323548 is_not_shared_and_deallocate_is_trivial() const noexcept
+ 327 + + {
+ 328 + +4323548 return (i_ & 3) == 2;
+ 329 + + }
+ 330 + +
+ 331 + + /** Return a pointer to the memory resource.
+ 332 + +
+ 333 + + This function returns a pointer to the
+ 334 + + referenced @ref boost::container::pmr::memory_resource.
+ 335 + +
+ 336 + + @par Complexity
+ 337 + + Constant.
+ 338 + +
+ 339 + + @par Exception Safety
+ 340 + + No-throw guarantee.
+ 341 + + */
+ 342 + + container::pmr::memory_resource*
+ 343 + +653237 get() const noexcept
+ 344 + + {
+ 345 + +653237 if(i_ != 0)
+ 346 + + return reinterpret_cast<
+ 347 + +122565 container::pmr::memory_resource*>(i_ & ~3);
+ 348 + +530672 return default_resource::get();
+ 349 + + }
+ 350 + +
+ 351 + + /** Return a pointer to the memory resource.
+ 352 + +
+ 353 + + This function returns a pointer to the referenced @ref
+ 354 + + boost::container::pmr::memory_resource.
+ 355 + +
+ 356 + + @par Complexity
+ 357 + + Constant.
+ 358 + +
+ 359 + + @par Exception Safety
+ 360 + + No-throw guarantee.
+ 361 + + */
+ 362 + + container::pmr::memory_resource*
+ 363 + +649749 operator->() const noexcept
+ 364 + + {
+ 365 + +649749 return get();
+ 366 + + }
+ 367 + +
+ 368 + + /** Return a reference to the memory resource.
+ 369 + +
+ 370 + + This function returns a reference to the pointed-to @ref
+ 371 + + boost::container::pmr::memory_resource.
+ 372 + +
+ 373 + + @par Complexity
+ 374 + +
+ 375 + + Constant.
+ 376 + +
+ 377 + + @par Exception Safety
+ 378 + +
+ 379 + + No-throw guarantee.
+ 380 + + */
+ 381 + + container::pmr::memory_resource&
+ 382 + +3456 operator*() const noexcept
+ 383 + + {
+ 384 + +3456 return *get();
+ 385 + + }
+ 386 + +
+ 387 + + template<class U, class... Args>
+ 388 + + friend
+ 389 + + storage_ptr
+ 390 + + make_shared_resource(Args&&... args);
+ 391 + + };
+ 392 + +
+ 393 + + #if defined(_MSC_VER)
+ 394 + + # pragma warning( push )
+ 395 + + # if !defined(__clang__) && _MSC_VER <= 1900
+ 396 + + # pragma warning( disable : 4702 )
+ 397 + + # endif
+ 398 + + #endif
+ 399 + +
+ 400 + + /** Return a pointer that owns a new, dynamically allocated memory resource.
+ 401 + +
+ 402 + + This function dynamically allocates a new memory resource as if by
+ 403 + + `operator new` that uses shared ownership. The lifetime of the memory
+ 404 + + resource will be extended until the last @ref storage_ptr which points to
+ 405 + + it is destroyed.
+ 406 + +
+ 407 + + @par Constraints
+ 408 + + @code
+ 409 + + std::is_base_of< boost::container::pmr::memory_resource, U >::value == true
+ 410 + + @endcode
+ 411 + +
+ 412 + + @par Complexity
+ 413 + + Same as `new U( std::forward<Args>(args)... )`.
+ 414 + +
+ 415 + + @par Exception Safety
+ 416 + + Strong guarantee.
+ 417 + +
+ 418 + + @tparam U The type of memory resource to create.
+ 419 + +
+ 420 + + @param args Parameters forwarded to the constructor of `U`.
+ 421 + + */
+ 422 + + template<class U, class... Args>
+ 423 + + storage_ptr
+ 424 + +21 make_shared_resource(Args&&... args)
+ 425 + + {
+ 426 + + // If this generates an error, it means that
+ 427 + + // `T` is not a memory resource.
+ 428 + + BOOST_CORE_STATIC_ASSERT((
+ 429 + + std::is_base_of<container::pmr::memory_resource, U>::value));
+ 430 + +23 return storage_ptr(new
+ 431 + + detail::shared_resource_impl<U>(
+ 432 + +22 std::forward<Args>(args)...));
+ 433 + + }
+ 434 + + #if defined(_MSC_VER)
+ 435 + + # pragma warning( pop )
+ 436 + + #endif
+ 437 + +
+ 438 + + /// Overload
+ 439 + + inline
+ 440 + + bool
+ 441 + +5 operator==(
+ 442 + + storage_ptr const& lhs,
+ 443 + + storage_ptr const& rhs) noexcept
+ 444 + + {
+ 445 + +5 return lhs.get() == rhs.get();
+ 446 + + }
+ 447 + +
+ 448 + + /// Overload
+ 449 + + inline
+ 450 + + bool
+ 451 + + operator!=(
+ 452 + + storage_ptr const& lhs,
+ 453 + + storage_ptr const& rhs) noexcept
+ 454 + + {
+ 455 + + return lhs.get() != rhs.get();
+ 456 + + }
+ 457 + +
+ 458 + + } // namespace json
+ 459 + + } // namespace boost
+ 460 + +
+ 461 + + #endif
+ 462 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.stream.hpp.07654afdcb5f383c2335d7fecd03055c.html b/json/gcovr/index.stream.hpp.07654afdcb5f383c2335d7fecd03055c.html new file mode 100644 index 00000000..a279465a --- /dev/null +++ b/json/gcovr/index.stream.hpp.07654afdcb5f383c2335d7fecd03055c.html @@ -0,0 +1,4886 @@ + + + + + + detail/stream.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/stream.hpp

+
+ + 100.0% Lines (101/101) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/stream.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_STREAM_HPP
+ 11 + + #define BOOST_JSON_DETAIL_STREAM_HPP
+ 12 + +
+ 13 + + namespace boost {
+ 14 + + namespace json {
+ 15 + + namespace detail {
+ 16 + +
+ 17 + + class const_stream
+ 18 + + {
+ 19 + + friend class local_const_stream;
+ 20 + +
+ 21 + + char const* p_;
+ 22 + + char const* end_;
+ 23 + +
+ 24 + + public:
+ 25 + + const_stream() = default;
+ 26 + +
+ 27 + +35719 const_stream(
+ 28 + + char const* data,
+ 29 + + std::size_t size) noexcept
+ 30 + +35719 : p_(data)
+ 31 + +35719 , end_(data + size)
+ 32 + + {
+ 33 + +35719 }
+ 34 + +
+ 35 + + size_t
+ 36 + + used(char const* begin) const noexcept
+ 37 + + {
+ 38 + + return static_cast<
+ 39 + + size_t>(p_ - begin);
+ 40 + + }
+ 41 + +
+ 42 + + size_t
+ 43 + +64866 remain() const noexcept
+ 44 + + {
+ 45 + +64866 return end_ - p_;
+ 46 + + }
+ 47 + +
+ 48 + + char const*
+ 49 + +62244 data() const noexcept
+ 50 + + {
+ 51 + +62244 return p_;
+ 52 + + }
+ 53 + +
+ 54 + +31451934 operator bool() const noexcept
+ 55 + + {
+ 56 + +31451934 return p_ < end_;
+ 57 + + }
+ 58 + +
+ 59 + + // unchecked
+ 60 + + char
+ 61 + +31417505 operator*() const noexcept
+ 62 + + {
+ 63 + +31417505 BOOST_ASSERT(p_ < end_);
+ 64 + +31417505 return *p_;
+ 65 + + }
+ 66 + +
+ 67 + + // unchecked
+ 68 + + const_stream&
+ 69 + +31417505 operator++() noexcept
+ 70 + + {
+ 71 + +31417505 BOOST_ASSERT(p_ < end_);
+ 72 + +31417505 ++p_;
+ 73 + +31417505 return *this;
+ 74 + + }
+ 75 + +
+ 76 + + void
+ 77 + +26559 skip(std::size_t n) noexcept
+ 78 + + {
+ 79 + +26559 BOOST_ASSERT(n <= remain());
+ 80 + +26559 p_ += n;
+ 81 + +26559 }
+ 82 + +
+ 83 + + void
+ 84 + + skip_to(const char* p) noexcept
+ 85 + + {
+ 86 + + BOOST_ASSERT(p <= end_ && p >= p_);
+ 87 + + p_ = p;
+ 88 + + }
+ 89 + + };
+ 90 + +
+ 91 + + class local_const_stream
+ 92 + + : public const_stream
+ 93 + + {
+ 94 + + const_stream& src_;
+ 95 + +
+ 96 + + public:
+ 97 + + explicit
+ 98 + +44285 local_const_stream(
+ 99 + + const_stream& src) noexcept
+ 100 + +44285 : const_stream(src)
+ 101 + +44285 , src_(src)
+ 102 + + {
+ 103 + +44285 }
+ 104 + +
+ 105 + +44285 ~local_const_stream()
+ 106 + + {
+ 107 + +44285 src_.p_ = p_;
+ 108 + +44285 }
+ 109 + +
+ 110 + + void
+ 111 + + clip(std::size_t n) noexcept
+ 112 + + {
+ 113 + + if(static_cast<std::size_t>(
+ 114 + + src_.end_ - p_) > n)
+ 115 + + end_ = p_ + n;
+ 116 + + else
+ 117 + + end_ = src_.end_;
+ 118 + + }
+ 119 + + };
+ 120 + +
+ 121 + + class const_stream_wrapper
+ 122 + + {
+ 123 + + const char*& p_;
+ 124 + + const char* const end_;
+ 125 + +
+ 126 + + friend class clipped_const_stream;
+ 127 + + public:
+ 128 + +4794062 const_stream_wrapper(
+ 129 + + const char*& p,
+ 130 + + const char* end)
+ 131 + +4794062 : p_(p)
+ 132 + +4794062 , end_(end)
+ 133 + + {
+ 134 + +4794062 }
+ 135 + +
+ 136 + +63384959 void operator++() noexcept
+ 137 + + {
+ 138 + +63384959 ++p_;
+ 139 + +63384959 }
+ 140 + +
+ 141 + +2046839 void operator+=(std::size_t n) noexcept
+ 142 + + {
+ 143 + +2046839 p_ += n;
+ 144 + +2046839 }
+ 145 + +
+ 146 + +7322858 void operator=(const char* p) noexcept
+ 147 + + {
+ 148 + +7322858 p_ = p;
+ 149 + +7322858 }
+ 150 + +
+ 151 + +70856167 char operator*() const noexcept
+ 152 + + {
+ 153 + +70856167 return *p_;
+ 154 + + }
+ 155 + +
+ 156 + +76831743 operator bool() const noexcept
+ 157 + + {
+ 158 + +76831743 return p_ < end_;
+ 159 + + }
+ 160 + +
+ 161 + +20797775 const char* begin() const noexcept
+ 162 + + {
+ 163 + +20797775 return p_;
+ 164 + + }
+ 165 + +
+ 166 + +4865457 const char* end() const noexcept
+ 167 + + {
+ 168 + +4865457 return end_;
+ 169 + + }
+ 170 + +
+ 171 + +2135882 std::size_t remain() const noexcept
+ 172 + + {
+ 173 + +2135882 return end_ - p_;
+ 174 + + }
+ 175 + +
+ 176 + +3071 std::size_t remain(const char* p) const noexcept
+ 177 + + {
+ 178 + +3071 return end_ - p;
+ 179 + + }
+ 180 + +
+ 181 + +2314817 std::size_t used(const char* p) const noexcept
+ 182 + + {
+ 183 + +2314817 return p_ - p;
+ 184 + + }
+ 185 + + };
+ 186 + +
+ 187 + + class clipped_const_stream
+ 188 + + : public const_stream_wrapper
+ 189 + + {
+ 190 + + const char* clip_;
+ 191 + +
+ 192 + + public:
+ 193 + +13678 clipped_const_stream(
+ 194 + + const char*& p,
+ 195 + + const char* end)
+ 196 + +13678 : const_stream_wrapper(p, end)
+ 197 + +13678 , clip_(end)
+ 198 + + {
+ 199 + +13678 }
+ 200 + +
+ 201 + + void operator=(const char* p)
+ 202 + + {
+ 203 + + p_ = p;
+ 204 + + }
+ 205 + +
+ 206 + + const char* end() const noexcept
+ 207 + + {
+ 208 + + return clip_;
+ 209 + + }
+ 210 + +
+ 211 + +68643 operator bool() const noexcept
+ 212 + + {
+ 213 + +68643 return p_ < clip_;
+ 214 + + }
+ 215 + +
+ 216 + +11688 std::size_t remain() const noexcept
+ 217 + + {
+ 218 + +11688 return clip_ - p_;
+ 219 + + }
+ 220 + +
+ 221 + + std::size_t remain(const char* p) const noexcept
+ 222 + + {
+ 223 + + return clip_ - p;
+ 224 + + }
+ 225 + +
+ 226 + + void
+ 227 + +15663 clip(std::size_t n) noexcept
+ 228 + + {
+ 229 + +15663 if(static_cast<std::size_t>(
+ 230 + +15663 end_ - p_) > n)
+ 231 + +37 clip_ = p_ + n;
+ 232 + + else
+ 233 + +15626 clip_ = end_;
+ 234 + +15663 }
+ 235 + + };
+ 236 + +
+ 237 + + //--------------------------------------
+ 238 + +
+ 239 + + class stream
+ 240 + + {
+ 241 + + friend class local_stream;
+ 242 + +
+ 243 + + char* p_;
+ 244 + + char* end_;
+ 245 + +
+ 246 + + public:
+ 247 + +32982 stream(
+ 248 + + char* data,
+ 249 + + std::size_t size) noexcept
+ 250 + +32982 : p_(data)
+ 251 + +32982 , end_(data + size)
+ 252 + + {
+ 253 + +32982 }
+ 254 + +
+ 255 + + size_t
+ 256 + +32980 used(char* begin) const noexcept
+ 257 + + {
+ 258 + + return static_cast<
+ 259 + +32980 size_t>(p_ - begin);
+ 260 + + }
+ 261 + +
+ 262 + + size_t
+ 263 + +90553 remain() const noexcept
+ 264 + + {
+ 265 + +90553 return end_ - p_;
+ 266 + + }
+ 267 + +
+ 268 + + char*
+ 269 + +2956 data() noexcept
+ 270 + + {
+ 271 + +2956 return p_;
+ 272 + + }
+ 273 + +
+ 274 + +31623944 operator bool() const noexcept
+ 275 + + {
+ 276 + +31623944 return p_ < end_;
+ 277 + + }
+ 278 + +
+ 279 + + // unchecked
+ 280 + + char&
+ 281 + + operator*() noexcept
+ 282 + + {
+ 283 + + BOOST_ASSERT(p_ < end_);
+ 284 + + return *p_;
+ 285 + + }
+ 286 + +
+ 287 + + // unchecked
+ 288 + + stream&
+ 289 + + operator++() noexcept
+ 290 + + {
+ 291 + + BOOST_ASSERT(p_ < end_);
+ 292 + + ++p_;
+ 293 + + return *this;
+ 294 + + }
+ 295 + +
+ 296 + + // unchecked
+ 297 + + void
+ 298 + +32736 append(
+ 299 + + char const* src,
+ 300 + + std::size_t n) noexcept
+ 301 + + {
+ 302 + +32736 BOOST_ASSERT(remain() >= n);
+ 303 + +32736 std::memcpy(p_, src, n);
+ 304 + +32736 p_ += n;
+ 305 + +32736 }
+ 306 + +
+ 307 + + // unchecked
+ 308 + + void
+ 309 + +31554204 append(char c) noexcept
+ 310 + + {
+ 311 + +31554204 BOOST_ASSERT(p_ < end_);
+ 312 + +31554204 *p_++ = c;
+ 313 + +31554204 }
+ 314 + +
+ 315 + + void
+ 316 + +2956 advance(std::size_t n) noexcept
+ 317 + + {
+ 318 + +2956 BOOST_ASSERT(remain() >= n);
+ 319 + +2956 p_ += n;
+ 320 + +2956 }
+ 321 + + };
+ 322 + +
+ 323 + + class local_stream
+ 324 + + : public stream
+ 325 + + {
+ 326 + + stream& src_;
+ 327 + +
+ 328 + + public:
+ 329 + + explicit
+ 330 + +84495 local_stream(
+ 331 + + stream& src)
+ 332 + +84495 : stream(src)
+ 333 + +84495 , src_(src)
+ 334 + + {
+ 335 + +84495 }
+ 336 + +
+ 337 + +84495 ~local_stream()
+ 338 + + {
+ 339 + +84495 src_.p_ = p_;
+ 340 + +84495 }
+ 341 + + };
+ 342 + +
+ 343 + + } // detail
+ 344 + + } // namespace json
+ 345 + + } // namespace boost
+ 346 + +
+ 347 + + #endif
+ 348 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.stream_parser.hpp.756a2056175378bf4974ad36f699d9ba.html b/json/gcovr/index.stream_parser.hpp.756a2056175378bf4974ad36f699d9ba.html new file mode 100644 index 00000000..140deb8e --- /dev/null +++ b/json/gcovr/index.stream_parser.hpp.756a2056175378bf4974ad36f699d9ba.html @@ -0,0 +1,7246 @@ + + + + + + stream_parser.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

stream_parser.hpp

+
+ + 100.0% Lines (31/31) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
stream_parser.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_STREAM_PARSER_HPP
+ 11 + + #define BOOST_JSON_STREAM_PARSER_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/json/basic_parser.hpp>
+ 15 + + #include <boost/json/parse_options.hpp>
+ 16 + + #include <boost/json/storage_ptr.hpp>
+ 17 + + #include <boost/json/value.hpp>
+ 18 + + #include <boost/json/detail/handler.hpp>
+ 19 + + #include <type_traits>
+ 20 + + #include <cstddef>
+ 21 + +
+ 22 + + namespace boost {
+ 23 + + namespace json {
+ 24 + +
+ 25 + + //----------------------------------------------------------
+ 26 + +
+ 27 + + /** A DOM parser for JSON text contained in multiple buffers.
+ 28 + +
+ 29 + + This class is used to parse a JSON text contained in a series of one or
+ 30 + + more character buffers, into a @ref value container. It implements a
+ 31 + + [_streaming algorithm_](https://en.wikipedia.org/wiki/Streaming_algorithm),
+ 32 + + allowing these parsing strategies:
+ 33 + +
+ 34 + + @li parse a JSON file a piece at a time;
+ 35 + + @li parse incoming JSON text as it arrives, one buffer at a time;
+ 36 + + @li parse with bounded resource consumption per cycle.
+ 37 + +
+ 38 + + @par Usage
+ 39 + + To use the parser first construct it, then optionally call @ref reset to
+ 40 + + specify a @ref storage_ptr to use for the resulting @ref value. Then call
+ 41 + + @ref write one or more times to parse a single, complete JSON text. Call
+ 42 + + @ref done to determine if the parse has completed. To indicate there are no
+ 43 + + more buffers, call @ref finish. If the parse is successful, call @ref
+ 44 + + release to take ownership of the value:
+ 45 + +
+ 46 + + @code
+ 47 + + stream_parser p; // construct a parser
+ 48 + + p.write( "[1,2" ); // parse some of a JSON text
+ 49 + + p.write( ",3,4]" ); // parse the rest of the JSON text
+ 50 + + assert( p.done() ); // we have a complete JSON text
+ 51 + + value jv = p.release(); // take ownership of the value
+ 52 + + @endcode
+ 53 + +
+ 54 + + @par Extra Data
+ 55 + + When the character buffer provided as input contains additional data that
+ 56 + + is not part of the complete JSON text, an error is returned. The @ref
+ 57 + + write_some function is an alternative which allows the parse to finish
+ 58 + + early, without consuming all the characters in the buffer. This allows
+ 59 + + parsing of a buffer containing multiple individual JSON texts or containing
+ 60 + + different protocol data:
+ 61 + +
+ 62 + + @code
+ 63 + + stream_parser p; // construct a parser
+ 64 + + std::size_t n; // number of characters used
+ 65 + + n = p.write_some( "[1,2" ); // parse some of a JSON text
+ 66 + + assert( n == 4 ); // all characters consumed
+ 67 + + n = p.write_some( ",3,4] null" ); // parse the remainder of the JSON text
+ 68 + + assert( n == 6 ); // only some characters consumed
+ 69 + + assert( p.done() ); // we have a complete JSON text
+ 70 + + value jv = p.release(); // take ownership of the value
+ 71 + + @endcode
+ 72 + +
+ 73 + + @par Temporary Storage
+ 74 + + The parser may dynamically allocate temporary storage as needed to
+ 75 + + accommodate the nesting level of the JSON text being parsed. Temporary
+ 76 + + storage is first obtained from an optional, caller-owned buffer specified
+ 77 + + upon construction. When that is exhausted, the next allocation uses the
+ 78 + + @ref boost::container::pmr::memory_resource passed to the constructor; if
+ 79 + + no such argument is specified, the default memory resource is used.
+ 80 + + Temporary storage is freed only when the parser is destroyed; The
+ 81 + + performance of parsing multiple JSON texts may be improved by reusing the
+ 82 + + same parser instance.
+ 83 + +
+ 84 + + It is important to note that the @ref
+ 85 + + boost::container::pmr::memory_resource supplied upon construction is used
+ 86 + + for temporary storage only, and not for allocating the elements which make
+ 87 + + up the parsed value. That other memory resource is optionally supplied in
+ 88 + + each call to @ref reset.
+ 89 + +
+ 90 + + @par Duplicate Keys
+ 91 + + If there are object elements with duplicate keys; that is, if multiple
+ 92 + + elements in an object have keys that compare equal, only the last
+ 93 + + equivalent element will be inserted.
+ 94 + +
+ 95 + + @par Non-Standard JSON
+ 96 + + The @ref parse_options structure optionally provided upon construction is
+ 97 + + used to customize some parameters of the parser, including which
+ 98 + + non-standard JSON extensions should be allowed. A default-constructed parse
+ 99 + + options allows only standard JSON.
+ 100 + +
+ 101 + + @par Thread Safety
+ 102 + + Distinct instances may be accessed concurrently. Non-const member functions
+ 103 + + of a shared instance may not be called concurrently with any other member
+ 104 + + functions of that instance.
+ 105 + +
+ 106 + + @see @ref parse, @ref parser, @ref parse_options.
+ 107 + + */
+ 108 + + class stream_parser
+ 109 + + {
+ 110 + + basic_parser<detail::handler> p_;
+ 111 + +
+ 112 + + public:
+ 113 + + /** Destructor.
+ 114 + +
+ 115 + + All dynamically allocated memory, including
+ 116 + + any incomplete parsing results, is freed.
+ 117 + +
+ 118 + + @par Complexity
+ 119 + + Linear in the size of partial results
+ 120 + +
+ 121 + + @par Exception Safety
+ 122 + + No-throw guarantee.
+ 123 + + */
+ 124 + +75326 ~stream_parser() = default;
+ 125 + +
+ 126 + + /** Constructors.
+ 127 + +
+ 128 + + Construct a new parser.
+ 129 + +
+ 130 + + The parser will only support standard JSON if overloads **(1)**
+ 131 + + or **(2)** are used. Otherwise the parser will support extensions
+ 132 + + specified by the parameter `opt`.
+ 133 + +
+ 134 + + The parsed value will use the \<\<default_memory_resource,default
+ 135 + + memory resource\>\> for storage. To use a different resource, call @ref
+ 136 + + reset after construction.
+ 137 + +
+ 138 + + The main difference between the overloads is in what the constructed
+ 139 + + parser will use for temporary storage:
+ 140 + +
+ 141 + + @li **(1)** the constructed parser uses the default memory resource for
+ 142 + + temporary storage.
+ 143 + +
+ 144 + + @li **(2)**, **(3)** the constructed parser uses the memory resource of
+ 145 + + `sp` for temporary storage.
+ 146 + +
+ 147 + + @li **(4)**, **(6)** the constructed parser first uses the caller-owned
+ 148 + + storage `[buffer, buffer + size)` for temporary storage, falling back
+ 149 + + to the memory resource of `sp` if needed.
+ 150 + +
+ 151 + + @li **(5)**, **(7)** the constructed parser first uses the caller-owned
+ 152 + + storage `[buffer, buffer + N)` for temporary storage, falling back to
+ 153 + + the memory resource of `sp` if needed.
+ 154 + +
+ 155 + + @note Ownership of `buffer` is not transferred. The caller is
+ 156 + + responsible for ensuring the lifetime of the storage pointed to by
+ 157 + + `buffer` extends until the parser is destroyed.
+ 158 + +
+ 159 + + Overload **(8)** is the copy constructor. The type is neither copyable
+ 160 + + nor movable, so the overload is deleted.
+ 161 + +
+ 162 + + @par Complexity
+ 163 + + Constant.
+ 164 + +
+ 165 + + @par Exception Safety
+ 166 + + No-throw guarantee.
+ 167 + +
+ 168 + + @{
+ 169 + + */
+ 170 + +187 stream_parser() noexcept
+ 171 + +187 : stream_parser({}, {})
+ 172 + + {
+ 173 + +187 }
+ 174 + +
+ 175 + +
+ 176 + + /** Overload
+ 177 + +
+ 178 + + @param sp The memory resource to use for temporary storage.
+ 179 + + */
+ 180 + + explicit
+ 181 + +2 stream_parser(storage_ptr sp) noexcept
+ 182 + +2 : stream_parser(std::move(sp), {})
+ 183 + + {
+ 184 + +2 }
+ 185 + +
+ 186 + + /** Overload
+ 187 + +
+ 188 + + @param opt The parsing options to use.
+ 189 + + @param sp
+ 190 + + */
+ 191 + + BOOST_JSON_DECL
+ 192 + + stream_parser(
+ 193 + + storage_ptr sp,
+ 194 + + parse_options const& opt) noexcept;
+ 195 + +
+ 196 + + /** Overload
+ 197 + + @param buffer A pointer to valid storage.
+ 198 + + @param size The number of valid bytes in `buffer`.
+ 199 + + @param sp
+ 200 + + @param opt
+ 201 + + */
+ 202 + + BOOST_JSON_DECL
+ 203 + + stream_parser(
+ 204 + + storage_ptr sp,
+ 205 + + parse_options const& opt,
+ 206 + + unsigned char* buffer,
+ 207 + + std::size_t size) noexcept;
+ 208 + +
+ 209 + + /** Overload
+ 210 + +
+ 211 + + @tparam N The number of valid bytes in `buffer`.
+ 212 + + @param sp
+ 213 + + @param opt
+ 214 + + @param buffer
+ 215 + + */
+ 216 + + template<std::size_t N>
+ 217 + +20 stream_parser(
+ 218 + + storage_ptr sp,
+ 219 + + parse_options const& opt,
+ 220 + + unsigned char(&buffer)[N]) noexcept
+ 221 + +20 : stream_parser(std::move(sp),
+ 222 + +20 opt, &buffer[0], N)
+ 223 + + {
+ 224 + +20 }
+ 225 + +
+ 226 + + #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
+ 227 + + /** Overload
+ 228 + +
+ 229 + + @param sp
+ 230 + + @param opt
+ 231 + + @param buffer
+ 232 + + @param size
+ 233 + + */
+ 234 + + stream_parser(
+ 235 + + storage_ptr sp,
+ 236 + + parse_options const& opt,
+ 237 + + std::byte* buffer,
+ 238 + + std::size_t size) noexcept
+ 239 + + : stream_parser(sp, opt, reinterpret_cast<
+ 240 + + unsigned char*>(buffer), size)
+ 241 + + {
+ 242 + + }
+ 243 + +
+ 244 + + /** Overload
+ 245 + +
+ 246 + + @tparam N
+ 247 + + @param sp
+ 248 + + @param opt
+ 249 + + @param buffer
+ 250 + + */
+ 251 + + template<std::size_t N>
+ 252 + + stream_parser(
+ 253 + + storage_ptr sp,
+ 254 + + parse_options const& opt,
+ 255 + + std::byte(&buffer)[N]) noexcept
+ 256 + + : stream_parser(std::move(sp),
+ 257 + + opt, &buffer[0], N)
+ 258 + + {
+ 259 + + }
+ 260 + + #endif
+ 261 + +
+ 262 + + #ifndef BOOST_JSON_DOCS
+ 263 + + // Safety net for accidental buffer overflows
+ 264 + + template<std::size_t N>
+ 265 + + stream_parser(
+ 266 + + storage_ptr sp,
+ 267 + + parse_options const& opt,
+ 268 + + unsigned char(&buffer)[N],
+ 269 + + std::size_t n) noexcept
+ 270 + + : stream_parser(std::move(sp),
+ 271 + + opt, &buffer[0], n)
+ 272 + + {
+ 273 + + // If this goes off, check your parameters
+ 274 + + // closely, chances are you passed an array
+ 275 + + // thinking it was a pointer.
+ 276 + + BOOST_ASSERT(n <= N);
+ 277 + + }
+ 278 + +
+ 279 + + #ifdef __cpp_lib_byte
+ 280 + + // Safety net for accidental buffer overflows
+ 281 + + template<std::size_t N>
+ 282 + + stream_parser(
+ 283 + + storage_ptr sp,
+ 284 + + parse_options const& opt,
+ 285 + + std::byte(&buffer)[N], std::size_t n) noexcept
+ 286 + + : stream_parser(std::move(sp),
+ 287 + + opt, &buffer[0], n)
+ 288 + + {
+ 289 + + // If this goes off, check your parameters
+ 290 + + // closely, chances are you passed an array
+ 291 + + // thinking it was a pointer.
+ 292 + + BOOST_ASSERT(n <= N);
+ 293 + + }
+ 294 + + #endif
+ 295 + + #endif
+ 296 + +
+ 297 + + /// Overload
+ 298 + + stream_parser(
+ 299 + + stream_parser const&) = delete;
+ 300 + + /// @}
+ 301 + +
+ 302 + + /** Assignment operator.
+ 303 + +
+ 304 + + This type is neither copyable nor movable, so copy assignment operator
+ 305 + + is deleted.
+ 306 + + */
+ 307 + + stream_parser& operator=(
+ 308 + + stream_parser const&) = delete;
+ 309 + +
+ 310 + + /** Reset the parser for a new JSON text.
+ 311 + +
+ 312 + + This function is used to reset the parser to prepare it for parsing
+ 313 + + a new complete JSON text. Any previous partial results are destroyed.
+ 314 + + The new value will use the memory resource of `sp`.
+ 315 + +
+ 316 + + @par Complexity
+ 317 + + Constant or linear in the size of any previous partial parsing results.
+ 318 + +
+ 319 + + @par Exception Safety
+ 320 + + No-throw guarantee.
+ 321 + +
+ 322 + + @param sp A pointer to the @ref boost::container::pmr::memory_resource.
+ 323 + + */
+ 324 + + BOOST_JSON_DECL
+ 325 + + void
+ 326 + + reset(storage_ptr sp = {}) noexcept;
+ 327 + +
+ 328 + + /** Check if a complete JSON text has been parsed.
+ 329 + +
+ 330 + + This function returns `true` when all of these conditions are met:
+ 331 + +
+ 332 + + @li A complete serialized JSON text has been presented to the parser,
+ 333 + + and
+ 334 + +
+ 335 + + @li No error has occurred since the parser was constructed, or since
+ 336 + + the last call to @ref reset,
+ 337 + +
+ 338 + + @par Complexity
+ 339 + + Constant.
+ 340 + +
+ 341 + + @par Exception Safety
+ 342 + + No-throw guarantee.
+ 343 + + */
+ 344 + + bool
+ 345 + +30 done() const noexcept
+ 346 + + {
+ 347 + +30 return p_.done();
+ 348 + + }
+ 349 + +
+ 350 + + /** Parse a buffer containing all or part of a complete JSON text.
+ 351 + +
+ 352 + + This function parses JSON text contained in the specified character
+ 353 + + buffer. If parsing completes, any additional characters past the end of
+ 354 + + the complete JSON text are ignored. The function returns the actual
+ 355 + + number of characters parsed, which may be less than the size of the
+ 356 + + input. This allows parsing of a buffer containing multiple individual
+ 357 + + JSON texts or containing different protocol data.
+ 358 + +
+ 359 + + Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
+ 360 + + setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
+ 361 + + exceptions. Upon error or exception, subsequent calls will fail until
+ 362 + + @ref reset is called to parse a new JSON text.
+ 363 + +
+ 364 + + @note To indicate there are no more character buffers, such as when
+ 365 + + @ref done returns `false` after writing, call @ref finish.
+ 366 + +
+ 367 + + @par Example
+ 368 + + @code
+ 369 + + stream_parser p; // construct a parser
+ 370 + + std::size_t n; // number of characters used
+ 371 + + n = p.write_some( "[1,2" ); // parse the first part of the JSON text
+ 372 + + assert( n == 4 ); // all characters consumed
+ 373 + + n = p.write_some( "3,4] null" ); // parse the rest of the JSON text
+ 374 + + assert( n == 5 ); // only some characters consumed
+ 375 + + value jv = p.release(); // take ownership of the value
+ 376 + + @endcode
+ 377 + +
+ 378 + + @par Complexity
+ 379 + + @li **(1)**--**(3)** linear in `size`.
+ 380 + + @li **(4)**--**(6)** linear in `s.size()`.
+ 381 + +
+ 382 + + @par Exception Safety
+ 383 + + Basic guarantee. Calls to `memory_resource::allocate` may throw.
+ 384 + +
+ 385 + + @return The number of characters consumed from the buffer.
+ 386 + +
+ 387 + + @param data A pointer to a buffer of `size` characters to parse.
+ 388 + + @param size The number of characters pointed to by `data`.
+ 389 + + @param ec Set to the error, if any occurred.
+ 390 + +
+ 391 + + @{
+ 392 + + */
+ 393 + + BOOST_JSON_DECL
+ 394 + + std::size_t
+ 395 + + write_some(
+ 396 + + char const* data,
+ 397 + + std::size_t size,
+ 398 + + system::error_code& ec);
+ 399 + +
+ 400 + + BOOST_JSON_DECL
+ 401 + + std::size_t
+ 402 + + write_some(
+ 403 + + char const* data,
+ 404 + + std::size_t size,
+ 405 + + std::error_code& ec);
+ 406 + +
+ 407 + + /** Overload
+ 408 + +
+ 409 + + @param data
+ 410 + + @param size
+ 411 + +
+ 412 + + @throw boost::system::system_error Thrown on error.
+ 413 + + */
+ 414 + + BOOST_JSON_DECL
+ 415 + + std::size_t
+ 416 + + write_some(
+ 417 + + char const* data,
+ 418 + + std::size_t size);
+ 419 + +
+ 420 + + /** Overload
+ 421 + + @param s The character string to parse.
+ 422 + + @param ec
+ 423 + + */
+ 424 + + std::size_t
+ 425 + +2 write_some(
+ 426 + + string_view s,
+ 427 + + system::error_code& ec)
+ 428 + + {
+ 429 + +2 return write_some(
+ 430 + +2 s.data(), s.size(), ec);
+ 431 + + }
+ 432 + +
+ 433 + + /** Overload
+ 434 + + @param s
+ 435 + + @param ec
+ 436 + + */
+ 437 + + std::size_t
+ 438 + +2 write_some(
+ 439 + + string_view s,
+ 440 + + std::error_code& ec)
+ 441 + + {
+ 442 + +2 return write_some(
+ 443 + +2 s.data(), s.size(), ec);
+ 444 + + }
+ 445 + +
+ 446 + + /** Overload
+ 447 + + @param s
+ 448 + + */
+ 449 + + std::size_t
+ 450 + +4 write_some(
+ 451 + + string_view s)
+ 452 + + {
+ 453 + +4 return write_some(
+ 454 + +3 s.data(), s.size());
+ 455 + + }
+ 456 + + /// @}
+ 457 + +
+ 458 + + /** Parse a buffer containing all or part of a complete JSON text.
+ 459 + +
+ 460 + + This function parses all or part of a JSON text contained in the
+ 461 + + specified character buffer. The entire buffer must be consumed; if
+ 462 + + there are additional characters past the end of the complete JSON text,
+ 463 + + the parse fails and an error is returned.
+ 464 + +
+ 465 + + Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
+ 466 + + setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
+ 467 + + exceptions. Upon error or exception, subsequent calls will fail until
+ 468 + + @ref reset is called to parse a new JSON text.
+ 469 + +
+ 470 + + @note To indicate there are no more character buffers, such as when
+ 471 + + @ref done returns `false` after writing, call @ref finish.
+ 472 + +
+ 473 + + @par Example
+ 474 + + @code
+ 475 + + stream_parser p; // construct a parser
+ 476 + + std::size_t n; // number of characters used
+ 477 + + n = p.write( "[1,2" ); // parse some of the JSON text
+ 478 + + assert( n == 4 ); // all characters consumed
+ 479 + + n = p.write( "3,4]" ); // parse the rest of the JSON text
+ 480 + + assert( n == 4 ); // all characters consumed
+ 481 + + value jv = p.release(); // take ownership of the value
+ 482 + + @endcode
+ 483 + +
+ 484 + + @par Complexity
+ 485 + + @li **(1)**--**(3)** linear in `size`.
+ 486 + + @li **(4)**--**(6)** linear in `s.size()`.
+ 487 + +
+ 488 + + @par Exception Safety
+ 489 + + Basic guarantee. Calls to `memory_resource::allocate` may throw.
+ 490 + + @return The number of characters consumed from the buffer.
+ 491 + +
+ 492 + + @param data A pointer to a buffer of `size` characters to parse.
+ 493 + +
+ 494 + + @param size The number of characters pointed to by `data`.
+ 495 + +
+ 496 + + @param ec Set to the error, if any occurred.
+ 497 + +
+ 498 + + @{
+ 499 + + */
+ 500 + + BOOST_JSON_DECL
+ 501 + + std::size_t
+ 502 + + write(
+ 503 + + char const* data,
+ 504 + + std::size_t size,
+ 505 + + system::error_code& ec);
+ 506 + +
+ 507 + + BOOST_JSON_DECL
+ 508 + + std::size_t
+ 509 + + write(
+ 510 + + char const* data,
+ 511 + + std::size_t size,
+ 512 + + std::error_code& ec);
+ 513 + +
+ 514 + + /** Overload
+ 515 + +
+ 516 + + @param data
+ 517 + + @param size
+ 518 + +
+ 519 + + @throw boost::system::system_error Thrown on error.
+ 520 + + */
+ 521 + + BOOST_JSON_DECL
+ 522 + + std::size_t
+ 523 + + write(
+ 524 + + char const* data,
+ 525 + + std::size_t size);
+ 526 + +
+ 527 + + /** Overload
+ 528 + +
+ 529 + + @param s The character string to parse.
+ 530 + + @param ec
+ 531 + + */
+ 532 + + std::size_t
+ 533 + +3 write(
+ 534 + + string_view s,
+ 535 + + system::error_code& ec)
+ 536 + + {
+ 537 + +3 return write(
+ 538 + +3 s.data(), s.size(), ec);
+ 539 + + }
+ 540 + +
+ 541 + + /** Overload
+ 542 + +
+ 543 + + @param s
+ 544 + + @param ec
+ 545 + + */
+ 546 + + std::size_t
+ 547 + +2 write(
+ 548 + + string_view s,
+ 549 + + std::error_code& ec)
+ 550 + + {
+ 551 + +2 return write(
+ 552 + +2 s.data(), s.size(), ec);
+ 553 + + }
+ 554 + +
+ 555 + + /** Overload
+ 556 + + @param s
+ 557 + + */
+ 558 + + std::size_t
+ 559 + +9 write(
+ 560 + + string_view s)
+ 561 + + {
+ 562 + +9 return write(
+ 563 + +8 s.data(), s.size());
+ 564 + + }
+ 565 + + /// @}
+ 566 + +
+ 567 + + /** Indicate the end of JSON input.
+ 568 + +
+ 569 + + This function is used to indicate that there are no more character
+ 570 + + buffers in the current JSON text being parsed. If the resulting JSON
+ 571 + + text is incomplete, **(1)** and **(2)** assign the relevant
+ 572 + + `error_code` to `ec`, while **(3)** throws an exception.
+ 573 + +
+ 574 + + Upon error or exception, subsequent calls will fail until @ref reset is
+ 575 + + called to parse a new JSON text.
+ 576 + +
+ 577 + + @par Example
+ 578 + + In the code below, @ref finish is called to
+ 579 + + indicate there are no more digits in the
+ 580 + + resulting number:
+ 581 + + @code
+ 582 + + stream_parser p; // construct a parser
+ 583 + + p.write( "3." ); // write the first part of the number
+ 584 + + p.write( "14" ); // write the second part of the number
+ 585 + + assert( ! p.done() ); // there could be more digits
+ 586 + + p.finish(); // indicate the end of the JSON input
+ 587 + + assert( p.done() ); // now we are finished
+ 588 + + value jv = p.release(); // take ownership of the value
+ 589 + + @endcode
+ 590 + +
+ 591 + + @par Complexity
+ 592 + + Constant.
+ 593 + +
+ 594 + + @par Exception Safety
+ 595 + + Basic guarantee. Calls to `memory_resource::allocate` may throw.
+ 596 + +
+ 597 + + @param ec Set to the error, if any occurred.
+ 598 + +
+ 599 + + @{
+ 600 + + */
+ 601 + + BOOST_JSON_DECL
+ 602 + + void
+ 603 + + finish(system::error_code& ec);
+ 604 + +
+ 605 + + BOOST_JSON_DECL
+ 606 + + void
+ 607 + + finish(std::error_code& ec);
+ 608 + +
+ 609 + + /** Overload
+ 610 + +
+ 611 + + @throw boost::system::system_error Parsing error.
+ 612 + + */
+ 613 + + BOOST_JSON_DECL
+ 614 + + void
+ 615 + + finish();
+ 616 + + /// @}
+ 617 + +
+ 618 + + /** Return the parsed JSON as a @ref value.
+ 619 + +
+ 620 + + This returns the parsed value, or throws an exception if the parsing is
+ 621 + + incomplete or failed. If `! this->done()`, calls @ref finish() first.
+ 622 + + It is necessary to call @ref reset after calling this function in order
+ 623 + + to parse another JSON text.
+ 624 + +
+ 625 + + @par Complexity
+ 626 + + Constant.
+ 627 + +
+ 628 + + @return The parsed value. Ownership of this value is transferred to the
+ 629 + + caller.
+ 630 + +
+ 631 + + @throw boost::system::system_error A complete JSON text hasn't been
+ 632 + + parsed, or parsing failed.
+ 633 + + */
+ 634 + + BOOST_JSON_DECL
+ 635 + + value
+ 636 + + release();
+ 637 + + };
+ 638 + +
+ 639 + + } // namespace json
+ 640 + + } // namespace boost
+ 641 + +
+ 642 + + #endif
+ 643 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.stream_parser.ipp.9e84d7cb15fc2f2f5eb0a5dbb07fed15.html b/json/gcovr/index.stream_parser.ipp.9e84d7cb15fc2f2f5eb0a5dbb07fed15.html new file mode 100644 index 00000000..01538ff0 --- /dev/null +++ b/json/gcovr/index.stream_parser.ipp.9e84d7cb15fc2f2f5eb0a5dbb07fed15.html @@ -0,0 +1,3566 @@ + + + + + + impl/stream_parser.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/stream_parser.ipp

+
+ + 100.0% Lines (67/67) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/stream_parser.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_STREAM_PARSER_IPP
+ 11 + + #define BOOST_JSON_IMPL_STREAM_PARSER_IPP
+ 12 + +
+ 13 + + #include <boost/json/stream_parser.hpp>
+ 14 + + #include <boost/json/basic_parser_impl.hpp>
+ 15 + + #include <boost/json/error.hpp>
+ 16 + + #include <cstring>
+ 17 + + #include <stdexcept>
+ 18 + + #include <utility>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + +
+ 23 + +22 stream_parser::
+ 24 + + stream_parser(
+ 25 + + storage_ptr sp,
+ 26 + + parse_options const& opt,
+ 27 + + unsigned char* buffer,
+ 28 + +22 std::size_t size) noexcept
+ 29 + +22 : p_(
+ 30 + + opt,
+ 31 + +22 std::move(sp),
+ 32 + + buffer,
+ 33 + + size)
+ 34 + + {
+ 35 + +22 reset();
+ 36 + +22 }
+ 37 + +
+ 38 + +75304 stream_parser::
+ 39 + + stream_parser(
+ 40 + + storage_ptr sp,
+ 41 + +75304 parse_options const& opt) noexcept
+ 42 + +75304 : p_(
+ 43 + + opt,
+ 44 + +75304 std::move(sp),
+ 45 + +150608 nullptr,
+ 46 + +75304 0)
+ 47 + + {
+ 48 + +75304 reset();
+ 49 + +75304 }
+ 50 + +
+ 51 + + void
+ 52 + +150055 stream_parser::
+ 53 + + reset(storage_ptr sp) noexcept
+ 54 + + {
+ 55 + +150055 p_.reset();
+ 56 + +150055 p_.handler().st.reset(sp);
+ 57 + +150055 }
+ 58 + +
+ 59 + + std::size_t
+ 60 + +130421 stream_parser::
+ 61 + + write_some(
+ 62 + + char const* data,
+ 63 + + std::size_t size,
+ 64 + + system::error_code& ec)
+ 65 + + {
+ 66 + +130421 return p_.write_some(
+ 67 + +130280 true, data, size, ec);
+ 68 + + }
+ 69 + +
+ 70 + + std::size_t
+ 71 + +2 stream_parser::
+ 72 + + write_some(
+ 73 + + char const* data,
+ 74 + + std::size_t size,
+ 75 + + std::error_code& ec)
+ 76 + + {
+ 77 + +2 system::error_code jec;
+ 78 + +2 std::size_t const result = write_some(data, size, jec);
+ 79 + +2 ec = jec;
+ 80 + +2 return result;
+ 81 + + }
+ 82 + +
+ 83 + + std::size_t
+ 84 + +6 stream_parser::
+ 85 + + write_some(
+ 86 + + char const* data,
+ 87 + + std::size_t size)
+ 88 + + {
+ 89 + +6 system::error_code ec;
+ 90 + +6 auto const n = write_some(
+ 91 + + data, size, ec);
+ 92 + +6 if(ec)
+ 93 + +1 detail::throw_system_error( ec );
+ 94 + +5 return n;
+ 95 + + }
+ 96 + +
+ 97 + + std::size_t
+ 98 + +130392 stream_parser::
+ 99 + + write(
+ 100 + + char const* data,
+ 101 + + std::size_t size,
+ 102 + + system::error_code& ec)
+ 103 + + {
+ 104 + +130392 auto const n = write_some(
+ 105 + + data, size, ec);
+ 106 + +130251 if(! ec && n < size)
+ 107 + + {
+ 108 + +6 BOOST_JSON_FAIL(ec, error::extra_data);
+ 109 + +6 p_.fail(ec);
+ 110 + + }
+ 111 + +130251 return n;
+ 112 + + }
+ 113 + +
+ 114 + + std::size_t
+ 115 + +2 stream_parser::
+ 116 + + write(
+ 117 + + char const* data,
+ 118 + + std::size_t size,
+ 119 + + std::error_code& ec)
+ 120 + + {
+ 121 + +2 system::error_code jec;
+ 122 + +2 std::size_t const result = write(data, size, jec);
+ 123 + +2 ec = jec;
+ 124 + +2 return result;
+ 125 + + }
+ 126 + +
+ 127 + + std::size_t
+ 128 + +11 stream_parser::
+ 129 + + write(
+ 130 + + char const* data,
+ 131 + + std::size_t size)
+ 132 + + {
+ 133 + +11 system::error_code ec;
+ 134 + +11 auto const n = write(
+ 135 + + data, size, ec);
+ 136 + +11 if(ec)
+ 137 + +1 detail::throw_system_error( ec );
+ 138 + +10 return n;
+ 139 + + }
+ 140 + +
+ 141 + + void
+ 142 + +75152 stream_parser::
+ 143 + + finish(system::error_code& ec)
+ 144 + + {
+ 145 + +75152 p_.write_some(false, nullptr, 0, ec);
+ 146 + +75152 }
+ 147 + +
+ 148 + + void
+ 149 + +8 stream_parser::
+ 150 + + finish()
+ 151 + + {
+ 152 + +8 system::error_code ec;
+ 153 + +8 finish(ec);
+ 154 + +8 if(ec)
+ 155 + +6 detail::throw_system_error( ec );
+ 156 + +2 }
+ 157 + +
+ 158 + + void
+ 159 + +2 stream_parser::
+ 160 + + finish(std::error_code& ec)
+ 161 + + {
+ 162 + +2 system::error_code jec;
+ 163 + +2 finish(jec);
+ 164 + +2 ec = jec;
+ 165 + +2 }
+ 166 + +
+ 167 + + value
+ 168 + +75151 stream_parser::
+ 169 + + release()
+ 170 + + {
+ 171 + +75151 if(! p_.done())
+ 172 + + {
+ 173 + + // prevent undefined behavior
+ 174 + +4 finish();
+ 175 + + }
+ 176 + +75148 return p_.handler().st.release();
+ 177 + + }
+ 178 + +
+ 179 + + } // namespace json
+ 180 + + } // namespace boost
+ 181 + +
+ 182 + + #endif
+ 183 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.string.hpp.753c5fbae83abdbca988b8d9bf6c7e2c.html b/json/gcovr/index.string.hpp.753c5fbae83abdbca988b8d9bf6c7e2c.html new file mode 100644 index 00000000..bde50a35 --- /dev/null +++ b/json/gcovr/index.string.hpp.753c5fbae83abdbca988b8d9bf6c7e2c.html @@ -0,0 +1,4126 @@ + + + + + + impl/string.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/string.hpp

+
+ + 100.0% Lines (69/69) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/string.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_STRING_HPP
+ 11 + + #define BOOST_JSON_IMPL_STRING_HPP
+ 12 + +
+ 13 + + #include <utility>
+ 14 + +
+ 15 + + namespace boost {
+ 16 + + namespace json {
+ 17 + +
+ 18 + +30296 string::
+ 19 + + string(
+ 20 + + detail::key_t const&,
+ 21 + + string_view s,
+ 22 + +30296 storage_ptr sp)
+ 23 + +30296 : sp_(std::move(sp))
+ 24 + +30296 , impl_(detail::key_t{},
+ 25 + +30296 s, sp_)
+ 26 + + {
+ 27 + +30296 }
+ 28 + +
+ 29 + +8060 string::
+ 30 + + string(
+ 31 + + detail::key_t const&,
+ 32 + + string_view s1,
+ 33 + + string_view s2,
+ 34 + +8060 storage_ptr sp)
+ 35 + +8060 : sp_(std::move(sp))
+ 36 + +8060 , impl_(detail::key_t{},
+ 37 + +8060 s1, s2, sp_)
+ 38 + + {
+ 39 + +8060 }
+ 40 + +
+ 41 + + template<class InputIt, class>
+ 42 + +31 string::
+ 43 + + string(
+ 44 + + InputIt first,
+ 45 + + InputIt last,
+ 46 + + storage_ptr sp)
+ 47 + +31 : sp_(std::move(sp))
+ 48 + +31 , impl_(first, last, sp_,
+ 49 + +21 iter_cat<InputIt>{})
+ 50 + + {
+ 51 + +31 }
+ 52 + +
+ 53 + + template<class InputIt, class>
+ 54 + + string&
+ 55 + +13 string::
+ 56 + + assign(
+ 57 + + InputIt first,
+ 58 + + InputIt last)
+ 59 + + {
+ 60 + +13 assign(first, last,
+ 61 + + iter_cat<InputIt>{});
+ 62 + +10 return *this;
+ 63 + + }
+ 64 + +
+ 65 + + template<class InputIt, class>
+ 66 + + string&
+ 67 + +6 string::
+ 68 + + append(InputIt first, InputIt last)
+ 69 + + {
+ 70 + +6 append(first, last,
+ 71 + + iter_cat<InputIt>{});
+ 72 + +4 return *this;
+ 73 + + }
+ 74 + +
+ 75 + + // KRYSTIAN TODO: this can be done without copies when
+ 76 + + // reallocation is not needed, when the iterator is a
+ 77 + + // FowardIterator or better, as we can use std::distance
+ 78 + + template<class InputIt, class>
+ 79 + + auto
+ 80 + +6 string::
+ 81 + + insert(
+ 82 + + size_type pos,
+ 83 + + InputIt first,
+ 84 + + InputIt last) ->
+ 85 + + string&
+ 86 + + {
+ 87 + + struct cleanup
+ 88 + + {
+ 89 + + detail::string_impl& s;
+ 90 + + storage_ptr const& sp;
+ 91 + +
+ 92 + +6 ~cleanup()
+ 93 + + {
+ 94 + +6 s.destroy(sp);
+ 95 + +6 }
+ 96 + + };
+ 97 + +
+ 98 + + // We use the default storage because
+ 99 + + // the allocation is immediately freed.
+ 100 + +6 storage_ptr dsp;
+ 101 + +6 detail::string_impl tmp(
+ 102 + + first, last, dsp,
+ 103 + + iter_cat<InputIt>{});
+ 104 + +6 cleanup c{tmp, dsp};
+ 105 + +6 std::memcpy(
+ 106 + +6 impl_.insert_unchecked(pos, tmp.size(), sp_),
+ 107 + +6 tmp.data(),
+ 108 + + tmp.size());
+ 109 + +4 return *this;
+ 110 + +8 }
+ 111 + +
+ 112 + + // KRYSTIAN TODO: this can be done without copies when
+ 113 + + // reallocation is not needed, when the iterator is a
+ 114 + + // FowardIterator or better, as we can use std::distance
+ 115 + + template<class InputIt, class>
+ 116 + + auto
+ 117 + + string::
+ 118 + + replace(
+ 119 + + const_iterator first,
+ 120 + + const_iterator last,
+ 121 + + InputIt first2,
+ 122 + + InputIt last2) ->
+ 123 + + string&
+ 124 + + {
+ 125 + + struct cleanup
+ 126 + + {
+ 127 + + detail::string_impl& s;
+ 128 + + storage_ptr const& sp;
+ 129 + +
+ 130 + + ~cleanup()
+ 131 + + {
+ 132 + + s.destroy(sp);
+ 133 + + }
+ 134 + + };
+ 135 + +
+ 136 + + // We use the default storage because
+ 137 + + // the allocation is immediately freed.
+ 138 + + storage_ptr dsp;
+ 139 + + detail::string_impl tmp(
+ 140 + + first2, last2, dsp,
+ 141 + + iter_cat<InputIt>{});
+ 142 + + cleanup c{tmp, dsp};
+ 143 + + std::memcpy(
+ 144 + + impl_.replace_unchecked(
+ 145 + + first - begin(),
+ 146 + + last - first,
+ 147 + + tmp.size(),
+ 148 + + sp_),
+ 149 + + tmp.data(),
+ 150 + + tmp.size());
+ 151 + + return *this;
+ 152 + + }
+ 153 + +
+ 154 + + //----------------------------------------------------------
+ 155 + +
+ 156 + + template<class InputIt>
+ 157 + + void
+ 158 + +6 string::
+ 159 + + assign(
+ 160 + + InputIt first,
+ 161 + + InputIt last,
+ 162 + + std::random_access_iterator_tag)
+ 163 + + {
+ 164 + +6 auto dest = impl_.assign(static_cast<
+ 165 + +6 size_type>(last - first), sp_);
+ 166 + +63 while(first != last)
+ 167 + +58 *dest++ = *first++;
+ 168 + +5 }
+ 169 + +
+ 170 + + template<class InputIt>
+ 171 + + void
+ 172 + +7 string::
+ 173 + + assign(
+ 174 + + InputIt first,
+ 175 + + InputIt last,
+ 176 + + std::input_iterator_tag)
+ 177 + + {
+ 178 + +7 if(first == last)
+ 179 + + {
+ 180 + +1 impl_.term(0);
+ 181 + +1 return;
+ 182 + + }
+ 183 + +6 detail::string_impl tmp(
+ 184 + +6 first, last, sp_,
+ 185 + + std::input_iterator_tag{});
+ 186 + +4 impl_.destroy(sp_);
+ 187 + +4 impl_ = tmp;
+ 188 + + }
+ 189 + +
+ 190 + + template<class InputIt>
+ 191 + + void
+ 192 + +3 string::
+ 193 + + append(
+ 194 + + InputIt first,
+ 195 + + InputIt last,
+ 196 + + std::random_access_iterator_tag)
+ 197 + + {
+ 198 + +
+ 199 + +3 auto const n = static_cast<
+ 200 + +3 size_type>(last - first);
+ 201 + +3 char* out = impl_.append(n, sp_);
+ 202 + + #if defined(_MSC_VER) && _MSC_VER <= 1900
+ 203 + + while( first != last )
+ 204 + + *out++ = *first++;
+ 205 + + #else
+ 206 + +2 std::copy(first, last, out);
+ 207 + + #endif
+ 208 + +2 }
+ 209 + +
+ 210 + + template<class InputIt>
+ 211 + + void
+ 212 + +3 string::
+ 213 + + append(
+ 214 + + InputIt first,
+ 215 + + InputIt last,
+ 216 + + std::input_iterator_tag)
+ 217 + + {
+ 218 + + struct cleanup
+ 219 + + {
+ 220 + + detail::string_impl& s;
+ 221 + + storage_ptr const& sp;
+ 222 + +
+ 223 + +3 ~cleanup()
+ 224 + + {
+ 225 + +3 s.destroy(sp);
+ 226 + +3 }
+ 227 + + };
+ 228 + +
+ 229 + + // We use the default storage because
+ 230 + + // the allocation is immediately freed.
+ 231 + +3 storage_ptr dsp;
+ 232 + +3 detail::string_impl tmp(
+ 233 + + first, last, dsp,
+ 234 + + std::input_iterator_tag{});
+ 235 + +3 cleanup c{tmp, dsp};
+ 236 + +3 std::memcpy(
+ 237 + +3 impl_.append(tmp.size(), sp_),
+ 238 + +3 tmp.data(), tmp.size());
+ 239 + +4 }
+ 240 + +
+ 241 + + char&
+ 242 + +15 string::at(std::size_t pos, source_location const& loc)
+ 243 + + {
+ 244 + +
+ 245 + +15 auto const& self = *this;
+ 246 + +15 return const_cast< char& >( self.at(pos, loc) );
+ 247 + + }
+ 248 + +
+ 249 + + } // namespace json
+ 250 + + } // namespace boost
+ 251 + +
+ 252 + + #endif
+ 253 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.string.hpp.a0ee7b78a1e1a48649112e27bc32c7ed.html b/json/gcovr/index.string.hpp.a0ee7b78a1e1a48649112e27bc32c7ed.html new file mode 100644 index 00000000..3849aeb4 --- /dev/null +++ b/json/gcovr/index.string.hpp.a0ee7b78a1e1a48649112e27bc32c7ed.html @@ -0,0 +1,19846 @@ + + + + + + string.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

string.hpp

+
+ + 100.0% Lines (151/151) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
string.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_STRING_HPP
+ 12 + + #define BOOST_JSON_STRING_HPP
+ 13 + +
+ 14 + + #include <boost/json/detail/config.hpp>
+ 15 + + #include <boost/json/pilfer.hpp>
+ 16 + + #include <boost/json/storage_ptr.hpp>
+ 17 + + #include <boost/json/string_view.hpp>
+ 18 + + #include <boost/json/detail/digest.hpp>
+ 19 + + #include <boost/json/detail/except.hpp>
+ 20 + + #include <boost/json/detail/string_impl.hpp>
+ 21 + + #include <boost/json/detail/value.hpp>
+ 22 + + #include <boost/system/result.hpp>
+ 23 + + #include <cstring>
+ 24 + + #include <iosfwd>
+ 25 + + #include <iterator>
+ 26 + + #include <new>
+ 27 + + #include <type_traits>
+ 28 + + #include <utility>
+ 29 + +
+ 30 + + namespace boost {
+ 31 + + namespace json {
+ 32 + +
+ 33 + + class value;
+ 34 + +
+ 35 + + /** The native type of string values.
+ 36 + +
+ 37 + + Instances of string store and manipulate sequences of `char` using the
+ 38 + + UTF-8 encoding. The elements of a string are stored contiguously. A pointer
+ 39 + + to any character in a string may be passed to functions that expect
+ 40 + + a pointer to the first element of a null-terminated `char` array. The type
+ 41 + + uses small buffer optimisation to avoid allocations for small strings.
+ 42 + +
+ 43 + + String iterators are regular `char` pointers.
+ 44 + +
+ 45 + + @attention `string` member functions do not validate any UTF-8 byte sequences
+ 46 + + passed to them.
+ 47 + +
+ 48 + + @par Thread Safety
+ 49 + + Non-const member functions may not be called concurrently with any other
+ 50 + + member functions.
+ 51 + +
+ 52 + + @par Satisfies
+ 53 + + [_ContiguousContainer_](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
+ 54 + + [_ReversibleContainer_](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer),
+ 55 + + and {req_SequenceContainer}.
+ 56 + + */
+ 57 + + class string
+ 58 + + {
+ 59 + + friend class value;
+ 60 + + #ifndef BOOST_JSON_DOCS
+ 61 + + // VFALCO doc toolchain shouldn't show this but does
+ 62 + + friend struct detail::access;
+ 63 + + #endif
+ 64 + +
+ 65 + + using string_impl = detail::string_impl;
+ 66 + +
+ 67 + + inline
+ 68 + + string(
+ 69 + + detail::key_t const&,
+ 70 + + string_view s,
+ 71 + + storage_ptr sp);
+ 72 + +
+ 73 + + inline
+ 74 + + string(
+ 75 + + detail::key_t const&,
+ 76 + + string_view s1,
+ 77 + + string_view s2,
+ 78 + + storage_ptr sp);
+ 79 + +
+ 80 + + public:
+ 81 + + /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
+ 82 + + using allocator_type = container::pmr::polymorphic_allocator<value>;
+ 83 + +
+ 84 + + /// The type of a character
+ 85 + + using value_type = char;
+ 86 + +
+ 87 + + /// The type used to represent unsigned integers
+ 88 + + using size_type = std::size_t;
+ 89 + +
+ 90 + + /// The type used to represent signed integers
+ 91 + + using difference_type = std::ptrdiff_t;
+ 92 + +
+ 93 + + /// A pointer to an element
+ 94 + + using pointer = char*;
+ 95 + +
+ 96 + + /// A const pointer to an element
+ 97 + + using const_pointer = char const*;
+ 98 + +
+ 99 + + /// A reference to an element
+ 100 + + using reference = char&;
+ 101 + +
+ 102 + + /// A const reference to an element
+ 103 + + using const_reference = const char&;
+ 104 + +
+ 105 + + /// A random access iterator to an element
+ 106 + + using iterator = char*;
+ 107 + +
+ 108 + + /// A random access const iterator to an element
+ 109 + + using const_iterator = char const*;
+ 110 + +
+ 111 + + /// A reverse random access iterator to an element
+ 112 + + using reverse_iterator =
+ 113 + + std::reverse_iterator<iterator>;
+ 114 + +
+ 115 + + /// A reverse random access const iterator to an element
+ 116 + + using const_reverse_iterator =
+ 117 + + std::reverse_iterator<const_iterator>;
+ 118 + +
+ 119 + + /** A special index
+ 120 + +
+ 121 + + Represents the end of the string.
+ 122 + + */
+ 123 + + static constexpr std::size_t npos =
+ 124 + + string_view::npos;
+ 125 + +
+ 126 + + private:
+ 127 + + template<class T>
+ 128 + + using is_inputit = typename std::enable_if<
+ 129 + + std::is_convertible<typename
+ 130 + + std::iterator_traits<T>::reference,
+ 131 + + char>::value>::type;
+ 132 + +
+ 133 + + storage_ptr sp_; // must come first
+ 134 + + string_impl impl_;
+ 135 + +
+ 136 + + public:
+ 137 + + /** Destructor.
+ 138 + +
+ 139 + + Any dynamically allocated internal storage is freed.
+ 140 + +
+ 141 + + @par Complexity
+ 142 + + Constant.
+ 143 + +
+ 144 + + @par Exception Safety
+ 145 + + No-throw guarantee.
+ 146 + + */
+ 147 + +30626 ~string() noexcept
+ 148 + + {
+ 149 + +30626 impl_.destroy(sp_);
+ 150 + +30626 }
+ 151 + +
+ 152 + + //------------------------------------------------------
+ 153 + + //
+ 154 + + // Construction
+ 155 + + //
+ 156 + + //------------------------------------------------------
+ 157 + +
+ 158 + + /** Constructors.
+ 159 + +
+ 160 + + Construct a string.
+ 161 + +
+ 162 + + @li **(1)**, **(2)** the string is empty with a non-zero,
+ 163 + + unspecified capacity.
+ 164 + +
+ 165 + + @li **(3)** the string is filled with `count` copies of character `ch`.
+ 166 + +
+ 167 + + @li **(4)** the string will contain a copy of the characters of `s`.
+ 168 + +
+ 169 + + @li **(5)** the string will contain a copy of the characters of the
+ 170 + + null-terminated string `s`.
+ 171 + +
+ 172 + + @li **(6)** the string will contain a copy of the characters in the
+ 173 + + range `[s, s + count)`.
+ 174 + +
+ 175 + + @li **(7)** the string will contain a copy of the characters in the
+ 176 + + range `[first, last)`.
+ 177 + +
+ 178 + + @li **(8)**, **(9)** the string contains a copy of the characters of
+ 179 + + `other`.
+ 180 + +
+ 181 + + @li **(10)** the string acquires ownership of the contents of `other`.
+ 182 + +
+ 183 + + @li **(11)** equivalent to **(10)** if `*sp == *other.storage()`;
+ 184 + + otherwise equivalent to **(9)**.
+ 185 + +
+ 186 + + @li **(12)** the string is acquires ownership of the contents of
+ 187 + + `other` using pilfer semantics. This is more efficient than move
+ 188 + + construction, when it is known that the moved-from object
+ 189 + + will be immediately destroyed afterwards.
+ 190 + +
+ 191 + + With **(2)**--**(7)**, **(9)**, **(11)** the constructed string uses
+ 192 + + memory resource of `sp`. With **(8)**, **(10)**, and **(12)** it uses
+ 193 + + `other`'s memory resource. In either case the string will share the
+ 194 + + ownership of the memory resource. With **(1)** it uses the
+ 195 + + \<\<default_memory_resource, default memory resource\>\>.
+ 196 + +
+ 197 + + After **(10)** `other` behaves as if newly constructed with its
+ 198 + + current storage pointer.
+ 199 + +
+ 200 + + After **(12)** `other` is not in a usable state and may only be
+ 201 + + destroyed.
+ 202 + +
+ 203 + + @par Constraints
+ 204 + + `InputIt` satisfies {req_InputIterator}.
+ 205 + +
+ 206 + + @par Complexity
+ 207 + + @li **(1)**, **(2)**, **(10)**, **(12)** constant.
+ 208 + + @li **(3)** linear in `count`.
+ 209 + + @li **(4)** linear in `s.size()`.
+ 210 + + @li **(5)** linear in `std::strlen(s)`.
+ 211 + + @li **(6)** linear in `count`.
+ 212 + + @li **(7)** linear in `std::distance(first, last)`.
+ 213 + + @li **(8)**, **(9)** linear in `other.size()`.
+ 214 + + @li **(11)** constant if `*sp == *other.storage()`; otherwise linear in
+ 215 + + `other.size()`.
+ 216 + +
+ 217 + + @par Exception Safety
+ 218 + + @li **(1)**, **(2)**, **(10)**, **(12)** no-throw guarantee.
+ 219 + + @li **(3)**--**(6)**, **(8)**, **(9)**, **(11)** strong guarantee.
+ 220 + + @li **(7)** strong guarantee if `InputIt` satisfies
+ 221 + + {req_ForwardIterator}, basic guarantee otherwise.
+ 222 + +
+ 223 + + Calls to `memory_resource::allocate` may throw.
+ 224 + +
+ 225 + + @throw boost::system::system_error The constructed string's size would
+ 226 + + have exceeded @ref max_size().
+ 227 + +
+ 228 + + @see @ref pilfer,
+ 229 + + [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
+ 230 + +
+ 231 + + @{
+ 232 + + */
+ 233 + +2423 string() = default;
+ 234 + +
+ 235 + + /** Overload
+ 236 + +
+ 237 + + @param sp A pointer to the @ref boost::container::pmr::memory_resource
+ 238 + + to use. The container will acquire shared ownership of the memory
+ 239 + + resource.
+ 240 + + */
+ 241 + + explicit
+ 242 + +9103 string(storage_ptr sp)
+ 243 + +9103 : sp_(std::move(sp))
+ 244 + + {
+ 245 + +9103 }
+ 246 + +
+ 247 + + /** Overload
+ 248 + +
+ 249 + + @param count The size of the resulting string.
+ 250 + + @param ch The value to initialize characters of the string with.
+ 251 + + @param sp
+ 252 + + */
+ 253 + + BOOST_JSON_DECL
+ 254 + + explicit
+ 255 + + string(
+ 256 + + std::size_t count,
+ 257 + + char ch,
+ 258 + + storage_ptr sp = {});
+ 259 + +
+ 260 + + /** Overload
+ 261 + +
+ 262 + + @param s The string to copy from.
+ 263 + + @param sp
+ 264 + + */
+ 265 + + BOOST_JSON_DECL
+ 266 + + string(
+ 267 + + string_view s,
+ 268 + + storage_ptr sp = {});
+ 269 + +
+ 270 + + /// Overload
+ 271 + + BOOST_JSON_DECL
+ 272 + + string(
+ 273 + + char const* s,
+ 274 + + storage_ptr sp = {});
+ 275 + +
+ 276 + + /// Overload
+ 277 + + BOOST_JSON_DECL
+ 278 + + explicit
+ 279 + + string(
+ 280 + + char const* s,
+ 281 + + std::size_t count,
+ 282 + + storage_ptr sp = {});
+ 283 + +
+ 284 + + /** Overload
+ 285 + +
+ 286 + + @tparam InputIt The type of the iterators.
+ 287 + +
+ 288 + + @param first An input iterator pointing to the first character to
+ 289 + + insert, or pointing to the end of the range.
+ 290 + + @param last An input iterator pointing to the end of the range.
+ 291 + + @param sp
+ 292 + + */
+ 293 + + template<class InputIt
+ 294 + + #ifndef BOOST_JSON_DOCS
+ 295 + + ,class = is_inputit<InputIt>
+ 296 + + #endif
+ 297 + + >
+ 298 + + explicit
+ 299 + + string(
+ 300 + + InputIt first,
+ 301 + + InputIt last,
+ 302 + + storage_ptr sp = {});
+ 303 + +
+ 304 + + /** Overload
+ 305 + + @param other The source string.
+ 306 + + */
+ 307 + + BOOST_JSON_DECL
+ 308 + + string(string const& other);
+ 309 + +
+ 310 + + /// Overload
+ 311 + + BOOST_JSON_DECL
+ 312 + + explicit
+ 313 + + string(
+ 314 + + string const& other,
+ 315 + + storage_ptr sp);
+ 316 + +
+ 317 + + /// Overload
+ 318 + +415 string(string&& other) noexcept
+ 319 + +415 : sp_(other.sp_)
+ 320 + +415 , impl_(other.impl_)
+ 321 + + {
+ 322 + +415 ::new(&other.impl_) string_impl();
+ 323 + +415 }
+ 324 + +
+ 325 + + /// Overload
+ 326 + + BOOST_JSON_DECL
+ 327 + + explicit
+ 328 + + string(
+ 329 + + string&& other,
+ 330 + + storage_ptr sp);
+ 331 + +
+ 332 + + /// Overload
+ 333 + +5 string(pilfered<string> other) noexcept
+ 334 + +5 : sp_(std::move(other.get().sp_))
+ 335 + +5 , impl_(other.get().impl_)
+ 336 + + {
+ 337 + +5 ::new(&other.get().impl_) string_impl();
+ 338 + +5 }
+ 339 + + /// @}
+ 340 + +
+ 341 + + //------------------------------------------------------
+ 342 + + //
+ 343 + + // Assignment
+ 344 + + //
+ 345 + + //------------------------------------------------------
+ 346 + +
+ 347 + + /** Assignment operators.
+ 348 + +
+ 349 + + @li **(1)**, **(4)** the contents are replaced with an element-wise
+ 350 + + copy of `other`.
+ 351 + + @li **(2)** takes ownership of `other`'s element storage if
+ 352 + + `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
+ 353 + + @li **(3)** the contents are replaced with an element-wise copy of
+ 354 + + null-terminated string `s`.
+ 355 + +
+ 356 + + After **(2)**, the moved-from array behaves as if newly constructed
+ 357 + + with its current storage pointer.
+ 358 + +
+ 359 + + @par Complexity
+ 360 + + @li **(1)**, **(4)** linear in `other.size()`.
+ 361 + + @li **(2)** constant if `*storage() == *other.storage()`; otherwise
+ 362 + + linear in `other.size()`.
+ 363 + + @li **(3)** linear in `std::strlen(s)`.
+ 364 + +
+ 365 + + @par Exception Safety
+ 366 + + {sp} **(2)** provides strong guarantee if
+ 367 + + `*storage() != *other.storage()` and no-throw guarantee otherwise.
+ 368 + + Other overloads provide strong guarantee.
+ 369 + + Calls to `memory_resource::allocate` may throw.
+ 370 + +
+ 371 + + @param other The string to copy.
+ 372 + +
+ 373 + + @return `*this`
+ 374 + +
+ 375 + + @{
+ 376 + + */
+ 377 + + BOOST_JSON_DECL
+ 378 + + string&
+ 379 + + operator=(string const& other);
+ 380 + +
+ 381 + + BOOST_JSON_DECL
+ 382 + + string&
+ 383 + + operator=(string&& other);
+ 384 + +
+ 385 + + /** Overload
+ 386 + +
+ 387 + + @param s The null-terminated character string.
+ 388 + +
+ 389 + + @throw boost::system::system_error `std::strlen(s) >` @ref max_size().
+ 390 + + */
+ 391 + + BOOST_JSON_DECL
+ 392 + + string&
+ 393 + + operator=(char const* s);
+ 394 + +
+ 395 + + /** Overload
+ 396 + +
+ 397 + + @throw `boost::system::system_error` `other.size() >` @ref max_size().
+ 398 + + */
+ 399 + + BOOST_JSON_DECL
+ 400 + + string&
+ 401 + + operator=(string_view other);
+ 402 + + /// @}
+ 403 + +
+ 404 + + /** Assign characters to a string.
+ 405 + +
+ 406 + + @li **(1)** replaces the contents with `count` copies of character
+ 407 + + `ch`.
+ 408 + +
+ 409 + + @li **(2)** replaces the contents with copies of the characters in the
+ 410 + + range `[s, s + count)`. This range can contain null characters.
+ 411 + +
+ 412 + + @li **(3)** replaces the contents with those of the null terminated
+ 413 + + string `s`. The length of the string is determined by the first null
+ 414 + + character.
+ 415 + +
+ 416 + + @li **(4)** replaces the contents with copies of characters in the
+ 417 + + range `[first, last)`.
+ 418 + +
+ 419 + + @li **(5)** Replaces the contents with those of string view `s`. This
+ 420 + + view can contain null characters.
+ 421 + +
+ 422 + + @li **(6)** replaces the contents with a copy of the characters of
+ 423 + + `other`.
+ 424 + +
+ 425 + + @li **(7)** if `*storage() == *other.storage()` takes ownership of the
+ 426 + + element storage of `other`; otherwise equivalent to **(6)**.
+ 427 + +
+ 428 + + Self-assignment using **(7)** does nothing.
+ 429 + +
+ 430 + + After **(7)** `other` is left in valid but unspecified state.
+ 431 + +
+ 432 + + @par Constraints
+ 433 + + `InputIt` satisfies {req_InputIterator}.
+ 434 + +
+ 435 + + @par Complexity
+ 436 + + @li **(1)**, **(2)** linear in `count`.
+ 437 + + @li **(3)** linear in `std::strlen(s)`.
+ 438 + + @li **(4)** linear in `std::distance(first, last)`.
+ 439 + + @li **(5)** linear in `s.size()`.
+ 440 + + @li **(6)** linear in `other.size()`.
+ 441 + + @li **(7)** constant if `*storage() == *other.storage()`, otherwise
+ 442 + + linear in `other.size()`.
+ 443 + +
+ 444 + + @par Exception Safety
+ 445 + + {sp} **(7)** provides strong guarantee if
+ 446 + + `*storage() != *other.storage()` and no-throw guarantee otherwise.
+ 447 + + Other overloads provide strong guarantee. Calls to
+ 448 + + `memory_resource::allocate` may throw.
+ 449 + +
+ 450 + + @return `*this`.
+ 451 + +
+ 452 + + @param count The number of the characters to use.
+ 453 + +
+ 454 + + @param ch The character to fill the string with.
+ 455 + +
+ 456 + + @throw boost::system::system_error The size of the string after the
+ 457 + + operation would exceed @ref max_size().
+ 458 + +
+ 459 + + @{
+ 460 + + */
+ 461 + + BOOST_JSON_DECL
+ 462 + + string&
+ 463 + + assign(
+ 464 + + std::size_t count,
+ 465 + + char ch);
+ 466 + +
+ 467 + + /** Overload
+ 468 + + @param s A pointer to a character string used to copy from.
+ 469 + + @param count
+ 470 + + */
+ 471 + + BOOST_JSON_DECL
+ 472 + + string&
+ 473 + + assign(
+ 474 + + char const* s,
+ 475 + + std::size_t count);
+ 476 + +
+ 477 + + /** Overload
+ 478 + + @param s
+ 479 + + */
+ 480 + + BOOST_JSON_DECL
+ 481 + + string&
+ 482 + + assign(
+ 483 + + char const* s);
+ 484 + +
+ 485 + + /** Overload
+ 486 + +
+ 487 + + @tparam InputIt The type of the iterators.
+ 488 + +
+ 489 + + @param first An input iterator pointing to the first character to
+ 490 + + insert, or pointing to the end of the range.
+ 491 + + @param last An input iterator pointing to the end of the range.
+ 492 + + */
+ 493 + + template<class InputIt
+ 494 + + #ifndef BOOST_JSON_DOCS
+ 495 + + ,class = is_inputit<InputIt>
+ 496 + + #endif
+ 497 + + >
+ 498 + + string&
+ 499 + + assign(
+ 500 + + InputIt first,
+ 501 + + InputIt last);
+ 502 + +
+ 503 + + /** Overload
+ 504 + + @param s The string view to copy from.
+ 505 + + */
+ 506 + + string&
+ 507 + +17970 assign(string_view s)
+ 508 + + {
+ 509 + +17970 return assign(s.data(), s.size());
+ 510 + + }
+ 511 + +
+ 512 + + /** Overload
+ 513 + + @param other Another string.
+ 514 + + */
+ 515 + + BOOST_JSON_DECL
+ 516 + + string&
+ 517 + + assign(
+ 518 + + string const& other);
+ 519 + +
+ 520 + + /** Overload
+ 521 + + @param other
+ 522 + + */
+ 523 + + BOOST_JSON_DECL
+ 524 + + string&
+ 525 + + assign(string&& other);
+ 526 + + /// @}
+ 527 + +
+ 528 + + /** Return the associated memory resource.
+ 529 + +
+ 530 + + This function returns a smart pointer to the
+ 531 + + @ref boost::container::pmr::memory_resource used by the container.
+ 532 + +
+ 533 + + @par Complexity
+ 534 + + Constant.
+ 535 + +
+ 536 + + @par Exception Safety
+ 537 + + No-throw guarantee.
+ 538 + + */
+ 539 + + storage_ptr const&
+ 540 + +116 storage() const noexcept
+ 541 + + {
+ 542 + +116 return sp_;
+ 543 + + }
+ 544 + +
+ 545 + + /** Return the associated allocator.
+ 546 + +
+ 547 + + This function returns an instance of @ref allocator_type constructed
+ 548 + + from the associated @ref boost::container::pmr::memory_resource.
+ 549 + +
+ 550 + + @par Complexity
+ 551 + + Constant.
+ 552 + +
+ 553 + + @par Exception Safety
+ 554 + + No-throw guarantee.
+ 555 + + */
+ 556 + + allocator_type
+ 557 + +1 get_allocator() const noexcept
+ 558 + + {
+ 559 + +1 return sp_.get();
+ 560 + + }
+ 561 + +
+ 562 + + //------------------------------------------------------
+ 563 + + //
+ 564 + + // Element Access
+ 565 + + //
+ 566 + + //------------------------------------------------------
+ 567 + +
+ 568 + + /** Return a character with bounds checking.
+ 569 + +
+ 570 + + Returns @ref boost::system::result containing a reference to the
+ 571 + + character specified at location `pos`, if `pos` is within the range of
+ 572 + + the string. Otherwise the result contains an `error_code`.
+ 573 + +
+ 574 + + @par Exception Safety
+ 575 + + Strong guarantee.
+ 576 + +
+ 577 + + @param pos A zero-based index to access.
+ 578 + +
+ 579 + + @par Complexity
+ 580 + + Constant.
+ 581 + +
+ 582 + + @{
+ 583 + + */
+ 584 + + BOOST_JSON_DECL
+ 585 + + system::result<char&>
+ 586 + + try_at(std::size_t pos) noexcept;
+ 587 + +
+ 588 + + BOOST_JSON_DECL
+ 589 + + system::result<char const&>
+ 590 + + try_at(std::size_t pos) const noexcept;
+ 591 + + /// @}
+ 592 + +
+ 593 + + /** Return a character with bounds checking.
+ 594 + +
+ 595 + + Returns a reference to the character specified at location `pos`.
+ 596 + +
+ 597 + + @par Complexity
+ 598 + + Constant.
+ 599 + +
+ 600 + + @par Exception Safety
+ 601 + + Strong guarantee.
+ 602 + +
+ 603 + + @param pos A zero-based index to access.
+ 604 + + @param loc `source_location` to use in thrown exception; the source
+ 605 + + location of the call site by default.
+ 606 + +
+ 607 + + @throw boost::system::system_error `pos >=` @ref size().
+ 608 + +
+ 609 + + @{
+ 610 + + */
+ 611 + + inline
+ 612 + + char&
+ 613 + + at(
+ 614 + + std::size_t pos,
+ 615 + + source_location const& loc = BOOST_CURRENT_LOCATION);
+ 616 + +
+ 617 + + BOOST_JSON_DECL
+ 618 + + char const&
+ 619 + + at(
+ 620 + + std::size_t pos,
+ 621 + + source_location const& loc = BOOST_CURRENT_LOCATION) const;
+ 622 + + /// @}
+ 623 + +
+ 624 + + /** Return a character without bounds checking.
+ 625 + +
+ 626 + + Returns a reference to the character specified at location `pos`.
+ 627 + +
+ 628 + + @par Complexity
+ 629 + + Constant.
+ 630 + +
+ 631 + + @pre
+ 632 + + @code
+ 633 + + pos < size()
+ 634 + + @endcode
+ 635 + +
+ 636 + + @param pos A zero-based index to access.
+ 637 + +
+ 638 + + @{
+ 639 + + */
+ 640 + + char&
+ 641 + +18 operator[](std::size_t pos)
+ 642 + + {
+ 643 + +18 return impl_.data()[pos];
+ 644 + + }
+ 645 + +
+ 646 + + const char&
+ 647 + +2 operator[](std::size_t pos) const
+ 648 + + {
+ 649 + +2 return impl_.data()[pos];
+ 650 + + }
+ 651 + + /// @}
+ 652 + +
+ 653 + + /** Return the first character.
+ 654 + +
+ 655 + + Returns a reference to the first character.
+ 656 + +
+ 657 + + @pre
+ 658 + + @code
+ 659 + + ! empty()
+ 660 + + @endcode
+ 661 + +
+ 662 + + @par Complexity
+ 663 + + Constant.
+ 664 + +
+ 665 + + @par Exception Safety
+ 666 + + No-throw guarantee.
+ 667 + +
+ 668 + + @{
+ 669 + + */
+ 670 + + char&
+ 671 + +10 front()
+ 672 + + {
+ 673 + +10 return impl_.data()[0];
+ 674 + + }
+ 675 + +
+ 676 + + char const&
+ 677 + +6 front() const
+ 678 + + {
+ 679 + +6 return impl_.data()[0];
+ 680 + + }
+ 681 + + /// @}
+ 682 + +
+ 683 + + /** Return the last character.
+ 684 + +
+ 685 + + Returns a reference to the last character.
+ 686 + +
+ 687 + + @pre
+ 688 + + @code
+ 689 + + ! empty()
+ 690 + + @endcode
+ 691 + +
+ 692 + + @par Complexity
+ 693 + + Constant.
+ 694 + +
+ 695 + + @{
+ 696 + + */
+ 697 + + char&
+ 698 + +39 back()
+ 699 + + {
+ 700 + +39 return impl_.data()[impl_.size() - 1];
+ 701 + + }
+ 702 + +
+ 703 + + char const&
+ 704 + +6 back() const
+ 705 + + {
+ 706 + +6 return impl_.data()[impl_.size() - 1];
+ 707 + + }
+ 708 + + /// @}
+ 709 + +
+ 710 + + /** Return the underlying character array directly.
+ 711 + +
+ 712 + + Returns a pointer to the underlying array serving as storage. The value
+ 713 + + returned is such that the range `[data(), data() + size())` is always
+ 714 + + a valid range, even if the container is empty.
+ 715 + +
+ 716 + + @note The value returned from this function is never equal to
+ 717 + + `nullptr`.
+ 718 + +
+ 719 + + @par Complexity
+ 720 + + Constant.
+ 721 + +
+ 722 + + @par Exception Safety
+ 723 + + No-throw guarantee.
+ 724 + +
+ 725 + + @{
+ 726 + + */
+ 727 + + char*
+ 728 + +24004 data() noexcept
+ 729 + + {
+ 730 + +24004 return impl_.data();
+ 731 + + }
+ 732 + +
+ 733 + + char const*
+ 734 + +43947 data() const noexcept
+ 735 + + {
+ 736 + +43947 return impl_.data();
+ 737 + + }
+ 738 + + /// @@}
+ 739 + +
+ 740 + + /** Return the underlying character array directly.
+ 741 + +
+ 742 + + Returns a pointer to the underlying array serving as storage. The value
+ 743 + + returned is such that the range `[c_str(), c_str() + size())` is always
+ 744 + + a valid range, even if the container is empty.
+ 745 + +
+ 746 + + @note The value returned from this function is never equal to
+ 747 + + `nullptr`.
+ 748 + +
+ 749 + + @par Complexity
+ 750 + + Constant.
+ 751 + + */
+ 752 + + char const*
+ 753 + +4 c_str() const noexcept
+ 754 + + {
+ 755 + +4 return impl_.data();
+ 756 + + }
+ 757 + +
+ 758 + + /** Convert to a @ref string_view referring to the string.
+ 759 + +
+ 760 + + Returns a string view to the
+ 761 + + underlying character string. The size of the view
+ 762 + + does not include the null terminator.
+ 763 + +
+ 764 + + @par Complexity
+ 765 + +
+ 766 + + Constant.
+ 767 + + */
+ 768 + +57 operator string_view() const noexcept
+ 769 + + {
+ 770 + +57 return {data(), size()};
+ 771 + + }
+ 772 + +
+ 773 + + #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
+ 774 + + /** Convert to @ref std::string_view referring to the string.
+ 775 + +
+ 776 + + Returns a string view to the underlying character string. The size of
+ 777 + + the view does not include the null terminator.
+ 778 + +
+ 779 + + This overload is not defined when `BOOST_NO_CXX17_HDR_STRING_VIEW` is
+ 780 + + defined.
+ 781 + +
+ 782 + + @par Complexity
+ 783 + +
+ 784 + + Constant.
+ 785 + + */
+ 786 + + operator std::string_view() const noexcept
+ 787 + + {
+ 788 + + return {data(), size()};
+ 789 + + }
+ 790 + + #endif
+ 791 + +
+ 792 + + //------------------------------------------------------
+ 793 + + //
+ 794 + + // Iterators
+ 795 + + //
+ 796 + + //------------------------------------------------------
+ 797 + +
+ 798 + + /** Return an iterator to the beginning.
+ 799 + +
+ 800 + + If the container is empty, @ref end() is returned.
+ 801 + +
+ 802 + + @par Complexity
+ 803 + + Constant.
+ 804 + +
+ 805 + + @par Exception Safety
+ 806 + + No-throw guarantee.
+ 807 + +
+ 808 + + @{
+ 809 + + */
+ 810 + + iterator
+ 811 + +34 begin() noexcept
+ 812 + + {
+ 813 + +34 return impl_.data();
+ 814 + + }
+ 815 + +
+ 816 + + const_iterator
+ 817 + +8 begin() const noexcept
+ 818 + + {
+ 819 + +8 return impl_.data();
+ 820 + + }
+ 821 + + /// @}
+ 822 + +
+ 823 + + /** Return a const iterator to the first element.
+ 824 + +
+ 825 + + If the container is empty, @ref cend() is returned.
+ 826 + +
+ 827 + + @par Complexity
+ 828 + + Constant.
+ 829 + +
+ 830 + + @par Exception Safety
+ 831 + + No-throw guarantee.
+ 832 + + */
+ 833 + + const_iterator
+ 834 + +2 cbegin() const noexcept
+ 835 + + {
+ 836 + +2 return impl_.data();
+ 837 + + }
+ 838 + +
+ 839 + + /** Return an iterator to the end.
+ 840 + +
+ 841 + + The returned iterator only acts as a sentinel. Dereferencing it results
+ 842 + + in undefined behavior.
+ 843 + +
+ 844 + + @par Complexity
+ 845 + + Constant.
+ 846 + +
+ 847 + + @par Exception Safety
+ 848 + + No-throw guarantee.
+ 849 + +
+ 850 + + @{
+ 851 + + */
+ 852 + + iterator
+ 853 + +3 end() noexcept
+ 854 + + {
+ 855 + +3 return impl_.end();
+ 856 + + }
+ 857 + +
+ 858 + + const_iterator
+ 859 + +3 end() const noexcept
+ 860 + + {
+ 861 + +3 return impl_.end();
+ 862 + + }
+ 863 + + /// @}
+ 864 + +
+ 865 + + /** Return a const iterator past the last element.
+ 866 + +
+ 867 + + The returned iterator only acts as a sentinel. Dereferencing it results
+ 868 + + in undefined behavior.
+ 869 + +
+ 870 + + @par Complexity
+ 871 + + Constant.
+ 872 + +
+ 873 + + @par Exception Safety
+ 874 + + No-throw guarantee.
+ 875 + + */
+ 876 + + const_iterator
+ 877 + +2 cend() const noexcept
+ 878 + + {
+ 879 + +2 return impl_.end();
+ 880 + + }
+ 881 + +
+ 882 + + /** Return a reverse iterator to the first character of the reversed container.
+ 883 + +
+ 884 + + Returns the pointed-to character that corresponds to the last character
+ 885 + + of the non-reversed container. If the container is empty, @ref rend()
+ 886 + + is returned.
+ 887 + +
+ 888 + + @par Complexity
+ 889 + + Constant.
+ 890 + +
+ 891 + + @{
+ 892 + + */
+ 893 + + reverse_iterator
+ 894 + +3 rbegin() noexcept
+ 895 + + {
+ 896 + +3 return reverse_iterator(impl_.end());
+ 897 + + }
+ 898 + +
+ 899 + + const_reverse_iterator
+ 900 + +3 rbegin() const noexcept
+ 901 + + {
+ 902 + +3 return const_reverse_iterator(impl_.end());
+ 903 + + }
+ 904 + + /// @}
+ 905 + +
+ 906 + + /** Return a const reverse iterator to the first element of the reversed container.
+ 907 + +
+ 908 + + Returns the pointed-to character that corresponds to the last character
+ 909 + + of the non-reversed container. If the container is empty, @ref crend()
+ 910 + + is returned.
+ 911 + +
+ 912 + + @par Complexity
+ 913 + + Constant.
+ 914 + +
+ 915 + + @par Exception Safety
+ 916 + + No-throw guarantee.
+ 917 + + */
+ 918 + + const_reverse_iterator
+ 919 + +2 crbegin() const noexcept
+ 920 + + {
+ 921 + +2 return const_reverse_iterator(impl_.end());
+ 922 + + }
+ 923 + +
+ 924 + + /** Return a reverse iterator to the character following the last character of the reversed container.
+ 925 + +
+ 926 + + The pointed-to element corresponds to the element preceding the first
+ 927 + + element of the non-reversed container. The returned iterator only acts
+ 928 + + as a sentinel. Dereferencing it results in undefined behavior.
+ 929 + +
+ 930 + + @par Complexity
+ 931 + + Constant.
+ 932 + +
+ 933 + + @par Exception Safety
+ 934 + + No-throw guarantee.
+ 935 + +
+ 936 + + @{
+ 937 + + */
+ 938 + + reverse_iterator
+ 939 + +3 rend() noexcept
+ 940 + + {
+ 941 + +3 return reverse_iterator(begin());
+ 942 + + }
+ 943 + +
+ 944 + + const_reverse_iterator
+ 945 + +3 rend() const noexcept
+ 946 + + {
+ 947 + +3 return const_reverse_iterator(begin());
+ 948 + + }
+ 949 + + /// @}
+ 950 + +
+ 951 + + /** Return a const reverse iterator to the character following the last character of the reversed container.
+ 952 + +
+ 953 + + The pointed-to character corresponds to the character preceding the
+ 954 + + first character of the non-reversed container. The returned iterator
+ 955 + + only acts as a sentinel. Dereferencing it results in undefined
+ 956 + + behavior.
+ 957 + +
+ 958 + + @par Complexity
+ 959 + + Constant.
+ 960 + +
+ 961 + + @par Exception Safety
+ 962 + + No-throw guarantee.
+ 963 + + */
+ 964 + + const_reverse_iterator
+ 965 + +2 crend() const noexcept
+ 966 + + {
+ 967 + +2 return const_reverse_iterator(begin());
+ 968 + + }
+ 969 + +
+ 970 + + //------------------------------------------------------
+ 971 + + //
+ 972 + + // Capacity
+ 973 + + //
+ 974 + + //------------------------------------------------------
+ 975 + +
+ 976 + + /** Check if the string has no characters.
+ 977 + +
+ 978 + + Returns `true` if there are no characters in the string, i.e. @ref
+ 979 + + size() returns 0.
+ 980 + +
+ 981 + + @par Complexity
+ 982 + + Constant.
+ 983 + +
+ 984 + + @par Exception Safety
+ 985 + + No-throw guarantee.
+ 986 + + */
+ 987 + + bool
+ 988 + +69 empty() const noexcept
+ 989 + + {
+ 990 + +69 return impl_.size() == 0;
+ 991 + + }
+ 992 + +
+ 993 + + /** Return the number of characters in the string.
+ 994 + +
+ 995 + + The value returned does not include the null terminator, which is
+ 996 + + always present.
+ 997 + +
+ 998 + + @par Complexity
+ 999 + + Constant.
+ 1000 + + */
+ 1001 + + std::size_t
+ 1002 + +47765 size() const noexcept
+ 1003 + + {
+ 1004 + +47765 return impl_.size();
+ 1005 + + }
+ 1006 + +
+ 1007 + + /** Return the maximum number of characters any string can hold.
+ 1008 + +
+ 1009 + + The maximum is an implementation-defined number. This value is
+ 1010 + + a theoretical limit; at runtime, the actual maximum size may be less
+ 1011 + + due to resource limits.
+ 1012 + +
+ 1013 + + @par Complexity
+ 1014 + + Constant.
+ 1015 + + */
+ 1016 + + static
+ 1017 + + constexpr
+ 1018 + + std::size_t
+ 1019 + +7895 max_size() noexcept
+ 1020 + + {
+ 1021 + +7895 return string_impl::max_size();
+ 1022 + + }
+ 1023 + +
+ 1024 + + /** Return the number of characters that can be held in currently allocated memory.
+ 1025 + +
+ 1026 + + Returns the number of characters that the container has currently
+ 1027 + + allocated space for. This number is never smaller than the value
+ 1028 + + returned by @ref size().
+ 1029 + +
+ 1030 + + @par Complexity
+ 1031 + + Constant.
+ 1032 + +
+ 1033 + + @par Exception Safety
+ 1034 + + No-throw guarantee.
+ 1035 + + */
+ 1036 + + std::size_t
+ 1037 + +11658 capacity() const noexcept
+ 1038 + + {
+ 1039 + +11658 return impl_.capacity();
+ 1040 + + }
+ 1041 + +
+ 1042 + + /** Increase the capacity to at least a certain amount.
+ 1043 + +
+ 1044 + + This increases the capacity of the array to a value that is greater
+ 1045 + + than or equal to `new_capacity`. If `new_capacity > `@ref capacity(),
+ 1046 + + new memory is allocated. Otherwise, the call has no effect. The number
+ 1047 + + of elements and therefore the @ref size() of the container is not
+ 1048 + + changed.
+ 1049 + +
+ 1050 + + If new memory is allocated, all iterators including any past-the-end
+ 1051 + + iterators, and all references to the elements are invalidated.
+ 1052 + + Otherwise, no iterators or references are invalidated.
+ 1053 + +
+ 1054 + + @par Complexity
+ 1055 + + At most, linear in @ref size().
+ 1056 + +
+ 1057 + + @par Exception Safety
+ 1058 + + Strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 1059 + +
+ 1060 + + @param new_capacity The new capacity of the array.
+ 1061 + +
+ 1062 + + @throw boost::system::system_error `new_capacity > `@ref max_size().
+ 1063 + + */
+ 1064 + + void
+ 1065 + +11348 reserve(std::size_t new_capacity)
+ 1066 + + {
+ 1067 + +11348 if(new_capacity <= capacity())
+ 1068 + +1662 return;
+ 1069 + +9686 reserve_impl(new_capacity);
+ 1070 + + }
+ 1071 + +
+ 1072 + + /** Request the removal of unused capacity.
+ 1073 + +
+ 1074 + + This performs a non-binding request to reduce @ref capacity() to
+ 1075 + + @ref size(). The request may or may not be fulfilled.
+ 1076 + +
+ 1077 + + @note If reallocation occurs, all iterators including any past-the-end
+ 1078 + + iterators, and all references to characters are invalidated. Otherwise,
+ 1079 + + no iterators or references are invalidated.
+ 1080 + +
+ 1081 + + @par Complexity
+ 1082 + + At most, linear in @ref size().
+ 1083 + + */
+ 1084 + + BOOST_JSON_DECL
+ 1085 + + void
+ 1086 + + shrink_to_fit();
+ 1087 + +
+ 1088 + + //------------------------------------------------------
+ 1089 + + //
+ 1090 + + // Operations
+ 1091 + + //
+ 1092 + + //------------------------------------------------------
+ 1093 + +
+ 1094 + + /** Clear the contents.
+ 1095 + +
+ 1096 + + Erases all characters from the string. After this call, @ref size()
+ 1097 + + returns zero but @ref capacity() is unchanged. All references,
+ 1098 + + pointers, or iterators referring to contained elements are invalidated.
+ 1099 + + Any past-the-end iterators are also invalidated.
+ 1100 + +
+ 1101 + + @par Complexity
+ 1102 + + Linear in @ref size().
+ 1103 + +
+ 1104 + + @par Exception Safety
+ 1105 + + No-throw guarantee.
+ 1106 + + */
+ 1107 + + BOOST_JSON_DECL
+ 1108 + + void
+ 1109 + + clear() noexcept;
+ 1110 + +
+ 1111 + + /** Insert characters at the specified index.
+ 1112 + +
+ 1113 + + @li **(1)** inserts `sv`.
+ 1114 + + @li **(2)** inserts `count` copies of `ch`.
+ 1115 + + @li **(3)** inserts the character `ch`.
+ 1116 + + @li **(4)** inserts characters from the range `[first, last)`.
+ 1117 + +
+ 1118 + + The first character is inserted at the index `pos`. All references,
+ 1119 + + pointers, or iterators referring to contained elements are invalidated.
+ 1120 + + Any past-the-end iterators are also invalidated.
+ 1121 + +
+ 1122 + + @par Constraints
+ 1123 + + `InputIt` satisfies {req_InputIterator}.
+ 1124 + +
+ 1125 + + @pre
+ 1126 + + `[first, last)` is a valid range.
+ 1127 + +
+ 1128 + + @par Exception Safety
+ 1129 + + @li **(1)**--*(3)* strong guarantee.
+ 1130 + + @li **(4)** strong guarantee if `InputIt` satisfies
+ 1131 + + {req_ForwardIterator}, basic guarantee otherwise.
+ 1132 + +
+ 1133 + + @return `*this`
+ 1134 + +
+ 1135 + + @param pos The index to insert at.
+ 1136 + + @param sv The `string_view` to insert.
+ 1137 + +
+ 1138 + + @throw boost::system::system_error The size of the string would exceed
+ 1139 + + @ref max_size().
+ 1140 + +
+ 1141 + + @throw boost::system::system_error `pos > `@ref size().
+ 1142 + +
+ 1143 + + @{
+ 1144 + + */
+ 1145 + + BOOST_JSON_DECL
+ 1146 + + string&
+ 1147 + + insert(
+ 1148 + + std::size_t pos,
+ 1149 + + string_view sv);
+ 1150 + +
+ 1151 + + /** Overload
+ 1152 + + @param count The number of characters to insert.
+ 1153 + + @param ch The character to insert.
+ 1154 + + @param pos
+ 1155 + + */
+ 1156 + + BOOST_JSON_DECL
+ 1157 + + string&
+ 1158 + + insert(
+ 1159 + + std::size_t pos,
+ 1160 + + std::size_t count,
+ 1161 + + char ch);
+ 1162 + +
+ 1163 + + /** Overload
+ 1164 + + @param pos
+ 1165 + + @param ch
+ 1166 + + */
+ 1167 + + string&
+ 1168 + +3 insert(
+ 1169 + + size_type pos,
+ 1170 + + char ch)
+ 1171 + + {
+ 1172 + +3 return insert(pos, 1, ch);
+ 1173 + + }
+ 1174 + +
+ 1175 + + /** Overload
+ 1176 + +
+ 1177 + + @tparam InputIt The type of the iterators.
+ 1178 + +
+ 1179 + + @param first The beginning of the character range.
+ 1180 + + @param last The end of the character range.
+ 1181 + + @param pos
+ 1182 + + */
+ 1183 + + template<class InputIt
+ 1184 + + #ifndef BOOST_JSON_DOCS
+ 1185 + + ,class = is_inputit<InputIt>
+ 1186 + + #endif
+ 1187 + + >
+ 1188 + + string&
+ 1189 + + insert(
+ 1190 + + size_type pos,
+ 1191 + + InputIt first,
+ 1192 + + InputIt last);
+ 1193 + + /// @}
+ 1194 + +
+ 1195 + + /** Remove characters from the string.
+ 1196 + +
+ 1197 + + @li **(1)** removes at most `count` but not more than `size() - pos`
+ 1198 + + characters starting at `index`.
+ 1199 + + @li **(2)** removes the character at `pos`.
+ 1200 + + @li **(3)** removes characters in the range `[first, last)`.
+ 1201 + +
+ 1202 + + All references, pointers, or iterators referring to contained elements
+ 1203 + + are invalidated. Any past-the-end iterators are also invalidated.
+ 1204 + +
+ 1205 + + @pre
+ 1206 + + `pos`, `first`, and `last` are iterators into this string. `first` and
+ 1207 + + `last` form a valid range.
+ 1208 + +
+ 1209 + + @par Complexity
+ 1210 + + @li **(1)** linear in `count`.
+ 1211 + + @li **(2)** constant.
+ 1212 + + @li **(3)** linear in `std::distance(first, last)`.
+ 1213 + +
+ 1214 + + @par Exception Safety
+ 1215 + + Strong guarantee.
+ 1216 + +
+ 1217 + + @return
+ 1218 + + @li **(1)** `*this`.
+ 1219 + +
+ 1220 + + @li **(2)** An iterator referring to the character immediately
+ 1221 + + following the removed character, or @ref end() if one does not exist.
+ 1222 + +
+ 1223 + + @li **(3)** An iterator referring to the character `last` previously
+ 1224 + + referred to, or @ref end() if one does not exist.
+ 1225 + +
+ 1226 + + @param index The index of the first character to remove.
+ 1227 + +
+ 1228 + + @param count The number of characters to remove. By default remove
+ 1229 + + until the end of the string.
+ 1230 + +
+ 1231 + + @throw boost::system::system_error `pos >` @ref size().
+ 1232 + +
+ 1233 + + @{
+ 1234 + + */
+ 1235 + + BOOST_JSON_DECL
+ 1236 + + string&
+ 1237 + + erase(
+ 1238 + + std::size_t index = 0,
+ 1239 + + std::size_t count = npos);
+ 1240 + +
+ 1241 + + /** Overload
+ 1242 + + @param pos An iterator referring to the character to erase.
+ 1243 + + */
+ 1244 + + BOOST_JSON_DECL
+ 1245 + + iterator
+ 1246 + + erase(const_iterator pos);
+ 1247 + +
+ 1248 + + /** Overload
+ 1249 + + @param first An iterator representing the first character to erase.
+ 1250 + + @param last An iterator one past the last character to erase.
+ 1251 + + */
+ 1252 + + BOOST_JSON_DECL
+ 1253 + + iterator
+ 1254 + + erase(
+ 1255 + + const_iterator first,
+ 1256 + + const_iterator last);
+ 1257 + + /// @}
+ 1258 + +
+ 1259 + + //------------------------------------------------------
+ 1260 + +
+ 1261 + + /** Append a character.
+ 1262 + +
+ 1263 + + Appends a character to the end of the string.
+ 1264 + +
+ 1265 + + @par Exception Safety
+ 1266 + + Strong guarantee.
+ 1267 + +
+ 1268 + + @param ch The character to append.
+ 1269 + +
+ 1270 + + @throw boost::system::system_error @ref size() `+ 1 > `@ref max_size().
+ 1271 + + */
+ 1272 + + BOOST_JSON_DECL
+ 1273 + + void
+ 1274 + + push_back(char ch);
+ 1275 + +
+ 1276 + + /** Remove the last character.
+ 1277 + +
+ 1278 + + Removes a character from the end of the string.
+ 1279 + +
+ 1280 + + @pre
+ 1281 + + @code
+ 1282 + + ! empty()
+ 1283 + + @endcode
+ 1284 + + */
+ 1285 + + BOOST_JSON_DECL
+ 1286 + + void
+ 1287 + + pop_back();
+ 1288 + +
+ 1289 + + //------------------------------------------------------
+ 1290 + +
+ 1291 + + /** Append characters to the string.
+ 1292 + +
+ 1293 + + @li **(1)** appends `count` copies of `ch`.
+ 1294 + +
+ 1295 + + @li **(2)** appends copies of characters of `sv`, preserving order.
+ 1296 + +
+ 1297 + + @li **(3)** appends characters from the range `[first, last)`,
+ 1298 + + preserving order.
+ 1299 + +
+ 1300 + + @pre
+ 1301 + + `[first, last)` shall be a valid range.
+ 1302 + +
+ 1303 + + @par Constraints
+ 1304 + + `InputIt` satisfies {req_InputIterator}.
+ 1305 + +
+ 1306 + + @par Exception Safety
+ 1307 + + Strong guarantee.
+ 1308 + +
+ 1309 + + @return `*this`.
+ 1310 + +
+ 1311 + + @param count The number of characters to append.
+ 1312 + + @param ch The character to append.
+ 1313 + +
+ 1314 + + @throw boost::system::system_error The size of the string after the
+ 1315 + + operation would exceed @ref max_size().
+ 1316 + +
+ 1317 + + @{
+ 1318 + + */
+ 1319 + + BOOST_JSON_DECL
+ 1320 + + string&
+ 1321 + + append(
+ 1322 + + std::size_t count,
+ 1323 + + char ch);
+ 1324 + +
+ 1325 + + /** Overload
+ 1326 + + @param sv The `string_view` to append.
+ 1327 + + */
+ 1328 + + BOOST_JSON_DECL
+ 1329 + + string&
+ 1330 + + append(string_view sv);
+ 1331 + +
+ 1332 + + /** Overload
+ 1333 + +
+ 1334 + + @tparam InputIt The type of the iterators.
+ 1335 + +
+ 1336 + + @param first An iterator representing the first character to append.
+ 1337 + + @param last An iterator one past the last character to append.
+ 1338 + + */
+ 1339 + + template<class InputIt
+ 1340 + + #ifndef BOOST_JSON_DOCS
+ 1341 + + ,class = is_inputit<InputIt>
+ 1342 + + #endif
+ 1343 + + >
+ 1344 + + string&
+ 1345 + + append(InputIt first, InputIt last);
+ 1346 + + /// @}
+ 1347 + +
+ 1348 + + /** Append characters to the string.
+ 1349 + +
+ 1350 + + @li **(1)** appends `[sv.begin(), sv.end())`.
+ 1351 + + @li **(2)** appends `ch`.
+ 1352 + +
+ 1353 + + @par Exception Safety
+ 1354 + + Strong guarantee.
+ 1355 + +
+ 1356 + + @return `*this`
+ 1357 + +
+ 1358 + + @param sv The `string_view` to append.
+ 1359 + +
+ 1360 + + @throw boost::system::system_error The size of the string after the
+ 1361 + + operation would exceed @ref max_size().
+ 1362 + +
+ 1363 + + @{
+ 1364 + + */
+ 1365 + + string&
+ 1366 + +11 operator+=(string_view sv)
+ 1367 + + {
+ 1368 + +11 return append(sv);
+ 1369 + + }
+ 1370 + +
+ 1371 + + /** Overload
+ 1372 + + @param ch The character to append.
+ 1373 + + */
+ 1374 + + string&
+ 1375 + +44 operator+=(char ch)
+ 1376 + + {
+ 1377 + +44 push_back(ch);
+ 1378 + +43 return *this;
+ 1379 + + }
+ 1380 + + /// @}
+ 1381 + +
+ 1382 + + //------------------------------------------------------
+ 1383 + +
+ 1384 + + /** Compare a string with the string.
+ 1385 + +
+ 1386 + + Let `comp` be `std::char_traits<char>::compare(data(), sv.data(),
+ 1387 + + std::min(size(), sv.size())`. If `comp != 0`, then the result is
+ 1388 + + `comp`. Otherwise, the result is `0` if `size() == sv.size()`, `-1` if
+ 1389 + + `size() < sv.size()`, and `1` otherwise.
+ 1390 + +
+ 1391 + + @par Complexity
+ 1392 + + Linear.
+ 1393 + +
+ 1394 + + @return The result of lexicographically comparing the characters of
+ 1395 + + `sv` and the string.
+ 1396 + +
+ 1397 + + @param sv The `string_view` to compare.
+ 1398 + + */
+ 1399 + + int
+ 1400 + +13 compare(string_view sv) const noexcept
+ 1401 + + {
+ 1402 + +13 return subview().compare(sv);
+ 1403 + + }
+ 1404 + +
+ 1405 + + //------------------------------------------------------
+ 1406 + +
+ 1407 + + /** Return whether the string begins with another string.
+ 1408 + +
+ 1409 + + @li **(1)** checks if the string begins with `s`.
+ 1410 + + @li **(2)** checks if the string begins with `ch`.
+ 1411 + +
+ 1412 + + @par Complexity
+ 1413 + + @li **(1)** linear in `s.size()`.
+ 1414 + + @li **(2)** constant.
+ 1415 + +
+ 1416 + + @param s The string to check for.
+ 1417 + +
+ 1418 + + @{
+ 1419 + + */
+ 1420 + + bool
+ 1421 + +8 starts_with(string_view s) const noexcept
+ 1422 + + {
+ 1423 + +8 return subview(0, s.size()) == s;
+ 1424 + + }
+ 1425 + +
+ 1426 + + /** Overload
+ 1427 + +
+ 1428 + + @param ch The character to check for.
+ 1429 + + */
+ 1430 + + bool
+ 1431 + +4 starts_with(char ch) const noexcept
+ 1432 + + {
+ 1433 + +4 return ! empty() && front() == ch;
+ 1434 + + }
+ 1435 + + /// @}
+ 1436 + +
+ 1437 + + /** Check if the string ends with given suffix.
+ 1438 + +
+ 1439 + + @li **(1)** returns `true` if the string ends with `s`.
+ 1440 + + @li **(2)** returns `true` if the string ends with the character `ch`.
+ 1441 + +
+ 1442 + + @par Complexity
+ 1443 + + @li **(1)** linear in `s`.
+ 1444 + + @li **(2)** constant.
+ 1445 + +
+ 1446 + + @par Exception Safety
+ 1447 + + No-throw guarantee.
+ 1448 + +
+ 1449 + + @param s The string to check for.
+ 1450 + +
+ 1451 + + @{
+ 1452 + + */
+ 1453 + + bool
+ 1454 + +8 ends_with(string_view s) const noexcept
+ 1455 + + {
+ 1456 + +16 return size() >= s.size() &&
+ 1457 + +16 subview(size() - s.size()) == s;
+ 1458 + + }
+ 1459 + +
+ 1460 + + /** Overload
+ 1461 + + @param ch The character to check for.
+ 1462 + + */
+ 1463 + + bool
+ 1464 + +4 ends_with(char ch) const noexcept
+ 1465 + + {
+ 1466 + +4 return ! empty() && back() == ch;
+ 1467 + + }
+ 1468 + + /// @}
+ 1469 + +
+ 1470 + + /** Replace a substring with another string.
+ 1471 + +
+ 1472 + + @li **(1)** replaces `std::min(count, size() - pos)` characters
+ 1473 + + starting at index `pos` with those of `sv`.
+ 1474 + + @li **(2)** replaces the characters in the range `[first, last)` with
+ 1475 + + those of `sv`.
+ 1476 + + @li **(3)** replaces the characters in the range `[first, last)` with
+ 1477 + + those of `[first2, last2)`.
+ 1478 + + @li **(4)** replaces `std::min(count, size() - pos)` characters
+ 1479 + + starting at index `pos` with `count2` copies of `ch`.
+ 1480 + + @li **(5)** replaces the characters in the range `[first, last)` with
+ 1481 + + `count2` copies of `ch`.
+ 1482 + +
+ 1483 + + All references, pointers, or iterators referring to contained elements
+ 1484 + + are invalidated. Any past-the-end iterators are also invalidated.
+ 1485 + +
+ 1486 + + @pre
+ 1487 + + `[first, last)` is a valid range. `[first2, last2)` is a valid range.
+ 1488 + +
+ 1489 + + @par Constraints
+ 1490 + + `InputIt` satisfies {req_InputIterator}.
+ 1491 + +
+ 1492 + + @par Exception Safety
+ 1493 + + Strong guarantee.
+ 1494 + +
+ 1495 + + @return `*this`
+ 1496 + +
+ 1497 + + @param pos The index to replace at.
+ 1498 + +
+ 1499 + + @param count The number of characters to replace.
+ 1500 + +
+ 1501 + + @param sv The `string_view` to replace with.
+ 1502 + +
+ 1503 + + @throw boost::system::system_error The resulting string's size would
+ 1504 + + have exceeded @ref max_size().
+ 1505 + +
+ 1506 + + @{
+ 1507 + + */
+ 1508 + + BOOST_JSON_DECL
+ 1509 + + string&
+ 1510 + + replace(
+ 1511 + + std::size_t pos,
+ 1512 + + std::size_t count,
+ 1513 + + string_view sv);
+ 1514 + +
+ 1515 + + /** Overload
+ 1516 + +
+ 1517 + + @param first An iterator referring to the first character to replace.
+ 1518 + + @param last An iterator one past the end of the last character to
+ 1519 + + replace.
+ 1520 + + @param sv
+ 1521 + + */
+ 1522 + + string&
+ 1523 + +6 replace(
+ 1524 + + const_iterator first,
+ 1525 + + const_iterator last,
+ 1526 + + string_view sv)
+ 1527 + + {
+ 1528 + +6 return replace(first - begin(), last - first, sv);
+ 1529 + + }
+ 1530 + +
+ 1531 + + /** Overload
+ 1532 + +
+ 1533 + + @tparam InputIt The type of the iterators.
+ 1534 + +
+ 1535 + + @param first2 An iterator referring to the first character to replace
+ 1536 + + with.
+ 1537 + + @param last2 An iterator one past the end of the last character to
+ 1538 + + replace with.
+ 1539 + + @param first
+ 1540 + + @param last
+ 1541 + + */
+ 1542 + + template<class InputIt
+ 1543 + + #ifndef BOOST_JSON_DOCS
+ 1544 + + ,class = is_inputit<InputIt>
+ 1545 + + #endif
+ 1546 + + >
+ 1547 + + string&
+ 1548 + + replace(
+ 1549 + + const_iterator first,
+ 1550 + + const_iterator last,
+ 1551 + + InputIt first2,
+ 1552 + + InputIt last2);
+ 1553 + +
+ 1554 + + /** Overload
+ 1555 + +
+ 1556 + + @param count2 The number of characters to replace with.
+ 1557 + + @param ch The character to replace with.
+ 1558 + + @param pos
+ 1559 + + @param count
+ 1560 + + */
+ 1561 + + BOOST_JSON_DECL
+ 1562 + + string&
+ 1563 + + replace(
+ 1564 + + std::size_t pos,
+ 1565 + + std::size_t count,
+ 1566 + + std::size_t count2,
+ 1567 + + char ch);
+ 1568 + +
+ 1569 + + /** Overload
+ 1570 + +
+ 1571 + + @param first
+ 1572 + + @param last
+ 1573 + + @param count2
+ 1574 + + @param ch
+ 1575 + + */
+ 1576 + + string&
+ 1577 + +1 replace(
+ 1578 + + const_iterator first,
+ 1579 + + const_iterator last,
+ 1580 + + std::size_t count2,
+ 1581 + + char ch)
+ 1582 + + {
+ 1583 + +1 return replace(first - begin(), last - first, count2, ch);
+ 1584 + + }
+ 1585 + + /// @}
+ 1586 + +
+ 1587 + + //------------------------------------------------------
+ 1588 + +
+ 1589 + + /** Return a view.
+ 1590 + +
+ 1591 + + @li **(1)** equivalent to `subview().substr(pos, count)`.
+ 1592 + + @li **(2)** equivalent to `string_view(data(), size())`.
+ 1593 + +
+ 1594 + + @par Exception Safety
+ 1595 + + Strong guarantee.
+ 1596 + +
+ 1597 + + @param pos The index of the first character of the substring.
+ 1598 + + @param count The length of the substring.
+ 1599 + +
+ 1600 + + @throw boost::system::system_error `pos > ` @ref size().
+ 1601 + + */
+ 1602 + + string_view
+ 1603 + +41 subview(
+ 1604 + + std::size_t pos,
+ 1605 + + std::size_t count = npos) const
+ 1606 + + {
+ 1607 + +41 return subview().substr(pos, count);
+ 1608 + + }
+ 1609 + +
+ 1610 + + /// Overload
+ 1611 + + string_view
+ 1612 + +28955 subview() const noexcept
+ 1613 + + {
+ 1614 + +28955 return string_view( data(), size() );
+ 1615 + + }
+ 1616 + +
+ 1617 + + //------------------------------------------------------
+ 1618 + +
+ 1619 + + /** Copy a substring to another string.
+ 1620 + +
+ 1621 + + Copies `std::min(count, size() - pos)` characters starting at index
+ 1622 + + `pos` to the string pointed to by `dest`.
+ 1623 + +
+ 1624 + + @attention This function doesn't put the null terminator after the
+ 1625 + + copied characters.
+ 1626 + +
+ 1627 + + @return The number of characters copied.
+ 1628 + +
+ 1629 + + @param count The number of characters to copy.
+ 1630 + +
+ 1631 + + @param dest The string to copy to.
+ 1632 + +
+ 1633 + + @param pos The index to begin copying from.
+ 1634 + +
+ 1635 + + @throw boost::system::system_error `pos >` @ref max_size().
+ 1636 + + */
+ 1637 + + std::size_t
+ 1638 + +2 copy(
+ 1639 + + char* dest,
+ 1640 + + std::size_t count,
+ 1641 + + std::size_t pos = 0) const
+ 1642 + + {
+ 1643 + +2 return subview().copy(dest, count, pos);
+ 1644 + + }
+ 1645 + +
+ 1646 + + //------------------------------------------------------
+ 1647 + +
+ 1648 + + /** Change the size of the string.
+ 1649 + +
+ 1650 + + Resizes the string to contain `count` characters. If
+ 1651 + + `count > `@ref size(), **(2)** appends copies of `ch` and **(1)**
+ 1652 + + appends ``'\0'``. Otherwise, `size()` is reduced to `count`.
+ 1653 + +
+ 1654 + + @param count The size to resize the string to.
+ 1655 + +
+ 1656 + + @throw boost::system::system_error `count > `@ref max_size().
+ 1657 + +
+ 1658 + + @{
+ 1659 + + */
+ 1660 + + void
+ 1661 + +57 resize(std::size_t count)
+ 1662 + + {
+ 1663 + +57 resize(count, 0);
+ 1664 + +54 }
+ 1665 + +
+ 1666 + + /** Overload
+ 1667 + +
+ 1668 + + @param count
+ 1669 + + @param ch The characters to append if the size increases.
+ 1670 + + */
+ 1671 + + BOOST_JSON_DECL
+ 1672 + + void
+ 1673 + + resize(std::size_t count, char ch);
+ 1674 + + /// @}
+ 1675 + +
+ 1676 + + /** Increase size without changing capacity.
+ 1677 + +
+ 1678 + + This increases the size of the string by `n` characters, adjusting the
+ 1679 + + position of the terminating null character for the new size. The new
+ 1680 + + characters remain uninitialized. This function may be used to append
+ 1681 + + characters directly into the storage between @ref end() and @ref data()
+ 1682 + + ` + ` @ref capacity().
+ 1683 + +
+ 1684 + + @pre
+ 1685 + + @code
+ 1686 + + count <= capacity() - size()
+ 1687 + + @endcode
+ 1688 + +
+ 1689 + + @param n The amount to increase the size by.
+ 1690 + + */
+ 1691 + + void
+ 1692 + +15054 grow(std::size_t n) noexcept
+ 1693 + + {
+ 1694 + +15054 BOOST_ASSERT(
+ 1695 + + n <= impl_.capacity() - impl_.size());
+ 1696 + +15054 impl_.term(impl_.size() + n);
+ 1697 + +15054 }
+ 1698 + +
+ 1699 + + /** Swap the contents.
+ 1700 + +
+ 1701 + + Exchanges the contents of this string with another string. Ownership of
+ 1702 + + the respective @ref boost::container::pmr::memory_resource objects is
+ 1703 + + not transferred.
+ 1704 + +
+ 1705 + + @li If `&other == this`, do nothing. Otherwise,
+ 1706 + + @li if `*other.storage() == *this->storage()`, ownership of the
+ 1707 + + underlying memory is swapped in constant time, with no possibility
+ 1708 + + of exceptions. All iterators and references remain valid.
+ 1709 + + Otherwise,
+ 1710 + + @li the contents are logically swapped by making copies, which can
+ 1711 + + throw. In this case all iterators and references are invalidated.
+ 1712 + +
+ 1713 + + @par Complexity
+ 1714 + + Constant or linear in @ref size() `+ other.size()`.
+ 1715 + +
+ 1716 + + @par Exception Safety
+ 1717 + + Strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 1718 + + */
+ 1719 + + BOOST_JSON_DECL
+ 1720 + + void
+ 1721 + + swap(string& other);
+ 1722 + +
+ 1723 + + /** Exchange the given values.
+ 1724 + +
+ 1725 + + Exchanges the contents of the string `lhs` with another string `rhs`.
+ 1726 + + Ownership of the respective @ref boost::container::pmr::memory_resource
+ 1727 + + objects is not transferred.
+ 1728 + +
+ 1729 + + @li If `&lhs == &rhs`, do nothing. Otherwise,
+ 1730 + + @li if `*lhs.storage() == *rhs.storage()`, ownership of the underlying
+ 1731 + + memory is swapped in constant time, with no possibility of
+ 1732 + + exceptions. All iterators and references remain valid. Otherwise,
+ 1733 + + @li the contents are logically swapped by making a copy, which can
+ 1734 + + throw. In this case all iterators and references are invalidated.
+ 1735 + +
+ 1736 + + @par Effects
+ 1737 + + @code
+ 1738 + + lhs.swap( rhs );
+ 1739 + + @endcode
+ 1740 + +
+ 1741 + + @par Complexity
+ 1742 + + Constant or linear in `lhs.size() + rhs.size()`.
+ 1743 + +
+ 1744 + + @par Exception Safety
+ 1745 + + Strong guarantee.
+ 1746 + + Calls to `memory_resource::allocate` may throw.
+ 1747 + +
+ 1748 + + @param lhs The string to exchange.
+ 1749 + + @param rhs The string to exchange.
+ 1750 + +
+ 1751 + + @see @ref string::swap
+ 1752 + + */
+ 1753 + + friend
+ 1754 + + void
+ 1755 + +2 swap(string& lhs, string& rhs)
+ 1756 + + {
+ 1757 + +2 lhs.swap(rhs);
+ 1758 + +2 }
+ 1759 + + //------------------------------------------------------
+ 1760 + + //
+ 1761 + + // Search
+ 1762 + + //
+ 1763 + + //------------------------------------------------------
+ 1764 + +
+ 1765 + + /** Find the first occurrence of characters within the string.
+ 1766 + +
+ 1767 + + Search from `pos` onward for the first substring that is equal to the
+ 1768 + + first argument.
+ 1769 + +
+ 1770 + + @li **(1)** searches for the presense of the substring equal to `sv`.
+ 1771 + + @li **(2)** searches for the presense of the substring consisting of
+ 1772 + + the character `ch`.
+ 1773 + +
+ 1774 + + @par Complexity
+ 1775 + + Linear in @ref size().
+ 1776 + +
+ 1777 + + @par Exception Safety
+ 1778 + + No-throw guarantee.
+ 1779 + +
+ 1780 + + @return The index of the first character of the found substring, or
+ 1781 + + @ref npos if none was found.
+ 1782 + +
+ 1783 + + @param sv The `string_view` to search for.
+ 1784 + + @param pos The index to start searching at.
+ 1785 + +
+ 1786 + + @{
+ 1787 + + */
+ 1788 + + std::size_t
+ 1789 + +5 find(
+ 1790 + + string_view sv,
+ 1791 + + std::size_t pos = 0) const noexcept
+ 1792 + + {
+ 1793 + +5 return subview().find(sv, pos);
+ 1794 + + }
+ 1795 + +
+ 1796 + + /** Overload
+ 1797 + +
+ 1798 + + @param ch The character to search for.
+ 1799 + + @param pos
+ 1800 + + */
+ 1801 + + std::size_t
+ 1802 + +3 find(
+ 1803 + + char ch,
+ 1804 + + std::size_t pos = 0) const noexcept
+ 1805 + + {
+ 1806 + +3 return subview().find(ch, pos);
+ 1807 + + }
+ 1808 + + /// @}
+ 1809 + +
+ 1810 + + /** Find the last occurrence of a string within the string.
+ 1811 + +
+ 1812 + + @li **(1)** searches for the last substring equal to `sv`.
+ 1813 + + @li **(2)** searches for the last occurrence of `ch`.
+ 1814 + +
+ 1815 + + Both functions search for substrings fully contained within `[begin(),
+ 1816 + + begin() + pos)`.
+ 1817 + +
+ 1818 + + @par Complexity
+ 1819 + + Linear.
+ 1820 + +
+ 1821 + + @return Index of the first character of the found substring or
+ 1822 + + @ref npos if none was found.
+ 1823 + +
+ 1824 + + @param sv The string to search for.
+ 1825 + + @param pos The index to start searching at. By default searches from
+ 1826 + + the end of the string.
+ 1827 + +
+ 1828 + + @{
+ 1829 + + */
+ 1830 + + std::size_t
+ 1831 + +5 rfind(
+ 1832 + + string_view sv,
+ 1833 + + std::size_t pos = npos) const noexcept
+ 1834 + + {
+ 1835 + +5 return subview().rfind(sv, pos);
+ 1836 + + }
+ 1837 + +
+ 1838 + + /** Overload
+ 1839 + +
+ 1840 + + @param ch The character to search for.
+ 1841 + + @param pos
+ 1842 + + */
+ 1843 + + std::size_t
+ 1844 + +3 rfind(
+ 1845 + + char ch,
+ 1846 + + std::size_t pos = npos) const noexcept
+ 1847 + + {
+ 1848 + +3 return subview().rfind(ch, pos);
+ 1849 + + }
+ 1850 + + /// @}
+ 1851 + +
+ 1852 + + //------------------------------------------------------
+ 1853 + +
+ 1854 + + /** Find the first character present in the specified string.
+ 1855 + +
+ 1856 + + Search from `pos` onward for the first character in this string that is
+ 1857 + + equal to any of the characters of `sv`.
+ 1858 + +
+ 1859 + + @par Complexity
+ 1860 + + Linear in @ref size() `+ sv.size()`.
+ 1861 + +
+ 1862 + + @par Exception Safety
+ 1863 + + No-throw guarantee.
+ 1864 + +
+ 1865 + + @return The index of the found character, or @ref npos if none exists.
+ 1866 + +
+ 1867 + + @param sv The characters to search for.
+ 1868 + + @param pos The index to start searching at.
+ 1869 + + */
+ 1870 + + std::size_t
+ 1871 + +5 find_first_of(
+ 1872 + + string_view sv,
+ 1873 + + std::size_t pos = 0) const noexcept
+ 1874 + + {
+ 1875 + +5 return subview().find_first_of(sv, pos);
+ 1876 + + }
+ 1877 + +
+ 1878 + + /** Find the first character missing from the specified string.
+ 1879 + +
+ 1880 + + Search from `pos` onward for the first character in this string that is
+ 1881 + + not equal to any of the characters in the string provided as the first
+ 1882 + + argument.
+ 1883 + +
+ 1884 + + @li **(1)** compares with the characters in `sv`.
+ 1885 + + @li **(2)** compares with the character `ch`.
+ 1886 + +
+ 1887 + + @par Complexity
+ 1888 + + @li **(1)** linear in @ref size() `+ sv.size()`.
+ 1889 + + @li **(2)** linear in @ref size().
+ 1890 + +
+ 1891 + + @par Exception Safety
+ 1892 + + No-throw guarantee.
+ 1893 + +
+ 1894 + + @return The index of the found character, or @ref npos if none exists.
+ 1895 + +
+ 1896 + + @param sv The characters to compare with.
+ 1897 + + @param pos The index to start searching at.
+ 1898 + +
+ 1899 + + @{
+ 1900 + + */
+ 1901 + + std::size_t
+ 1902 + +4 find_first_not_of(
+ 1903 + + string_view sv,
+ 1904 + + std::size_t pos = 0) const noexcept
+ 1905 + + {
+ 1906 + +4 return subview().find_first_not_of(sv, pos);
+ 1907 + + }
+ 1908 + +
+ 1909 + + /** Overload
+ 1910 + + @param ch The character to compare with.
+ 1911 + + @param pos
+ 1912 + + */
+ 1913 + + std::size_t
+ 1914 + +3 find_first_not_of(
+ 1915 + + char ch,
+ 1916 + + std::size_t pos = 0) const noexcept
+ 1917 + + {
+ 1918 + +3 return subview().find_first_not_of(ch, pos);
+ 1919 + + }
+ 1920 + + /// @}
+ 1921 + +
+ 1922 + + /** Find the last character present in the specified string.
+ 1923 + +
+ 1924 + + Search from `pos` backwards for the first character in this string that
+ 1925 + + is equal to any of the characters of `sv`. If `pos` is equal to @ref
+ 1926 + + npos (the default), search from the last character.
+ 1927 + +
+ 1928 + + @par Complexity
+ 1929 + + Linear in @ref size() `+ sv.size()`.
+ 1930 + +
+ 1931 + + @par Exception Safety
+ 1932 + + No-throw guarantee.
+ 1933 + +
+ 1934 + + @return The index of the found character, or @ref npos if none exists.
+ 1935 + +
+ 1936 + + @param sv The characters to search for.
+ 1937 + + @param pos The index to start searching at.
+ 1938 + + */
+ 1939 + + std::size_t
+ 1940 + +5 find_last_of(
+ 1941 + + string_view sv,
+ 1942 + + std::size_t pos = npos) const noexcept
+ 1943 + + {
+ 1944 + +5 return subview().find_last_of(sv, pos);
+ 1945 + + }
+ 1946 + +
+ 1947 + + /** Find the last character missing from the specified string.
+ 1948 + +
+ 1949 + +
+ 1950 + + Search from `pos` backwards for the first character in this string that
+ 1951 + + is not equal to any of the characters in the string provided as the
+ 1952 + + first argument. If `pos` is equal to @ref npos (the default), search
+ 1953 + + from the last character.
+ 1954 + +
+ 1955 + + @li **(1)** compares with the characters in `sv`.
+ 1956 + + @li **(2)** compares with the character `ch`.
+ 1957 + +
+ 1958 + + @par Complexity
+ 1959 + + @li **(1)** linear in @ref size() `+ sv.size()`.
+ 1960 + + @li **(2)** linear in @ref size().
+ 1961 + +
+ 1962 + + @par Exception Safety
+ 1963 + + No-throw guarantee.
+ 1964 + +
+ 1965 + + @return The index of the found character, or @ref npos if none exists.
+ 1966 + +
+ 1967 + + @param sv The characters to compare with.
+ 1968 + + @param pos The index to start searching at.
+ 1969 + +
+ 1970 + + @{
+ 1971 + + */
+ 1972 + + std::size_t
+ 1973 + +4 find_last_not_of(
+ 1974 + + string_view sv,
+ 1975 + + std::size_t pos = npos) const noexcept
+ 1976 + + {
+ 1977 + +4 return subview().find_last_not_of(sv, pos);
+ 1978 + + }
+ 1979 + +
+ 1980 + + /** Overload
+ 1981 + + @param ch The character to compare with.
+ 1982 + + @param pos
+ 1983 + + */
+ 1984 + + std::size_t
+ 1985 + +3 find_last_not_of(
+ 1986 + + char ch,
+ 1987 + + std::size_t pos = npos) const noexcept
+ 1988 + + {
+ 1989 + +3 return subview().find_last_not_of(ch, pos);
+ 1990 + + }
+ 1991 + + /// @}
+ 1992 + +
+ 1993 + + /** Serialize a @ref string to an output stream.
+ 1994 + +
+ 1995 + + This function serializes a `string` as JSON into the output stream.
+ 1996 + +
+ 1997 + + @return Reference to `os`.
+ 1998 + +
+ 1999 + + @par Complexity
+ 2000 + + Linear in the `str.size()`.
+ 2001 + +
+ 2002 + + @par Exception Safety
+ 2003 + + Strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 2004 + +
+ 2005 + + @param os The output stream to serialize to.
+ 2006 + + @param str The value to serialize.
+ 2007 + + */
+ 2008 + + BOOST_JSON_DECL
+ 2009 + + friend
+ 2010 + + std::ostream&
+ 2011 + + operator<<(
+ 2012 + + std::ostream& os,
+ 2013 + + string const& str);
+ 2014 + +
+ 2015 + + private:
+ 2016 + + class undo;
+ 2017 + +
+ 2018 + + template<class It>
+ 2019 + + using iter_cat = typename
+ 2020 + + std::iterator_traits<It>::iterator_category;
+ 2021 + +
+ 2022 + + template<class InputIt>
+ 2023 + + void
+ 2024 + + assign(InputIt first, InputIt last,
+ 2025 + + std::random_access_iterator_tag);
+ 2026 + +
+ 2027 + + template<class InputIt>
+ 2028 + + void
+ 2029 + + assign(InputIt first, InputIt last,
+ 2030 + + std::input_iterator_tag);
+ 2031 + +
+ 2032 + + template<class InputIt>
+ 2033 + + void
+ 2034 + + append(InputIt first, InputIt last,
+ 2035 + + std::random_access_iterator_tag);
+ 2036 + +
+ 2037 + + template<class InputIt>
+ 2038 + + void
+ 2039 + + append(InputIt first, InputIt last,
+ 2040 + + std::input_iterator_tag);
+ 2041 + +
+ 2042 + + BOOST_JSON_DECL
+ 2043 + + void
+ 2044 + + reserve_impl(std::size_t new_capacity);
+ 2045 + + };
+ 2046 + +
+ 2047 + + //----------------------------------------------------------
+ 2048 + +
+ 2049 + + namespace detail
+ 2050 + + {
+ 2051 + +
+ 2052 + + template <>
+ 2053 + + inline
+ 2054 + + string_view
+ 2055 + +28787 to_string_view<string>(string const& s) noexcept
+ 2056 + + {
+ 2057 + +28787 return s.subview();
+ 2058 + + }
+ 2059 + +
+ 2060 + + } // namespace detail
+ 2061 + +
+ 2062 + +
+ 2063 + + /** Checks if lhs equals rhs.
+ 2064 + +
+ 2065 + + @li **(1)** A lexicographical comparison is used.
+ 2066 + + @li **(2)** equivalent to `lhs.get() == rhs.get()`.
+ 2067 + +
+ 2068 + + @par Complexity
+ 2069 + + @li **(1)** linear in `lhs.size() + rhs.size()`.
+ 2070 + + @li **(2)** constant.
+ 2071 + +
+ 2072 + + @par Exception Safety
+ 2073 + + No-throw guarantee.
+ 2074 + + */
+ 2075 + + #ifdef BOOST_JSON_DOCS
+ 2076 + + bool
+ 2077 + + operator==(string const& lhs, string const& rhs) noexcept
+ 2078 + + #else
+ 2079 + + template<class T, class U>
+ 2080 + + detail::string_comp_op_requirement<T, U>
+ 2081 + +15562 operator==(T const& lhs, U const& rhs) noexcept
+ 2082 + + #endif
+ 2083 + + {
+ 2084 + +15562 return detail::to_string_view(lhs) == detail::to_string_view(rhs);
+ 2085 + + }
+ 2086 + +
+ 2087 + + /** Checks if lhs does not equal rhs.
+ 2088 + +
+ 2089 + + @li **(1)** A lexicographical comparison is used.
+ 2090 + + @li **(2)** equivalent to `lhs.get() != rhs.get()`.
+ 2091 + +
+ 2092 + + @par Complexity
+ 2093 + + @li **(1)** linear in `lhs.size() + rhs.size()`.
+ 2094 + + @li **(2)** constant.
+ 2095 + +
+ 2096 + + @par Exception Safety
+ 2097 + + No-throw guarantee.
+ 2098 + + */
+ 2099 + + #ifdef BOOST_JSON_DOCS
+ 2100 + + bool
+ 2101 + + operator!=(string const& lhs, string const& rhs) noexcept
+ 2102 + + #else
+ 2103 + + template<class T, class U>
+ 2104 + + detail::string_comp_op_requirement<T, U>
+ 2105 + +24 operator!=(T const& lhs, U const& rhs) noexcept
+ 2106 + + #endif
+ 2107 + + {
+ 2108 + +24 return detail::to_string_view(lhs) != detail::to_string_view(rhs);
+ 2109 + + }
+ 2110 + +
+ 2111 + + /** Check if lhs is less than rhs.
+ 2112 + +
+ 2113 + + A lexicographical comparison is used.
+ 2114 + +
+ 2115 + + @par Complexity
+ 2116 + + Linear in `lhs.size() + rhs.size()`.
+ 2117 + +
+ 2118 + + @par Exception Safety
+ 2119 + + No-throw guarantee.
+ 2120 + + */
+ 2121 + + #ifdef BOOST_JSON_DOCS
+ 2122 + + bool
+ 2123 + + operator<(string const& lhs, string const& rhs) noexcept
+ 2124 + + #else
+ 2125 + + template<class T, class U>
+ 2126 + + detail::string_comp_op_requirement<T, U>
+ 2127 + +12 operator<(T const& lhs, U const& rhs) noexcept
+ 2128 + + #endif
+ 2129 + + {
+ 2130 + +12 return detail::to_string_view(lhs) < detail::to_string_view(rhs);
+ 2131 + + }
+ 2132 + +
+ 2133 + + /** Check if lhs is less than or equal to rhs.
+ 2134 + +
+ 2135 + + A lexicographical comparison is used.
+ 2136 + +
+ 2137 + + @par Complexity
+ 2138 + + Linear in `lhs.size() + rhs.size()`.
+ 2139 + +
+ 2140 + + @par Exception Safety
+ 2141 + + No-throw guarantee.
+ 2142 + + */
+ 2143 + + #ifdef BOOST_JSON_DOCS
+ 2144 + + bool
+ 2145 + + operator<=(string const& lhs, string const& rhs) noexcept
+ 2146 + + #else
+ 2147 + + template<class T, class U>
+ 2148 + + detail::string_comp_op_requirement<T, U>
+ 2149 + +12 operator<=(T const& lhs, U const& rhs) noexcept
+ 2150 + + #endif
+ 2151 + + {
+ 2152 + +12 return detail::to_string_view(lhs) <= detail::to_string_view(rhs);
+ 2153 + + }
+ 2154 + +
+ 2155 + + /** Check if lhs is more than or equal to rhs.
+ 2156 + +
+ 2157 + + A lexicographical comparison is used.
+ 2158 + +
+ 2159 + + @par Complexity
+ 2160 + + Linear in `lhs.size() + rhs.size()`.
+ 2161 + +
+ 2162 + + @par Exception Safety
+ 2163 + + No-throw guarantee.
+ 2164 + + */
+ 2165 + + #ifdef BOOST_JSON_DOCS
+ 2166 + + bool
+ 2167 + + operator>=(string const& lhs, string const& rhs) noexcept
+ 2168 + + #else
+ 2169 + + template<class T, class U>
+ 2170 + + detail::string_comp_op_requirement<T, U>
+ 2171 + +12 operator>=(T const& lhs, U const& rhs) noexcept
+ 2172 + + #endif
+ 2173 + + {
+ 2174 + +12 return detail::to_string_view(lhs) >= detail::to_string_view(rhs);
+ 2175 + + }
+ 2176 + +
+ 2177 + + /** Check if lhs is greater than rhs.
+ 2178 + +
+ 2179 + + A lexicographical comparison is used.
+ 2180 + +
+ 2181 + + @par Complexity
+ 2182 + + Linear in `lhs.size() + rhs.size()`.
+ 2183 + +
+ 2184 + + @par Exception Safety
+ 2185 + + No-throw guarantee.
+ 2186 + + */
+ 2187 + + #ifdef BOOST_JSON_DOCS
+ 2188 + + bool
+ 2189 + + operator>(string const& lhs, string const& rhs) noexcept
+ 2190 + + #else
+ 2191 + + template<class T, class U>
+ 2192 + + detail::string_comp_op_requirement<T, U>
+ 2193 + +12 operator>(T const& lhs, U const& rhs) noexcept
+ 2194 + + #endif
+ 2195 + + {
+ 2196 + +12 return detail::to_string_view(lhs) > detail::to_string_view(rhs);
+ 2197 + + }
+ 2198 + +
+ 2199 + + } // namespace json
+ 2200 + + } // namespace boost
+ 2201 + +
+ 2202 + + // std::hash specialization
+ 2203 + + #ifndef BOOST_JSON_DOCS
+ 2204 + + namespace std {
+ 2205 + + template<>
+ 2206 + + struct hash< ::boost::json::string >
+ 2207 + + {
+ 2208 + + BOOST_JSON_DECL
+ 2209 + + std::size_t
+ 2210 + + operator()( ::boost::json::string const& js ) const noexcept;
+ 2211 + + };
+ 2212 + + } // std
+ 2213 + + #endif
+ 2214 + +
+ 2215 + + #include <boost/json/impl/string.hpp>
+ 2216 + +
+ 2217 + + #endif
+ 2218 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.string.ipp.608f1816a0e4c09495ec66dab6eb9085.html b/json/gcovr/index.string.ipp.608f1816a0e4c09495ec66dab6eb9085.html new file mode 100644 index 00000000..0f69a1c3 --- /dev/null +++ b/json/gcovr/index.string.ipp.608f1816a0e4c09495ec66dab6eb9085.html @@ -0,0 +1,5830 @@ + + + + + + impl/string.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/string.ipp

+
+ + 100.0% Lines (167/167) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/string.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_STRING_IPP
+ 11 + + #define BOOST_JSON_IMPL_STRING_IPP
+ 12 + +
+ 13 + + #include <boost/json/detail/except.hpp>
+ 14 + + #include <algorithm>
+ 15 + + #include <new>
+ 16 + + #include <ostream>
+ 17 + + #include <stdexcept>
+ 18 + + #include <string>
+ 19 + + #include <utility>
+ 20 + +
+ 21 + + namespace boost {
+ 22 + + namespace json {
+ 23 + +
+ 24 + + //----------------------------------------------------------
+ 25 + + //
+ 26 + + // Construction
+ 27 + + //
+ 28 + + //----------------------------------------------------------
+ 29 + +
+ 30 + +78 string::
+ 31 + + string(
+ 32 + + std::size_t count,
+ 33 + + char ch,
+ 34 + +78 storage_ptr sp)
+ 35 + +78 : sp_(std::move(sp))
+ 36 + + {
+ 37 + +78 assign(count, ch);
+ 38 + +78 }
+ 39 + +
+ 40 + +173 string::
+ 41 + + string(
+ 42 + + char const* s,
+ 43 + +173 storage_ptr sp)
+ 44 + +173 : sp_(std::move(sp))
+ 45 + + {
+ 46 + +173 assign(s);
+ 47 + +173 }
+ 48 + +
+ 49 + +4 string::
+ 50 + + string(
+ 51 + + char const* s,
+ 52 + + std::size_t count,
+ 53 + +4 storage_ptr sp)
+ 54 + +4 : sp_(std::move(sp))
+ 55 + + {
+ 56 + +4 assign(s, count);
+ 57 + +4 }
+ 58 + +
+ 59 + +8 string::
+ 60 + +8 string(string const& other)
+ 61 + +8 : sp_(other.sp_)
+ 62 + + {
+ 63 + +8 assign(other);
+ 64 + +8 }
+ 65 + +
+ 66 + +145 string::
+ 67 + + string(
+ 68 + + string const& other,
+ 69 + +145 storage_ptr sp)
+ 70 + +145 : sp_(std::move(sp))
+ 71 + + {
+ 72 + +145 assign(other);
+ 73 + +145 }
+ 74 + +
+ 75 + +350 string::
+ 76 + + string(
+ 77 + + string&& other,
+ 78 + +350 storage_ptr sp)
+ 79 + +350 : sp_(std::move(sp))
+ 80 + + {
+ 81 + +350 assign(std::move(other));
+ 82 + +350 }
+ 83 + +
+ 84 + +17882 string::
+ 85 + + string(
+ 86 + + string_view s,
+ 87 + +17882 storage_ptr sp)
+ 88 + +17882 : sp_(std::move(sp))
+ 89 + + {
+ 90 + +17882 assign(s);
+ 91 + +17882 }
+ 92 + +
+ 93 + + //----------------------------------------------------------
+ 94 + + //
+ 95 + + // Assignment
+ 96 + + //
+ 97 + + //----------------------------------------------------------
+ 98 + +
+ 99 + + string&
+ 100 + +6 string::
+ 101 + + operator=(string const& other)
+ 102 + + {
+ 103 + +6 return assign(other);
+ 104 + + }
+ 105 + +
+ 106 + + string&
+ 107 + +10 string::
+ 108 + + operator=(string&& other)
+ 109 + + {
+ 110 + +10 return assign(std::move(other));
+ 111 + + }
+ 112 + +
+ 113 + + string&
+ 114 + +9 string::
+ 115 + + operator=(char const* s)
+ 116 + + {
+ 117 + +9 return assign(s);
+ 118 + + }
+ 119 + +
+ 120 + + string&
+ 121 + +8 string::
+ 122 + + operator=(string_view s)
+ 123 + + {
+ 124 + +8 return assign(s);
+ 125 + + }
+ 126 + +
+ 127 + +
+ 128 + +
+ 129 + + string&
+ 130 + +83 string::
+ 131 + + assign(
+ 132 + + size_type count,
+ 133 + + char ch)
+ 134 + + {
+ 135 + +64 std::char_traits<char>::assign(
+ 136 + +83 impl_.assign(count, sp_),
+ 137 + + count,
+ 138 + + ch);
+ 139 + +64 return *this;
+ 140 + + }
+ 141 + +
+ 142 + + string&
+ 143 + +193 string::
+ 144 + + assign(
+ 145 + + string const& other)
+ 146 + + {
+ 147 + +193 if(this == &other)
+ 148 + +1 return *this;
+ 149 + +192 return assign(
+ 150 + + other.data(),
+ 151 + +165 other.size());
+ 152 + + }
+ 153 + +
+ 154 + + string&
+ 155 + +374 string::
+ 156 + + assign(string&& other)
+ 157 + + {
+ 158 + +374 if( &other == this )
+ 159 + +1 return *this;
+ 160 + +
+ 161 + +373 if(*sp_ == *other.sp_)
+ 162 + + {
+ 163 + +339 impl_.destroy(sp_);
+ 164 + +339 impl_ = other.impl_;
+ 165 + +339 ::new(&other.impl_) detail::string_impl();
+ 166 + +339 return *this;
+ 167 + + }
+ 168 + +
+ 169 + + // copy
+ 170 + +34 return assign(other);
+ 171 + + }
+ 172 + +
+ 173 + + string&
+ 174 + +18357 string::
+ 175 + + assign(
+ 176 + + char const* s,
+ 177 + + size_type count)
+ 178 + + {
+ 179 + +18236 std::char_traits<char>::copy(
+ 180 + +18357 impl_.assign(count, sp_),
+ 181 + + s, count);
+ 182 + +18236 return *this;
+ 183 + + }
+ 184 + +
+ 185 + + string&
+ 186 + +187 string::
+ 187 + + assign(
+ 188 + + char const* s)
+ 189 + + {
+ 190 + +187 return assign(s, std::char_traits<
+ 191 + +184 char>::length(s));
+ 192 + + }
+ 193 + +
+ 194 + + //----------------------------------------------------------
+ 195 + + //
+ 196 + + // Capacity
+ 197 + + //
+ 198 + + //----------------------------------------------------------
+ 199 + +
+ 200 + + void
+ 201 + +7 string::
+ 202 + + shrink_to_fit()
+ 203 + + {
+ 204 + +7 impl_.shrink_to_fit(sp_);
+ 205 + +7 }
+ 206 + +
+ 207 + + //----------------------------------------------------------
+ 208 + + //
+ 209 + + // Access
+ 210 + + //
+ 211 + + //----------------------------------------------------------
+ 212 + +
+ 213 + + system::result<char&>
+ 214 + +12 string::try_at(std::size_t pos) noexcept
+ 215 + + {
+ 216 + +12 if( pos < size() )
+ 217 + +10 return impl_.data()[pos];
+ 218 + +
+ 219 + +2 system::error_code ec;
+ 220 + +2 BOOST_JSON_FAIL(ec, error::out_of_range);
+ 221 + +2 return ec;
+ 222 + + }
+ 223 + +
+ 224 + + system::result<char const&>
+ 225 + +20 string::try_at(std::size_t pos) const noexcept
+ 226 + + {
+ 227 + +20 if( pos < size() )
+ 228 + +18 return impl_.data()[pos];
+ 229 + +
+ 230 + +2 system::error_code ec;
+ 231 + +2 BOOST_JSON_FAIL(ec, error::out_of_range);
+ 232 + +2 return ec;
+ 233 + + }
+ 234 + +
+ 235 + + char const&
+ 236 + +18 string::at(std::size_t pos, source_location const& loc) const
+ 237 + + {
+ 238 + +18 return try_at(pos).value(loc);
+ 239 + + }
+ 240 + +
+ 241 + + //----------------------------------------------------------
+ 242 + + //
+ 243 + + // Operations
+ 244 + + //
+ 245 + + //----------------------------------------------------------
+ 246 + +
+ 247 + + void
+ 248 + +2 string::
+ 249 + + clear() noexcept
+ 250 + + {
+ 251 + +2 impl_.term(0);
+ 252 + +2 }
+ 253 + +
+ 254 + + //----------------------------------------------------------
+ 255 + +
+ 256 + + void
+ 257 + +88 string::
+ 258 + + push_back(char ch)
+ 259 + + {
+ 260 + +88 *impl_.append(1, sp_) = ch;
+ 261 + +86 }
+ 262 + +
+ 263 + + void
+ 264 + +29 string::
+ 265 + + pop_back()
+ 266 + + {
+ 267 + +29 back() = 0;
+ 268 + +29 impl_.size(impl_.size() - 1);
+ 269 + +29 }
+ 270 + +
+ 271 + + //----------------------------------------------------------
+ 272 + +
+ 273 + + string&
+ 274 + +4 string::
+ 275 + + append(size_type count, char ch)
+ 276 + + {
+ 277 + +2 std::char_traits<char>::assign(
+ 278 + +4 impl_.append(count, sp_),
+ 279 + + count, ch);
+ 280 + +2 return *this;
+ 281 + + }
+ 282 + +
+ 283 + + string&
+ 284 + +45 string::
+ 285 + + append(string_view sv)
+ 286 + + {
+ 287 + +90 std::char_traits<char>::copy(
+ 288 + +45 impl_.append(sv.size(), sp_),
+ 289 + + sv.data(), sv.size());
+ 290 + +34 return *this;
+ 291 + + }
+ 292 + +
+ 293 + + //----------------------------------------------------------
+ 294 + +
+ 295 + + string&
+ 296 + +27 string::
+ 297 + + insert(
+ 298 + + size_type pos,
+ 299 + + string_view sv)
+ 300 + + {
+ 301 + +27 impl_.insert(pos, sv.data(), sv.size(), sp_);
+ 302 + +17 return *this;
+ 303 + + }
+ 304 + +
+ 305 + + string&
+ 306 + +11 string::
+ 307 + + insert(
+ 308 + + std::size_t pos,
+ 309 + + std::size_t count,
+ 310 + + char ch)
+ 311 + + {
+ 312 + +6 std::char_traits<char>::assign(
+ 313 + +11 impl_.insert_unchecked(pos, count, sp_),
+ 314 + + count, ch);
+ 315 + +6 return *this;
+ 316 + + }
+ 317 + +
+ 318 + + //----------------------------------------------------------
+ 319 + +
+ 320 + + string&
+ 321 + +19 string::
+ 322 + + replace(
+ 323 + + std::size_t pos,
+ 324 + + std::size_t count,
+ 325 + + string_view sv)
+ 326 + + {
+ 327 + +19 impl_.replace(pos, count, sv.data(), sv.size(), sp_);
+ 328 + +15 return *this;
+ 329 + + }
+ 330 + +
+ 331 + + string&
+ 332 + +7 string::
+ 333 + + replace(
+ 334 + + std::size_t pos,
+ 335 + + std::size_t count,
+ 336 + + std::size_t count2,
+ 337 + + char ch)
+ 338 + + {
+ 339 + +4 std::char_traits<char>::assign(
+ 340 + +7 impl_.replace_unchecked(pos, count, count2, sp_),
+ 341 + + count2, ch);
+ 342 + +4 return *this;
+ 343 + + }
+ 344 + +
+ 345 + + //----------------------------------------------------------
+ 346 + +
+ 347 + + string&
+ 348 + +10 string::
+ 349 + + erase(
+ 350 + + size_type pos,
+ 351 + + size_type count)
+ 352 + + {
+ 353 + +10 if(pos > impl_.size())
+ 354 + + {
+ 355 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 356 + +1 detail::throw_system_error( error::out_of_range, &loc );
+ 357 + + }
+ 358 + +9 if( count > impl_.size() - pos)
+ 359 + +4 count = impl_.size() - pos;
+ 360 + +9 std::char_traits<char>::move(
+ 361 + +9 impl_.data() + pos,
+ 362 + +9 impl_.data() + pos + count,
+ 363 + +9 impl_.size() - pos - count + 1);
+ 364 + +9 impl_.term(impl_.size() - count);
+ 365 + +9 return *this;
+ 366 + + }
+ 367 + +
+ 368 + + auto
+ 369 + +2 string::
+ 370 + + erase(const_iterator pos) ->
+ 371 + + iterator
+ 372 + + {
+ 373 + +2 return erase(pos, pos+1);
+ 374 + + }
+ 375 + +
+ 376 + + auto
+ 377 + +3 string::
+ 378 + + erase(
+ 379 + + const_iterator first,
+ 380 + + const_iterator last) ->
+ 381 + + iterator
+ 382 + + {
+ 383 + +3 auto const pos = first - begin();
+ 384 + +3 auto const count = last - first;
+ 385 + +3 erase(pos, count);
+ 386 + +3 return data() + pos;
+ 387 + + }
+ 388 + +
+ 389 + + //----------------------------------------------------------
+ 390 + +
+ 391 + + void
+ 392 + +66 string::
+ 393 + + resize(size_type count, char ch)
+ 394 + + {
+ 395 + +66 if(count <= impl_.size())
+ 396 + + {
+ 397 + +25 impl_.term(count);
+ 398 + +25 return;
+ 399 + + }
+ 400 + +
+ 401 + +41 reserve(count);
+ 402 + +35 std::char_traits<char>::assign(
+ 403 + + impl_.end(),
+ 404 + +35 count - impl_.size(),
+ 405 + + ch);
+ 406 + +35 grow(count - size());
+ 407 + + }
+ 408 + +
+ 409 + + //----------------------------------------------------------
+ 410 + +
+ 411 + + void
+ 412 + +4 string::
+ 413 + + swap(string& other)
+ 414 + + {
+ 415 + +4 if(*sp_ == *other.sp_)
+ 416 + + {
+ 417 + +3 std::swap(impl_, other.impl_);
+ 418 + +3 return;
+ 419 + + }
+ 420 + + string temp1(
+ 421 + +1 std::move(*this), other.sp_);
+ 422 + + string temp2(
+ 423 + +1 std::move(other), sp_);
+ 424 + +1 this->~string();
+ 425 + +1 ::new(this) string(pilfer(temp2));
+ 426 + +1 other.~string();
+ 427 + +1 ::new(&other) string(pilfer(temp1));
+ 428 + +1 }
+ 429 + +
+ 430 + + //----------------------------------------------------------
+ 431 + +
+ 432 + + void
+ 433 + +9686 string::
+ 434 + + reserve_impl(size_type new_cap)
+ 435 + + {
+ 436 + +9686 BOOST_ASSERT(
+ 437 + + new_cap >= impl_.capacity());
+ 438 + +9686 if(new_cap > impl_.capacity())
+ 439 + + {
+ 440 + + // grow
+ 441 + +9686 new_cap = detail::string_impl::growth(
+ 442 + + new_cap, impl_.capacity());
+ 443 + +9685 detail::string_impl tmp(new_cap, sp_);
+ 444 + +9675 std::char_traits<char>::copy(tmp.data(),
+ 445 + +9675 impl_.data(), impl_.size() + 1);
+ 446 + +9675 tmp.size(impl_.size());
+ 447 + +9675 impl_.destroy(sp_);
+ 448 + +9675 impl_ = tmp;
+ 449 + +9675 return;
+ 450 + + }
+ 451 + + }
+ 452 + +
+ 453 + + } // namespace json
+ 454 + + } // namespace boost
+ 455 + +
+ 456 + + //----------------------------------------------------------
+ 457 + +
+ 458 + + std::size_t
+ 459 + +3 std::hash< ::boost::json::string >::operator()(
+ 460 + + ::boost::json::string const& js ) const noexcept
+ 461 + + {
+ 462 + +3 return ::boost::hash< ::boost::json::string >()( js );
+ 463 + + }
+ 464 + +
+ 465 + + #endif
+ 466 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.string_impl.hpp.3bd773ee5e5571ae1ed6db73d00280e3.html b/json/gcovr/index.string_impl.hpp.3bd773ee5e5571ae1ed6db73d00280e3.html new file mode 100644 index 00000000..e3c57326 --- /dev/null +++ b/json/gcovr/index.string_impl.hpp.3bd773ee5e5571ae1ed6db73d00280e3.html @@ -0,0 +1,5198 @@ + + + + + + detail/string_impl.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/string_impl.hpp

+
+ + 100.0% Lines (73/73) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/string_impl.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_DETAIL_STRING_IMPL_HPP
+ 12 + + #define BOOST_JSON_DETAIL_STRING_IMPL_HPP
+ 13 + +
+ 14 + + #include <boost/core/detail/static_assert.hpp>
+ 15 + + #include <boost/json/detail/config.hpp>
+ 16 + + #include <boost/json/kind.hpp>
+ 17 + + #include <boost/json/storage_ptr.hpp>
+ 18 + + #include <boost/json/detail/value.hpp>
+ 19 + + #include <algorithm>
+ 20 + + #include <iterator>
+ 21 + +
+ 22 + + namespace boost {
+ 23 + + namespace json {
+ 24 + +
+ 25 + + class value;
+ 26 + + class string;
+ 27 + +
+ 28 + + namespace detail {
+ 29 + +
+ 30 + + class string_impl
+ 31 + + {
+ 32 + + struct table
+ 33 + + {
+ 34 + + std::uint32_t size;
+ 35 + + std::uint32_t capacity;
+ 36 + + };
+ 37 + +
+ 38 + + #if BOOST_JSON_ARCH == 64
+ 39 + + static constexpr std::size_t sbo_chars_ = 14;
+ 40 + + #elif BOOST_JSON_ARCH == 32
+ 41 + + static constexpr std::size_t sbo_chars_ = 10;
+ 42 + + #else
+ 43 + + # error Unknown architecture
+ 44 + + #endif
+ 45 + +
+ 46 + + static
+ 47 + + constexpr
+ 48 + + kind
+ 49 + + short_string_ =
+ 50 + + static_cast<kind>(
+ 51 + + ((unsigned char)
+ 52 + + kind::string) | 0x80);
+ 53 + +
+ 54 + + static
+ 55 + + constexpr
+ 56 + + kind
+ 57 + + key_string_ =
+ 58 + + static_cast<kind>(
+ 59 + + ((unsigned char)
+ 60 + + kind::string) | 0x40);
+ 61 + +
+ 62 + + struct sbo
+ 63 + + {
+ 64 + + kind k; // must come first
+ 65 + + char buf[sbo_chars_ + 1];
+ 66 + + };
+ 67 + +
+ 68 + + struct pointer
+ 69 + + {
+ 70 + + kind k; // must come first
+ 71 + + table* t;
+ 72 + + };
+ 73 + +
+ 74 + + struct key
+ 75 + + {
+ 76 + + kind k; // must come first
+ 77 + + std::uint32_t n;
+ 78 + + char* s;
+ 79 + + };
+ 80 + +
+ 81 + + union
+ 82 + + {
+ 83 + + sbo s_;
+ 84 + + pointer p_;
+ 85 + + key k_;
+ 86 + + };
+ 87 + +
+ 88 + + #if BOOST_JSON_ARCH == 64
+ 89 + + BOOST_CORE_STATIC_ASSERT( sizeof(sbo) <= 16 );
+ 90 + + BOOST_CORE_STATIC_ASSERT( sizeof(pointer) <= 16 );
+ 91 + + BOOST_CORE_STATIC_ASSERT( sizeof(key) <= 16 );
+ 92 + + #elif BOOST_JSON_ARCH == 32
+ 93 + + BOOST_CORE_STATIC_ASSERT( sizeof(sbo) <= 24 );
+ 94 + + BOOST_CORE_STATIC_ASSERT( sizeof(pointer) <= 24 );
+ 95 + + BOOST_CORE_STATIC_ASSERT( sizeof(key) <= 24 );
+ 96 + + #endif
+ 97 + +
+ 98 + + public:
+ 99 + + static
+ 100 + + constexpr
+ 101 + + std::size_t
+ 102 + +153866 max_size() noexcept
+ 103 + + {
+ 104 + + // max_size depends on the address model
+ 105 + + using min = std::integral_constant<std::size_t,
+ 106 + + std::size_t(-1) - sizeof(table)>;
+ 107 + + return min::value < BOOST_JSON_MAX_STRING_SIZE ?
+ 108 + +153866 min::value : BOOST_JSON_MAX_STRING_SIZE;
+ 109 + + }
+ 110 + +
+ 111 + + BOOST_JSON_DECL
+ 112 + + string_impl() noexcept;
+ 113 + +
+ 114 + + BOOST_JSON_DECL
+ 115 + + string_impl(
+ 116 + + std::size_t new_size,
+ 117 + + storage_ptr const& sp);
+ 118 + +
+ 119 + + BOOST_JSON_DECL
+ 120 + + string_impl(
+ 121 + + key_t,
+ 122 + + string_view s,
+ 123 + + storage_ptr const& sp);
+ 124 + +
+ 125 + + BOOST_JSON_DECL
+ 126 + + string_impl(
+ 127 + + key_t,
+ 128 + + string_view s1,
+ 129 + + string_view s2,
+ 130 + + storage_ptr const& sp);
+ 131 + +
+ 132 + + BOOST_JSON_DECL
+ 133 + + string_impl(
+ 134 + + char** dest,
+ 135 + + std::size_t len,
+ 136 + + storage_ptr const& sp);
+ 137 + +
+ 138 + + template<class InputIt>
+ 139 + +8 string_impl(
+ 140 + + InputIt first,
+ 141 + + InputIt last,
+ 142 + + storage_ptr const& sp,
+ 143 + + std::random_access_iterator_tag)
+ 144 + +8 : string_impl(last - first, sp)
+ 145 + + {
+ 146 + +7 char* out = data();
+ 147 + + #if defined(_MSC_VER) && _MSC_VER <= 1900
+ 148 + + while( first != last )
+ 149 + + *out++ = *first++;
+ 150 + + #else
+ 151 + +7 std::copy(first, last, out);
+ 152 + + #endif
+ 153 + +7 }
+ 154 + +
+ 155 + + template<class InputIt>
+ 156 + +38 string_impl(
+ 157 + + InputIt first,
+ 158 + + InputIt last,
+ 159 + + storage_ptr const& sp,
+ 160 + + std::input_iterator_tag)
+ 161 + +38 : string_impl(0, sp)
+ 162 + + {
+ 163 + + struct undo
+ 164 + + {
+ 165 + + string_impl* s;
+ 166 + + storage_ptr const& sp;
+ 167 + +
+ 168 + +38 ~undo()
+ 169 + + {
+ 170 + +38 if(s)
+ 171 + +3 s->destroy(sp);
+ 172 + +38 }
+ 173 + + };
+ 174 + +
+ 175 + +38 undo u{this, sp};
+ 176 + +38 auto dest = data();
+ 177 + +313 while(first != last)
+ 178 + + {
+ 179 + +278 if(size() < capacity())
+ 180 + +267 size(size() + 1);
+ 181 + + else
+ 182 + +11 dest = append(1, sp);
+ 183 + +275 *dest++ = *first++;
+ 184 + + }
+ 185 + +35 term(size());
+ 186 + +35 u.s = nullptr;
+ 187 + +38 }
+ 188 + +
+ 189 + + std::size_t
+ 190 + +98892 size() const noexcept
+ 191 + + {
+ 192 + +98892 return s_.k == kind::string ?
+ 193 + +64299 p_.t->size :
+ 194 + + sbo_chars_ -
+ 195 + +98892 s_.buf[sbo_chars_];
+ 196 + + }
+ 197 + +
+ 198 + + std::size_t
+ 199 + +91875 capacity() const noexcept
+ 200 + + {
+ 201 + +91875 return s_.k == kind::string ?
+ 202 + +11708 p_.t->capacity :
+ 203 + +91875 sbo_chars_;
+ 204 + + }
+ 205 + +
+ 206 + + void
+ 207 + +10015 size(std::size_t n)
+ 208 + + {
+ 209 + +10015 if(s_.k == kind::string)
+ 210 + +9733 p_.t->size = static_cast<
+ 211 + + std::uint32_t>(n);
+ 212 + + else
+ 213 + +282 s_.buf[sbo_chars_] =
+ 214 + + static_cast<char>(
+ 215 + +282 sbo_chars_ - n);
+ 216 + +10015 }
+ 217 + +
+ 218 + + BOOST_JSON_DECL
+ 219 + + static
+ 220 + + std::uint32_t
+ 221 + + growth(
+ 222 + + std::size_t new_size,
+ 223 + + std::size_t capacity);
+ 224 + +
+ 225 + + char const*
+ 226 + +38150 release_key(
+ 227 + + std::size_t& n) noexcept
+ 228 + + {
+ 229 + +38150 BOOST_ASSERT(
+ 230 + + k_.k == key_string_);
+ 231 + +38150 n = k_.n;
+ 232 + +38150 auto const s = k_.s;
+ 233 + + // prevent deallocate
+ 234 + +38150 k_.k = short_string_;
+ 235 + +38150 return s;
+ 236 + + }
+ 237 + +
+ 238 + + void
+ 239 + +57650 destroy(
+ 240 + + storage_ptr const& sp) noexcept
+ 241 + + {
+ 242 + +57650 if(s_.k == kind::string)
+ 243 + + {
+ 244 + +26671 sp->deallocate(p_.t,
+ 245 + + sizeof(table) +
+ 246 + +26671 p_.t->capacity + 1,
+ 247 + + alignof(table));
+ 248 + + }
+ 249 + +30979 else if(s_.k != key_string_)
+ 250 + + {
+ 251 + + // do nothing
+ 252 + + }
+ 253 + + else
+ 254 + + {
+ 255 + +146 BOOST_ASSERT(
+ 256 + + s_.k == key_string_);
+ 257 + + // VFALCO unfortunately the key string
+ 258 + + // kind increases the cost of the destructor.
+ 259 + + // This function should be skipped when using
+ 260 + + // monotonic_resource.
+ 261 + +146 sp->deallocate(k_.s, k_.n + 1);
+ 262 + + }
+ 263 + +57650 }
+ 264 + +
+ 265 + + BOOST_JSON_DECL
+ 266 + + char*
+ 267 + + assign(
+ 268 + + std::size_t new_size,
+ 269 + + storage_ptr const& sp);
+ 270 + +
+ 271 + + BOOST_JSON_DECL
+ 272 + + char*
+ 273 + + append(
+ 274 + + std::size_t n,
+ 275 + + storage_ptr const& sp);
+ 276 + +
+ 277 + + BOOST_JSON_DECL
+ 278 + + void
+ 279 + + insert(
+ 280 + + std::size_t pos,
+ 281 + + const char* s,
+ 282 + + std::size_t n,
+ 283 + + storage_ptr const& sp);
+ 284 + +
+ 285 + + BOOST_JSON_DECL
+ 286 + + char*
+ 287 + + insert_unchecked(
+ 288 + + std::size_t pos,
+ 289 + + std::size_t n,
+ 290 + + storage_ptr const& sp);
+ 291 + +
+ 292 + + BOOST_JSON_DECL
+ 293 + + void
+ 294 + + replace(
+ 295 + + std::size_t pos,
+ 296 + + std::size_t n1,
+ 297 + + const char* s,
+ 298 + + std::size_t n2,
+ 299 + + storage_ptr const& sp);
+ 300 + +
+ 301 + + BOOST_JSON_DECL
+ 302 + + char*
+ 303 + + replace_unchecked(
+ 304 + + std::size_t pos,
+ 305 + + std::size_t n1,
+ 306 + + std::size_t n2,
+ 307 + + storage_ptr const& sp);
+ 308 + +
+ 309 + + BOOST_JSON_DECL
+ 310 + + void
+ 311 + + shrink_to_fit(
+ 312 + + storage_ptr const& sp) noexcept;
+ 313 + +
+ 314 + + void
+ 315 + +33565 term(std::size_t n) noexcept
+ 316 + + {
+ 317 + +33565 if(s_.k == short_string_)
+ 318 + + {
+ 319 + +5140 s_.buf[sbo_chars_] =
+ 320 + + static_cast<char>(
+ 321 + +5140 sbo_chars_ - n);
+ 322 + +5140 s_.buf[n] = 0;
+ 323 + + }
+ 324 + + else
+ 325 + + {
+ 326 + +28425 p_.t->size = static_cast<
+ 327 + + std::uint32_t>(n);
+ 328 + +28425 data()[n] = 0;
+ 329 + + }
+ 330 + +33565 }
+ 331 + +
+ 332 + + char*
+ 333 + +117283 data() noexcept
+ 334 + + {
+ 335 + +117283 if(s_.k == short_string_)
+ 336 + +15377 return s_.buf;
+ 337 + + return reinterpret_cast<
+ 338 + +101906 char*>(p_.t + 1);
+ 339 + + }
+ 340 + +
+ 341 + + char const*
+ 342 + +44003 data() const noexcept
+ 343 + + {
+ 344 + +44003 if(s_.k == short_string_)
+ 345 + +4548 return s_.buf;
+ 346 + + return reinterpret_cast<
+ 347 + +39455 char const*>(p_.t + 1);
+ 348 + + }
+ 349 + +
+ 350 + + char*
+ 351 + +175 end() noexcept
+ 352 + + {
+ 353 + +175 return data() + size();
+ 354 + + }
+ 355 + +
+ 356 + + char const*
+ 357 + +10 end() const noexcept
+ 358 + + {
+ 359 + +10 return data() + size();
+ 360 + + }
+ 361 + + };
+ 362 + +
+ 363 + + template<class T>
+ 364 + + string_view
+ 365 + +2481 to_string_view(T const& t) noexcept
+ 366 + + {
+ 367 + +2481 return string_view(t);
+ 368 + + }
+ 369 + +
+ 370 + + template<class T, class U>
+ 371 + + using string_and_stringlike = std::integral_constant<bool,
+ 372 + + std::is_same<T, string>::value &&
+ 373 + + std::is_convertible<U const&, string_view>::value>;
+ 374 + +
+ 375 + + template<class T, class U>
+ 376 + + using string_comp_op_requirement
+ 377 + + = typename std::enable_if<
+ 378 + + string_and_stringlike<T, U>::value ||
+ 379 + + string_and_stringlike<U, T>::value,
+ 380 + + bool>::type;
+ 381 + +
+ 382 + + } // detail
+ 383 + + } // namespace json
+ 384 + + } // namespace boost
+ 385 + +
+ 386 + + #endif
+ 387 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.string_impl.ipp.e66f2c45d36b3fec9c3bfbb095fa9edb.html b/json/gcovr/index.string_impl.ipp.e66f2c45d36b3fec9c3bfbb095fa9edb.html new file mode 100644 index 00000000..9cd0faa6 --- /dev/null +++ b/json/gcovr/index.string_impl.ipp.e66f2c45d36b3fec9c3bfbb095fa9edb.html @@ -0,0 +1,6006 @@ + + + + + + detail/impl/string_impl.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/impl/string_impl.ipp

+
+ + 99.1% Lines (227/229) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/impl/string_impl.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_DETAIL_IMPL_STRING_IMPL_IPP
+ 12 + + #define BOOST_JSON_DETAIL_IMPL_STRING_IMPL_IPP
+ 13 + +
+ 14 + + #include <boost/json/detail/string_impl.hpp>
+ 15 + + #include <boost/json/detail/except.hpp>
+ 16 + + #include <cstring>
+ 17 + + #include <functional>
+ 18 + +
+ 19 + + namespace boost {
+ 20 + + namespace json {
+ 21 + + namespace detail {
+ 22 + +
+ 23 + + inline
+ 24 + + bool
+ 25 + +23 ptr_in_range(
+ 26 + + const char* first,
+ 27 + + const char* last,
+ 28 + + const char* ptr) noexcept
+ 29 + + {
+ 30 + +37 return std::less<const char*>()(ptr, last) &&
+ 31 + +37 std::greater_equal<const char*>()(ptr, first);
+ 32 + + }
+ 33 + +
+ 34 + +30925 string_impl::
+ 35 + +30925 string_impl() noexcept
+ 36 + + {
+ 37 + +30925 s_.k = short_string_;
+ 38 + +30925 s_.buf[sbo_chars_] =
+ 39 + + static_cast<char>(
+ 40 + + sbo_chars_);
+ 41 + +30925 s_.buf[0] = 0;
+ 42 + +30925 }
+ 43 + +
+ 44 + +26901 string_impl::
+ 45 + + string_impl(
+ 46 + + std::size_t size,
+ 47 + +26901 storage_ptr const& sp)
+ 48 + + {
+ 49 + +26901 if(size <= sbo_chars_)
+ 50 + + {
+ 51 + +41 s_.k = short_string_;
+ 52 + +41 s_.buf[sbo_chars_] =
+ 53 + + static_cast<char>(
+ 54 + +41 sbo_chars_ - size);
+ 55 + +41 s_.buf[size] = 0;
+ 56 + + }
+ 57 + + else
+ 58 + + {
+ 59 + +26860 s_.k = kind::string;
+ 60 + +26860 auto const n = growth(
+ 61 + + size, sbo_chars_ + 1);
+ 62 + +26860 p_.t = ::new(sp->allocate(
+ 63 + + sizeof(table) +
+ 64 + +26860 n + 1,
+ 65 + + alignof(table))) table{
+ 66 + + static_cast<
+ 67 + + std::uint32_t>(size),
+ 68 + + static_cast<
+ 69 + +26673 std::uint32_t>(n)};
+ 70 + +26673 data()[n] = 0;
+ 71 + + }
+ 72 + +26714 }
+ 73 + +
+ 74 + + // construct a key, unchecked
+ 75 + +30296 string_impl::
+ 76 + + string_impl(
+ 77 + + key_t,
+ 78 + + string_view s,
+ 79 + +30296 storage_ptr const& sp)
+ 80 + + {
+ 81 + +30296 BOOST_ASSERT(
+ 82 + + s.size() <= max_size());
+ 83 + +30296 k_.k = key_string_;
+ 84 + +30296 k_.n = static_cast<
+ 85 + +30296 std::uint32_t>(s.size());
+ 86 + +30236 k_.s = reinterpret_cast<char*>(
+ 87 + +30296 sp->allocate(s.size() + 1,
+ 88 + + alignof(char)));
+ 89 + +30236 k_.s[s.size()] = 0; // null term
+ 90 + +30236 std::memcpy(&k_.s[0],
+ 91 + +30236 s.data(), s.size());
+ 92 + +30236 }
+ 93 + +
+ 94 + + // construct a key, unchecked
+ 95 + +8060 string_impl::
+ 96 + + string_impl(
+ 97 + + key_t,
+ 98 + + string_view s1,
+ 99 + + string_view s2,
+ 100 + +8060 storage_ptr const& sp)
+ 101 + + {
+ 102 + +8060 auto len = s1.size() + s2.size();
+ 103 + +8060 BOOST_ASSERT(len <= max_size());
+ 104 + +8060 k_.k = key_string_;
+ 105 + +8060 k_.n = static_cast<
+ 106 + + std::uint32_t>(len);
+ 107 + +8060 k_.s = reinterpret_cast<char*>(
+ 108 + +8060 sp->allocate(len + 1,
+ 109 + + alignof(char)));
+ 110 + +8060 k_.s[len] = 0; // null term
+ 111 + +8060 std::memcpy(&k_.s[0],
+ 112 + +8060 s1.data(), s1.size());
+ 113 + +16120 std::memcpy(&k_.s[s1.size()],
+ 114 + +8060 s2.data(), s2.size());
+ 115 + +8060 }
+ 116 + +
+ 117 + + std::uint32_t
+ 118 + +53714 string_impl::
+ 119 + + growth(
+ 120 + + std::size_t new_size,
+ 121 + + std::size_t capacity)
+ 122 + + {
+ 123 + +53714 if(new_size > max_size())
+ 124 + + {
+ 125 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 126 + +1 detail::throw_system_error( error::string_too_large, &loc );
+ 127 + + }
+ 128 + + // growth factor 2
+ 129 + +53713 if( capacity >
+ 130 + +53713 max_size() - capacity)
+ 131 + + return static_cast<
+ 132 + + std::uint32_t>(max_size()); // overflow
+ 133 + + return static_cast<std::uint32_t>(
+ 134 + +53713 (std::max)(capacity * 2, new_size));
+ 135 + + }
+ 136 + +
+ 137 + + char*
+ 138 + +18446 string_impl::
+ 139 + + assign(
+ 140 + + std::size_t new_size,
+ 141 + + storage_ptr const& sp)
+ 142 + + {
+ 143 + +18446 if(new_size > capacity())
+ 144 + + {
+ 145 + +17092 string_impl tmp(growth(
+ 146 + + new_size,
+ 147 + +17092 capacity()), sp);
+ 148 + +16951 destroy(sp);
+ 149 + +16951 *this = tmp;
+ 150 + + }
+ 151 + +18305 term(new_size);
+ 152 + +18305 return data();
+ 153 + + }
+ 154 + +
+ 155 + + char*
+ 156 + +154 string_impl::
+ 157 + + append(
+ 158 + + std::size_t n,
+ 159 + + storage_ptr const& sp)
+ 160 + + {
+ 161 + +154 if(n > max_size() - size())
+ 162 + + {
+ 163 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 164 + +1 detail::throw_system_error( error::string_too_large, &loc );
+ 165 + + }
+ 166 + +153 if(n <= capacity() - size())
+ 167 + + {
+ 168 + +107 term(size() + n);
+ 169 + +107 return end() - n;
+ 170 + + }
+ 171 + +92 string_impl tmp(growth(
+ 172 + +92 size() + n, capacity()), sp);
+ 173 + +27 std::memcpy(
+ 174 + +27 tmp.data(), data(), size());
+ 175 + +27 tmp.term(size() + n);
+ 176 + +27 destroy(sp);
+ 177 + +27 *this = tmp;
+ 178 + +27 return end() - n;
+ 179 + + }
+ 180 + +
+ 181 + + void
+ 182 + +27 string_impl::
+ 183 + + insert(
+ 184 + + std::size_t pos,
+ 185 + + const char* s,
+ 186 + + std::size_t n,
+ 187 + + storage_ptr const& sp)
+ 188 + + {
+ 189 + +27 const auto curr_size = size();
+ 190 + +27 if(pos > curr_size)
+ 191 + + {
+ 192 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 193 + +2 detail::throw_system_error( error::out_of_range, &loc );
+ 194 + + }
+ 195 + +25 const auto curr_data = data();
+ 196 + +25 if(n <= capacity() - curr_size)
+ 197 + + {
+ 198 + +10 const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, s);
+ 199 + +10 if (!inside || (inside && ((s - curr_data) + n <= pos)))
+ 200 + + {
+ 201 + +8 std::memmove(&curr_data[pos + n], &curr_data[pos], curr_size - pos + 1);
+ 202 + +8 std::memcpy(&curr_data[pos], s, n);
+ 203 + + }
+ 204 + + else
+ 205 + + {
+ 206 + +2 const std::size_t offset = s - curr_data;
+ 207 + +2 std::memmove(&curr_data[pos + n], &curr_data[pos], curr_size - pos + 1);
+ 208 + +2 if (offset < pos)
+ 209 + + {
+ 210 + +1 const std::size_t diff = pos - offset;
+ 211 + +1 std::memcpy(&curr_data[pos], &curr_data[offset], diff);
+ 212 + +1 std::memcpy(&curr_data[pos + diff], &curr_data[pos + n], n - diff);
+ 213 + + }
+ 214 + + else
+ 215 + + {
+ 216 + +1 std::memcpy(&curr_data[pos], &curr_data[offset + n], n);
+ 217 + + }
+ 218 + + }
+ 219 + +10 size(curr_size + n);
+ 220 + + }
+ 221 + + else
+ 222 + + {
+ 223 + +15 if(n > max_size() - curr_size)
+ 224 + + {
+ 225 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 226 + +1 detail::throw_system_error( error::string_too_large, &loc );
+ 227 + + }
+ 228 + +14 string_impl tmp(growth(
+ 229 + +14 curr_size + n, capacity()), sp);
+ 230 + +7 tmp.size(curr_size + n);
+ 231 + +7 std::memcpy(
+ 232 + +7 tmp.data(),
+ 233 + + curr_data,
+ 234 + + pos);
+ 235 + +14 std::memcpy(
+ 236 + +14 tmp.data() + pos + n,
+ 237 + + curr_data + pos,
+ 238 + +7 curr_size + 1 - pos);
+ 239 + +7 std::memcpy(
+ 240 + +7 tmp.data() + pos,
+ 241 + + s,
+ 242 + + n);
+ 243 + +7 destroy(sp);
+ 244 + +7 *this = tmp;
+ 245 + + }
+ 246 + +17 }
+ 247 + +
+ 248 + + char*
+ 249 + +17 string_impl::
+ 250 + + insert_unchecked(
+ 251 + + std::size_t pos,
+ 252 + + std::size_t n,
+ 253 + + storage_ptr const& sp)
+ 254 + + {
+ 255 + +17 const auto curr_size = size();
+ 256 + +17 if(pos > curr_size)
+ 257 + + {
+ 258 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 259 + +1 detail::throw_system_error( error::out_of_range, &loc );
+ 260 + + }
+ 261 + +16 const auto curr_data = data();
+ 262 + +16 if(n <= capacity() - size())
+ 263 + + {
+ 264 + +5 auto const dest =
+ 265 + + curr_data + pos;
+ 266 + +5 std::memmove(
+ 267 + + dest + n,
+ 268 + + dest,
+ 269 + +5 curr_size + 1 - pos);
+ 270 + +5 size(curr_size + n);
+ 271 + +5 return dest;
+ 272 + + }
+ 273 + +11 if(n > max_size() - curr_size)
+ 274 + + {
+ 275 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 276 + +1 detail::throw_system_error( error::string_too_large, &loc );
+ 277 + + }
+ 278 + +10 string_impl tmp(growth(
+ 279 + +10 curr_size + n, capacity()), sp);
+ 280 + +5 tmp.size(curr_size + n);
+ 281 + +5 std::memcpy(
+ 282 + +5 tmp.data(),
+ 283 + + curr_data,
+ 284 + + pos);
+ 285 + +10 std::memcpy(
+ 286 + +10 tmp.data() + pos + n,
+ 287 + + curr_data + pos,
+ 288 + +5 curr_size + 1 - pos);
+ 289 + +5 destroy(sp);
+ 290 + +5 *this = tmp;
+ 291 + +5 return data() + pos;
+ 292 + + }
+ 293 + +
+ 294 + + void
+ 295 + +19 string_impl::
+ 296 + + replace(
+ 297 + + std::size_t pos,
+ 298 + + std::size_t n1,
+ 299 + + const char* s,
+ 300 + + std::size_t n2,
+ 301 + + storage_ptr const& sp)
+ 302 + + {
+ 303 + +19 const auto curr_size = size();
+ 304 + +19 if (pos > curr_size)
+ 305 + + {
+ 306 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 307 + +1 detail::throw_system_error( error::out_of_range, &loc );
+ 308 + + }
+ 309 + +18 const auto curr_data = data();
+ 310 + +18 n1 = (std::min)(n1, curr_size - pos);
+ 311 + +18 const auto delta = (std::max)(n1, n2) -
+ 312 + +18 (std::min)(n1, n2);
+ 313 + + // if we are shrinking in size or we have enough
+ 314 + + // capacity, dont reallocate
+ 315 + +18 if (n1 > n2 || delta <= capacity() - curr_size)
+ 316 + + {
+ 317 + +13 const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, s);
+ 318 + + // there is nothing to replace; return
+ 319 + +13 if (inside && s == curr_data + pos && n1 == n2)
+ 320 + +1 return;
+ 321 + +12 if (!inside || (inside && ((s - curr_data) + n2 <= pos)))
+ 322 + + {
+ 323 + + // source outside
+ 324 + +6 std::memmove(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
+ 325 + +6 std::memcpy(&curr_data[pos], s, n2);
+ 326 + + }
+ 327 + + else
+ 328 + + {
+ 329 + + // source inside
+ 330 + +6 const std::size_t offset = s - curr_data;
+ 331 + +6 if (n2 >= n1)
+ 332 + + {
+ 333 + + // grow/unchanged
+ 334 + +4 const std::size_t diff = offset <= pos + n1 ? (std::min)((pos + n1) - offset, n2) : 0;
+ 335 + + // shift all right of splice point by n2 - n1 to the right
+ 336 + +4 std::memmove(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
+ 337 + + // copy all before splice point
+ 338 + +4 std::memmove(&curr_data[pos], &curr_data[offset], diff);
+ 339 + + // copy all after splice point
+ 340 + +4 std::memmove(&curr_data[pos + diff], &curr_data[(offset - n1) + n2 + diff], n2 - diff);
+ 341 + + }
+ 342 + + else
+ 343 + + {
+ 344 + + // shrink
+ 345 + + // copy all elements into place
+ 346 + +2 std::memmove(&curr_data[pos], &curr_data[offset], n2);
+ 347 + + // shift all elements after splice point left
+ 348 + +2 std::memmove(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
+ 349 + + }
+ 350 + + }
+ 351 + +12 size((curr_size - n1) + n2);
+ 352 + + }
+ 353 + + else
+ 354 + + {
+ 355 + +5 if (delta > max_size() - curr_size)
+ 356 + + {
+ 357 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 358 + +1 detail::throw_system_error( error::string_too_large, &loc );
+ 359 + + }
+ 360 + + // would exceed capacity, reallocate
+ 361 + +4 string_impl tmp(growth(
+ 362 + +4 curr_size + delta, capacity()), sp);
+ 363 + +2 tmp.size(curr_size + delta);
+ 364 + +2 std::memcpy(
+ 365 + +2 tmp.data(),
+ 366 + + curr_data,
+ 367 + + pos);
+ 368 + +4 std::memcpy(
+ 369 + +4 tmp.data() + pos + n2,
+ 370 + +2 curr_data + pos + n1,
+ 371 + +2 curr_size - pos - n1 + 1);
+ 372 + +4 std::memcpy(
+ 373 + +2 tmp.data() + pos,
+ 374 + + s,
+ 375 + + n2);
+ 376 + +2 destroy(sp);
+ 377 + +2 *this = tmp;
+ 378 + + }
+ 379 + + }
+ 380 + +
+ 381 + + // unlike the replace overload, this function does
+ 382 + + // not move any characters
+ 383 + + char*
+ 384 + +7 string_impl::
+ 385 + + replace_unchecked(
+ 386 + + std::size_t pos,
+ 387 + + std::size_t n1,
+ 388 + + std::size_t n2,
+ 389 + + storage_ptr const& sp)
+ 390 + + {
+ 391 + +7 const auto curr_size = size();
+ 392 + +7 if(pos > curr_size)
+ 393 + + {
+ 394 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 395 + +1 detail::throw_system_error( error::out_of_range, &loc );
+ 396 + + }
+ 397 + +6 const auto curr_data = data();
+ 398 + +6 const auto delta = (std::max)(n1, n2) -
+ 399 + +6 (std::min)(n1, n2);
+ 400 + + // if the size doesn't change, we don't need to
+ 401 + + // do anything
+ 402 + +6 if (!delta)
+ 403 + +1 return curr_data + pos;
+ 404 + + // if we are shrinking in size or we have enough
+ 405 + + // capacity, dont reallocate
+ 406 + +5 if(n1 > n2 || delta <= capacity() - curr_size)
+ 407 + + {
+ 408 + +2 auto const replace_pos = curr_data + pos;
+ 409 + +2 std::memmove(
+ 410 + +2 replace_pos + n2,
+ 411 + +2 replace_pos + n1,
+ 412 + +2 curr_size - pos - n1 + 1);
+ 413 + +2 size((curr_size - n1) + n2);
+ 414 + +2 return replace_pos;
+ 415 + + }
+ 416 + +3 if(delta > max_size() - curr_size)
+ 417 + + {
+ 418 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 419 + +1 detail::throw_system_error( error::string_too_large, &loc );
+ 420 + + }
+ 421 + + // would exceed capacity, reallocate
+ 422 + +2 string_impl tmp(growth(
+ 423 + +2 curr_size + delta, capacity()), sp);
+ 424 + +1 tmp.size(curr_size + delta);
+ 425 + +1 std::memcpy(
+ 426 + +1 tmp.data(),
+ 427 + + curr_data,
+ 428 + + pos);
+ 429 + +2 std::memcpy(
+ 430 + +2 tmp.data() + pos + n2,
+ 431 + +1 curr_data + pos + n1,
+ 432 + +1 curr_size - pos - n1 + 1);
+ 433 + +1 destroy(sp);
+ 434 + +1 *this = tmp;
+ 435 + +1 return data() + pos;
+ 436 + + }
+ 437 + +
+ 438 + + void
+ 439 + +7 string_impl::
+ 440 + + shrink_to_fit(
+ 441 + + storage_ptr const& sp) noexcept
+ 442 + + {
+ 443 + +7 if(s_.k == short_string_)
+ 444 + +3 return;
+ 445 + +4 auto const t = p_.t;
+ 446 + +4 if(t->size <= sbo_chars_)
+ 447 + + {
+ 448 + +2 s_.k = short_string_;
+ 449 + +4 std::memcpy(
+ 450 + +2 s_.buf, data(), t->size);
+ 451 + +2 s_.buf[sbo_chars_] =
+ 452 + + static_cast<char>(
+ 453 + +2 sbo_chars_ - t->size);
+ 454 + +2 s_.buf[t->size] = 0;
+ 455 + +2 sp->deallocate(t,
+ 456 + + sizeof(table) +
+ 457 + +2 t->capacity + 1,
+ 458 + + alignof(table));
+ 459 + +2 return;
+ 460 + + }
+ 461 + +2 if(t->size >= t->capacity)
+ 462 + + return;
+ 463 + + #ifndef BOOST_NO_EXCEPTIONS
+ 464 + + try
+ 465 + + {
+ 466 + + #endif
+ 467 + +2 string_impl tmp(t->size, sp);
+ 468 + +1 std::memcpy(
+ 469 + +1 tmp.data(),
+ 470 + +1 data(),
+ 471 + + size());
+ 472 + +1 destroy(sp);
+ 473 + +1 *this = tmp;
+ 474 + + #ifndef BOOST_NO_EXCEPTIONS
+ 475 + + }
+ 476 + +1 catch(std::exception const&)
+ 477 + + {
+ 478 + + // eat the exception
+ 479 + +1 }
+ 480 + + #endif
+ 481 + + }
+ 482 + +
+ 483 + + } // detail
+ 484 + + } // namespace json
+ 485 + + } // namespace boost
+ 486 + +
+ 487 + + #endif
+ 488 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.utf8.hpp.d18a20eb6345bd7b0b78784fd246f3ed.html b/json/gcovr/index.utf8.hpp.d18a20eb6345bd7b0b78784fd246f3ed.html new file mode 100644 index 00000000..2c95f09a --- /dev/null +++ b/json/gcovr/index.utf8.hpp.d18a20eb6345bd7b0b78784fd246f3ed.html @@ -0,0 +1,3670 @@ + + + + + + detail/utf8.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/utf8.hpp

+
+ + 100.0% Lines (62/62) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/utf8.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_UTF8_HPP
+ 11 + + #define BOOST_JSON_DETAIL_UTF8_HPP
+ 12 + +
+ 13 + + #include <boost/endian/conversion.hpp>
+ 14 + + #include <boost/json/detail/config.hpp>
+ 15 + +
+ 16 + + #include <cstddef>
+ 17 + + #include <cstring>
+ 18 + + #include <cstdint>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + + namespace detail {
+ 23 + +
+ 24 + + template<int N>
+ 25 + + std::uint32_t
+ 26 + +21733 load_little_endian(void const* p)
+ 27 + + {
+ 28 + +21733 std::uint32_t v = 0;
+ 29 + +21733 std::memcpy(&v, p, N);
+ 30 + +21733 endian::little_to_native_inplace(v);
+ 31 + +21733 return v;
+ 32 + + }
+ 33 + +
+ 34 + + inline
+ 35 + + uint16_t
+ 36 + +16690 classify_utf8(char c)
+ 37 + + {
+ 38 + + // 0x000 = invalid
+ 39 + + // 0x102 = 2 bytes, second byte [80, BF]
+ 40 + + // 0x203 = 3 bytes, second byte [A0, BF]
+ 41 + + // 0x303 = 3 bytes, second byte [80, BF]
+ 42 + + // 0x403 = 3 bytes, second byte [80, 9F]
+ 43 + + // 0x504 = 4 bytes, second byte [90, BF]
+ 44 + + // 0x604 = 4 bytes, second byte [80, BF]
+ 45 + + // 0x704 = 4 bytes, second byte [80, 8F]
+ 46 + + static constexpr uint16_t first[128]
+ 47 + + {
+ 48 + + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 49 + + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 50 + + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 51 + + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 52 + + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 53 + + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 54 + + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 55 + + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 56 + +
+ 57 + + 0x000, 0x000, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102,
+ 58 + + 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102,
+ 59 + + 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102,
+ 60 + + 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102,
+ 61 + + 0x203, 0x303, 0x303, 0x303, 0x303, 0x303, 0x303, 0x303,
+ 62 + + 0x303, 0x303, 0x303, 0x303, 0x303, 0x403, 0x303, 0x303,
+ 63 + + 0x504, 0x604, 0x604, 0x604, 0x704, 0x000, 0x000, 0x000,
+ 64 + + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 65 + + };
+ 66 + +16690 return first[static_cast<unsigned char>(c & 0x7F)];
+ 67 + + }
+ 68 + +
+ 69 + + inline
+ 70 + + bool
+ 71 + +13177 is_valid_utf8(const char* p, uint16_t first)
+ 72 + + {
+ 73 + + uint32_t v;
+ 74 + +13177 switch(first >> 8)
+ 75 + + {
+ 76 + +362 default:
+ 77 + +362 return false;
+ 78 + +
+ 79 + + // 2 bytes, second byte [80, BF]
+ 80 + +2348 case 1:
+ 81 + +2348 v = load_little_endian<2>(p);
+ 82 + +2348 return (v & 0xC000) == 0x8000;
+ 83 + +
+ 84 + + // 3 bytes, second byte [A0, BF]
+ 85 + +665 case 2:
+ 86 + +665 v = load_little_endian<3>(p);
+ 87 + +665 return (v & 0xC0E000) == 0x80A000;
+ 88 + +
+ 89 + + // 3 bytes, second byte [80, BF]
+ 90 + +3882 case 3:
+ 91 + +3882 v = load_little_endian<3>(p);
+ 92 + +3882 return (v & 0xC0C000) == 0x808000;
+ 93 + +
+ 94 + + // 3 bytes, second byte [80, 9F]
+ 95 + +725 case 4:
+ 96 + +725 v = load_little_endian<3>(p);
+ 97 + +725 return (v & 0xC0E000) == 0x808000;
+ 98 + +
+ 99 + + // 4 bytes, second byte [90, BF]
+ 100 + +1310 case 5:
+ 101 + +1310 v = load_little_endian<4>(p);
+ 102 + +1310 return (v & 0xC0C0FF00) + 0x7F7F7000 <= 0x2F00;
+ 103 + +
+ 104 + + // 4 bytes, second byte [80, BF]
+ 105 + +2346 case 6:
+ 106 + +2346 v = load_little_endian<4>(p);
+ 107 + +2346 return (v & 0xC0C0C000) == 0x80808000;
+ 108 + +
+ 109 + + // 4 bytes, second byte [80, 8F]
+ 110 + +1539 case 7:
+ 111 + +1539 v = load_little_endian<4>(p);
+ 112 + +1539 return (v & 0xC0C0F000) == 0x80808000;
+ 113 + + }
+ 114 + + }
+ 115 + +
+ 116 + + class utf8_sequence
+ 117 + + {
+ 118 + + char seq_[4];
+ 119 + + uint16_t first_;
+ 120 + + uint8_t size_;
+ 121 + +
+ 122 + + public:
+ 123 + + void
+ 124 + +3466 save(
+ 125 + + const char* p,
+ 126 + + std::size_t remain) noexcept
+ 127 + + {
+ 128 + +3466 first_ = classify_utf8(*p );
+ 129 + +3466 if(remain >= length())
+ 130 + +1560 size_ = length();
+ 131 + + else
+ 132 + +1906 size_ = static_cast<uint8_t>(remain);
+ 133 + +3466 std::memcpy(seq_, p, size_);
+ 134 + +3466 }
+ 135 + +
+ 136 + + uint8_t
+ 137 + +21338 length() const noexcept
+ 138 + + {
+ 139 + +21338 return first_ & 0xFF;
+ 140 + + }
+ 141 + +
+ 142 + + bool
+ 143 + +3469 complete() const noexcept
+ 144 + + {
+ 145 + +3469 return size_ >= length();
+ 146 + + }
+ 147 + +
+ 148 + + // returns true if complete
+ 149 + + bool
+ 150 + +1864 append(
+ 151 + + const char* p,
+ 152 + + std::size_t remain) noexcept
+ 153 + + {
+ 154 + +1864 if(BOOST_JSON_UNLIKELY(needed() == 0))
+ 155 + +1 return true;
+ 156 + +1863 if(BOOST_JSON_LIKELY(remain >= needed()))
+ 157 + + {
+ 158 + +1862 std::memcpy(
+ 159 + +1862 seq_ + size_, p, needed());
+ 160 + +1862 size_ = length();
+ 161 + +1862 return true;
+ 162 + + }
+ 163 + +1 if(BOOST_JSON_LIKELY(remain > 0))
+ 164 + + {
+ 165 + +1 std::memcpy(seq_ + size_, p, remain);
+ 166 + +1 size_ += static_cast<uint8_t>(remain);
+ 167 + + }
+ 168 + +1 return false;
+ 169 + + }
+ 170 + +
+ 171 + + const char*
+ 172 + +1658 data() const noexcept
+ 173 + + {
+ 174 + +1658 return seq_;
+ 175 + + }
+ 176 + +
+ 177 + + uint8_t
+ 178 + +7457 needed() const noexcept
+ 179 + + {
+ 180 + +7457 return length() - size_;
+ 181 + + }
+ 182 + +
+ 183 + + bool
+ 184 + +1866 valid() const noexcept
+ 185 + + {
+ 186 + +1866 BOOST_ASSERT(size_ >= length());
+ 187 + +1866 return is_valid_utf8(seq_, first_);
+ 188 + + }
+ 189 + + };
+ 190 + +
+ 191 + + } // detail
+ 192 + + } // namespace json
+ 193 + + } // namespace boost
+ 194 + +
+ 195 + + #endif
+ 196 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value.hpp.08b63e532c8156eaeb5cccaa7944e074.html b/json/gcovr/index.value.hpp.08b63e532c8156eaeb5cccaa7944e074.html new file mode 100644 index 00000000..26131eaa --- /dev/null +++ b/json/gcovr/index.value.hpp.08b63e532c8156eaeb5cccaa7944e074.html @@ -0,0 +1,4382 @@ + + + + + + detail/value.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/value.hpp

+
+ + 100.0% Lines (61/61) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/value.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_DETAIL_VALUE_HPP
+ 11 + + #define BOOST_JSON_DETAIL_VALUE_HPP
+ 12 + +
+ 13 + + #include <boost/json/fwd.hpp>
+ 14 + + #include <boost/json/kind.hpp>
+ 15 + + #include <boost/json/storage_ptr.hpp>
+ 16 + + #include <cstdint>
+ 17 + + #include <limits>
+ 18 + + #include <new>
+ 19 + + #include <utility>
+ 20 + +
+ 21 + + namespace boost {
+ 22 + + namespace json {
+ 23 + + namespace detail {
+ 24 + +
+ 25 + + struct key_t
+ 26 + + {
+ 27 + + };
+ 28 + +
+ 29 + + #if 0
+ 30 + + template<class T>
+ 31 + + struct to_number_limit
+ 32 + + : std::numeric_limits<T>
+ 33 + + {
+ 34 + + };
+ 35 + +
+ 36 + + template<class T>
+ 37 + + struct to_number_limit<T const>
+ 38 + + : to_number_limit<T>
+ 39 + + {
+ 40 + + };
+ 41 + +
+ 42 + + template<>
+ 43 + + struct to_number_limit<long long>
+ 44 + + {
+ 45 + + static constexpr long long (min)() noexcept
+ 46 + + {
+ 47 + + return -9223372036854774784;
+ 48 + + }
+ 49 + +
+ 50 + + static constexpr long long (max)() noexcept
+ 51 + + {
+ 52 + + return 9223372036854774784;
+ 53 + + }
+ 54 + + };
+ 55 + +
+ 56 + + template<>
+ 57 + + struct to_number_limit<unsigned long long>
+ 58 + + {
+ 59 + + static constexpr
+ 60 + + unsigned long long (min)() noexcept
+ 61 + + {
+ 62 + + return 0;
+ 63 + + }
+ 64 + +
+ 65 + + static constexpr
+ 66 + + unsigned long long (max)() noexcept
+ 67 + + {
+ 68 + + return 18446744073709549568ULL;
+ 69 + + }
+ 70 + + };
+ 71 + + #else
+ 72 + +
+ 73 + + template<class T>
+ 74 + + class to_number_limit
+ 75 + + {
+ 76 + + // unsigned
+ 77 + +
+ 78 + + static constexpr
+ 79 + + double min1(std::false_type)
+ 80 + + {
+ 81 + + return 0.0;
+ 82 + + }
+ 83 + +
+ 84 + + static constexpr
+ 85 + +8 double max1(std::false_type)
+ 86 + + {
+ 87 + +8 return max2u(std::integral_constant<
+ 88 + + bool, (std::numeric_limits<T>::max)() ==
+ 89 + +8 UINT64_MAX>{});
+ 90 + + }
+ 91 + +
+ 92 + + static constexpr
+ 93 + +6 double max2u(std::false_type)
+ 94 + + {
+ 95 + + return static_cast<double>(
+ 96 + +6 (std::numeric_limits<T>::max)());
+ 97 + + }
+ 98 + +
+ 99 + + static constexpr
+ 100 + +2 double max2u(std::true_type)
+ 101 + + {
+ 102 + +2 return 18446744073709549568.0;
+ 103 + + }
+ 104 + +
+ 105 + + // signed
+ 106 + +
+ 107 + + static constexpr
+ 108 + +20 double min1(std::true_type)
+ 109 + + {
+ 110 + +20 return min2s(std::integral_constant<
+ 111 + + bool, (std::numeric_limits<T>::max)() ==
+ 112 + +20 INT64_MAX>{});
+ 113 + + }
+ 114 + +
+ 115 + + static constexpr
+ 116 + +17 double min2s(std::false_type)
+ 117 + + {
+ 118 + + return static_cast<double>(
+ 119 + +17 (std::numeric_limits<T>::min)());
+ 120 + + }
+ 121 + +
+ 122 + + static constexpr
+ 123 + +3 double min2s(std::true_type)
+ 124 + + {
+ 125 + +3 return -9223372036854774784.0;
+ 126 + + }
+ 127 + +
+ 128 + + static constexpr
+ 129 + +20 double max1(std::true_type)
+ 130 + + {
+ 131 + +20 return max2s(std::integral_constant<
+ 132 + + bool, (std::numeric_limits<T>::max)() ==
+ 133 + +20 INT64_MAX>{});
+ 134 + + }
+ 135 + +
+ 136 + + static constexpr
+ 137 + +17 double max2s(std::false_type)
+ 138 + + {
+ 139 + + return static_cast<double>(
+ 140 + +17 (std::numeric_limits<T>::max)());
+ 141 + + }
+ 142 + +
+ 143 + + static constexpr
+ 144 + +3 double max2s(std::true_type)
+ 145 + + {
+ 146 + +3 return 9223372036854774784.0;
+ 147 + + }
+ 148 + +
+ 149 + + public:
+ 150 + + static constexpr
+ 151 + +20 double (min)() noexcept
+ 152 + + {
+ 153 + +20 return min1(std::is_signed<T>{});
+ 154 + + }
+ 155 + +
+ 156 + + static constexpr
+ 157 + +28 double (max)() noexcept
+ 158 + + {
+ 159 + +28 return max1(std::is_signed<T>{});
+ 160 + + }
+ 161 + + };
+ 162 + +
+ 163 + + #endif
+ 164 + +
+ 165 + + struct scalar
+ 166 + + {
+ 167 + + storage_ptr sp; // must come first
+ 168 + + kind k; // must come second
+ 169 + + union
+ 170 + + {
+ 171 + + bool b;
+ 172 + + std::int64_t i;
+ 173 + + std::uint64_t u;
+ 174 + + double d;
+ 175 + + };
+ 176 + +
+ 177 + + explicit
+ 178 + +2151977 scalar(storage_ptr sp_ = {}) noexcept
+ 179 + +2151977 : sp(std::move(sp_))
+ 180 + +2151977 , k(json::kind::null)
+ 181 + + {
+ 182 + +2151977 }
+ 183 + +
+ 184 + + explicit
+ 185 + +1085 scalar(bool b_,
+ 186 + + storage_ptr sp_ = {}) noexcept
+ 187 + +1085 : sp(std::move(sp_))
+ 188 + +1085 , k(json::kind::bool_)
+ 189 + +1085 , b(b_)
+ 190 + + {
+ 191 + +1085 }
+ 192 + +
+ 193 + + explicit
+ 194 + +34532 scalar(std::int64_t i_,
+ 195 + + storage_ptr sp_ = {}) noexcept
+ 196 + +34532 : sp(std::move(sp_))
+ 197 + +34532 , k(json::kind::int64)
+ 198 + +34532 , i(i_)
+ 199 + + {
+ 200 + +34532 }
+ 201 + +
+ 202 + + explicit
+ 203 + +406 scalar(std::uint64_t u_,
+ 204 + + storage_ptr sp_ = {}) noexcept
+ 205 + +406 : sp(std::move(sp_))
+ 206 + +406 , k(json::kind::uint64)
+ 207 + +406 , u(u_)
+ 208 + + {
+ 209 + +406 }
+ 210 + +
+ 211 + + explicit
+ 212 + +2040002 scalar(double d_,
+ 213 + + storage_ptr sp_ = {}) noexcept
+ 214 + +2040002 : sp(std::move(sp_))
+ 215 + +2040002 , k(json::kind::double_)
+ 216 + +2040002 , d(d_)
+ 217 + + {
+ 218 + +2040002 }
+ 219 + + };
+ 220 + +
+ 221 + + struct access
+ 222 + + {
+ 223 + + template<class Value, class... Args>
+ 224 + + static
+ 225 + + Value&
+ 226 + +2156934 construct_value(Value* p, Args&&... args)
+ 227 + + {
+ 228 + + return *reinterpret_cast<
+ 229 + +6396945 Value*>(::new(p) Value(
+ 230 + +6489244 std::forward<Args>(args)...));
+ 231 + + }
+ 232 + +
+ 233 + + template<class KeyValuePair, class... Args>
+ 234 + + static
+ 235 + + KeyValuePair&
+ 236 + +38150 construct_key_value_pair(
+ 237 + + KeyValuePair* p, Args&&... args)
+ 238 + + {
+ 239 + + return *reinterpret_cast<
+ 240 + +38150 KeyValuePair*>(::new(p)
+ 241 + + KeyValuePair(
+ 242 + +76300 std::forward<Args>(args)...));
+ 243 + + }
+ 244 + +
+ 245 + + template<class Value>
+ 246 + + static
+ 247 + + char const*
+ 248 + +38150 release_key(
+ 249 + + Value& jv,
+ 250 + + std::size_t& len) noexcept
+ 251 + + {
+ 252 + +38150 BOOST_ASSERT(jv.is_string());
+ 253 + +38150 jv.str_.sp_.~storage_ptr();
+ 254 + +38150 return jv.str_.impl_.release_key(len);
+ 255 + + }
+ 256 + +
+ 257 + + using index_t = std::uint32_t;
+ 258 + +
+ 259 + + template<class KeyValuePair>
+ 260 + + static
+ 261 + + index_t&
+ 262 + +10521 next(KeyValuePair& e) noexcept
+ 263 + + {
+ 264 + +10521 return e.next_;
+ 265 + + }
+ 266 + +
+ 267 + + template<class KeyValuePair>
+ 268 + + static
+ 269 + + index_t const&
+ 270 + + next(KeyValuePair const& e) noexcept
+ 271 + + {
+ 272 + + return e.next_;
+ 273 + + }
+ 274 + + };
+ 275 + +
+ 276 + + BOOST_JSON_DECL
+ 277 + + std::size_t
+ 278 + + hash_value_impl( value const& jv ) noexcept;
+ 279 + +
+ 280 + + } // detail
+ 281 + + } // namespace json
+ 282 + + } // namespace boost
+ 283 + +
+ 284 + + #endif
+ 285 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value.hpp.4e464561aa627034092b7a363639d5b7.html b/json/gcovr/index.value.hpp.4e464561aa627034092b7a363639d5b7.html new file mode 100644 index 00000000..8aa1d751 --- /dev/null +++ b/json/gcovr/index.value.hpp.4e464561aa627034092b7a363639d5b7.html @@ -0,0 +1,32702 @@ + + + + + + value.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

value.hpp

+
+ + 98.9% Lines (516/522) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
value.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + //
+ 5 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 6 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 7 + + //
+ 8 + + // Official repository: https://github.com/boostorg/json
+ 9 + + //
+ 10 + +
+ 11 + + #ifndef BOOST_JSON_VALUE_HPP
+ 12 + + #define BOOST_JSON_VALUE_HPP
+ 13 + +
+ 14 + + #include <boost/core/detail/static_assert.hpp>
+ 15 + + #include <boost/json/detail/config.hpp>
+ 16 + + #include <boost/json/array.hpp>
+ 17 + + #include <boost/json/kind.hpp>
+ 18 + + #include <boost/json/object.hpp>
+ 19 + + #include <boost/json/pilfer.hpp>
+ 20 + + #include <boost/json/set_pointer_options.hpp>
+ 21 + + #include <boost/json/storage_ptr.hpp>
+ 22 + + #include <boost/json/string.hpp>
+ 23 + + #include <boost/json/string_view.hpp>
+ 24 + + #include <boost/json/value_ref.hpp>
+ 25 + + #include <boost/json/detail/except.hpp>
+ 26 + + #include <boost/json/detail/value.hpp>
+ 27 + + #include <cstdlib>
+ 28 + + #include <cstring>
+ 29 + + #include <initializer_list>
+ 30 + + #include <iosfwd>
+ 31 + + #include <limits>
+ 32 + + #include <new>
+ 33 + + #include <type_traits>
+ 34 + + #include <utility>
+ 35 + +
+ 36 + + namespace boost {
+ 37 + + namespace json {
+ 38 + +
+ 39 + + //----------------------------------------------------------
+ 40 + +
+ 41 + + /** The type used to represent any JSON value
+ 42 + +
+ 43 + + This is a [Regular](https://en.cppreference.com/w/cpp/concepts/regular)
+ 44 + + type which works like a variant of the basic JSON data types: array,
+ 45 + + object, string, number, boolean, and null.
+ 46 + +
+ 47 + + @par Thread Safety
+ 48 + + Distinct instances may be accessed concurrently. Non-const member
+ 49 + + functions of a shared instance may not be called concurrently with any
+ 50 + + other member functions of that instance.
+ 51 + + */
+ 52 + + class value
+ 53 + + {
+ 54 + + #ifndef BOOST_JSON_DOCS
+ 55 + + using scalar = detail::scalar;
+ 56 + +
+ 57 + + union
+ 58 + + {
+ 59 + + storage_ptr sp_; // must come first
+ 60 + + array arr_;
+ 61 + + object obj_;
+ 62 + + string str_;
+ 63 + + scalar sca_;
+ 64 + + };
+ 65 + + #endif
+ 66 + +
+ 67 + + struct init_iter;
+ 68 + +
+ 69 + + #ifndef BOOST_JSON_DOCS
+ 70 + + // VFALCO doc toolchain incorrectly treats this as public
+ 71 + + friend struct detail::access;
+ 72 + + #endif
+ 73 + +
+ 74 + + explicit
+ 75 + +2120 value(
+ 76 + + detail::unchecked_array&& ua)
+ 77 + +2120 : arr_(std::move(ua))
+ 78 + + {
+ 79 + +2082 }
+ 80 + +
+ 81 + + explicit
+ 82 + +34879 value(
+ 83 + + detail::unchecked_object&& uo)
+ 84 + +34879 : obj_(std::move(uo))
+ 85 + + {
+ 86 + +34840 }
+ 87 + +
+ 88 + +30296 value(
+ 89 + + detail::key_t const&,
+ 90 + + string_view s,
+ 91 + + storage_ptr sp)
+ 92 + +30296 : str_(detail::key_t{}, s, std::move(sp))
+ 93 + + {
+ 94 + +30236 }
+ 95 + +
+ 96 + +8060 value(
+ 97 + + detail::key_t const&,
+ 98 + + string_view s1,
+ 99 + + string_view s2,
+ 100 + + storage_ptr sp)
+ 101 + +8060 : str_(detail::key_t{}, s1, s2, std::move(sp))
+ 102 + + {
+ 103 + +8060 }
+ 104 + +
+ 105 + +6696 inline bool is_scalar() const noexcept
+ 106 + + {
+ 107 + +6696 return sca_.k < json::kind::string;
+ 108 + + }
+ 109 + +
+ 110 + + public:
+ 111 + + /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
+ 112 + + using allocator_type = container::pmr::polymorphic_allocator<value>;
+ 113 + +
+ 114 + + /** Destructor.
+ 115 + +
+ 116 + + The value and all of its contents are destroyed. Any dynamically
+ 117 + + allocated memory that was allocated internally is freed.
+ 118 + +
+ 119 + + @par Complexity
+ 120 + + Constant, or linear in size for array or object.
+ 121 + +
+ 122 + + @par Exception Safety
+ 123 + + No-throw guarantee.
+ 124 + + */
+ 125 + + BOOST_JSON_DECL
+ 126 + + ~value() noexcept;
+ 127 + +
+ 128 + + /** Constructors.
+ 129 + +
+ 130 + + Construct a new `value`.
+ 131 + +
+ 132 + + @li **(1)**--**(3)** the constructed value is null.
+ 133 + + @li **(4)** the constructed value contains a copy of `b`.
+ 134 + + @li **(5)**--**(9)** the constructed value contains a copy of `i`.
+ 135 + + @li **(10)**--**(14)** the constructed value contains a copy of `u`.
+ 136 + + @li **(15)** the constructed value contains a copy of `d`.
+ 137 + + @li **(16)**, **(19)** the constructed value contains a copy of the
+ 138 + + string `s`.
+ 139 + + @li **(17)** the constructed value contains a copy of the
+ 140 + + null-terminated string `s`.
+ 141 + + @li **(18)** the constructed value takes ownership of `s`'s storage.
+ 142 + + @li **(20)** if `*s.storage() == *sp` equivalent to **(18)**, otherwise
+ 143 + + equivalent to **(19)**.
+ 144 + + @li **(21)** the constructed value contains an empty string.
+ 145 + + @li **(22)** the constructed value takes ownership of `arr`'s storage.
+ 146 + + @li **(23)** the constructed value contains an element-wise copy of the
+ 147 + + array `arr`.
+ 148 + + @li **(24)** if `*arr.storage() == *sp` equivalent to **(22)**,
+ 149 + + otherwise equivalent to **(23)**.
+ 150 + + @li **(25)** the constructed value contains an empty array.
+ 151 + + @li **(26)** the constructed value takes ownership of `obj`'s storage.
+ 152 + + @li **(27)** the constructed value contains an element-wise copy of the
+ 153 + + object `obj`.
+ 154 + + @li **(28)** if `*obj.storage() == *sp` equivalent to **(26)**,
+ 155 + + otherwise equivalent to **(27)**.
+ 156 + + @li **(29)** the constructed value contains an empty object.
+ 157 + + @li **(30)** the constructed value's contents are formed by
+ 158 + + constructing from `init` and `sp` (see \<\<initializer_lists\>\>).
+ 159 + + @li **(31)**, **(32)** the constructed value contains a copy of the
+ 160 + + contents of `other`.
+ 161 + + @li **(33)** the constructed value acquires ownership of the contents
+ 162 + + of `other`.
+ 163 + + @li **(34)** equivalent to **(33)** if `*sp == *other.storage()`;
+ 164 + + otherwise equivalent to **(32)**.
+ 165 + + @li **(35)** the constructed value acquires ownership of the contents
+ 166 + + of `other` using pilfer semantics. This is more efficient than move
+ 167 + + construction, when it is known that the moved-from object will be
+ 168 + + immediately destroyed afterwards.
+ 169 + +
+ 170 + + With **(2)**--**(17)**, **(19)**--**(21)**, **(23)**--**(25)**,
+ 171 + + {sp} **(27)**--**(30)**, **(32)**, and **(34)** the constructed value
+ 172 + + uses memory resource of `sp`. With **(18)**, **(22)**, **(26)**,
+ 173 + + {sp} **(31)**, **(33)**, and **(35)** it uses the memory resource of
+ 174 + + the argument (`s`, `arr`, obj`, or `value`). In either case the value
+ 175 + + will share the ownership of the memory resource. With **(1)**
+ 176 + + it uses the \<\<default_memory_resource, default memory resource\>\>.
+ 177 + +
+ 178 + + After **(18)**, **(22)**, **(26)**, and **(33)** the argument behaves
+ 179 + + as if newly constructed with its current storage pointer (i.e. becomes
+ 180 + + an empty string, array, object, or null value).
+ 181 + +
+ 182 + + After **(35)** `other` is not in a usable state and may only be
+ 183 + + destroyed.
+ 184 + +
+ 185 + + @par Complexity
+ 186 + + @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
+ 187 + + {sp} **(26)**, **(29)**, **(33)**, **(35)** constant.
+ 188 + + @li **(16)**, **(19)** linear in `s.size()`.
+ 189 + + @li **(17)** linear in `std::strlen(s)`.
+ 190 + + @li **(20)** if `*s.storage() == *sp` constant, otherwise linear
+ 191 + + in `s.size()`.
+ 192 + + @li **(23)** linear in `arr.size()`.
+ 193 + + @li **(24)** if `*arr.storage() == *sp` constant, otherwise linear
+ 194 + + in `arr.size()`.
+ 195 + + @li **(27)** linear in `obj.size()`.
+ 196 + + @li **(28)** if `*obj.storage() == *sp` constant, otherwise linear
+ 197 + + in `obj.size()`.
+ 198 + + @li **(30)** linear in `init.size()`.
+ 199 + + @li **(31)**, **(32)** linear in the size of `other`.
+ 200 + + @li **(34)** constant if `*sp == *other.storage()`; otherwise linear in
+ 201 + + the size of `other`.
+ 202 + +
+ 203 + + The size of `other` is either the size of the underlying container
+ 204 + + (if there is one), or can be considered to be 1.
+ 205 + +
+ 206 + + @par Exception Safety
+ 207 + + @li **(1)**--**(15)**, **(18)**, **(21)**, **(22)**, **(25)**,
+ 208 + + **(26)**, **(29)**, **(33)**, **(35)** no-throw guarantee.
+ 209 + + @li **(16)**, **(17)**, **(19)**, **(23)**, **(27)**,
+ 210 + + **(30)**--**(32)** strong guarantee.
+ 211 + + @li **(20)** if `*s.storage() == *sp` no-throw guarantee, otherwise
+ 212 + + strong guarantee.
+ 213 + + @li **(24)** if `*arr.storage() == *sp` no-throw guarantee, otherwise
+ 214 + + strong guarantee.
+ 215 + + @li **(28)** if `*obj.storage() == *sp` no-throw guarantee, otherwise
+ 216 + + strong guarantee.
+ 217 + + @li **(33)** if `*other.storage() == *sp` no-throw guarantee, otherwise
+ 218 + + strong guarantee.
+ 219 + +
+ 220 + + Calls to `memory_resource::allocate` may throw.
+ 221 + +
+ 222 + + @see @ref pilfer,
+ 223 + + [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
+ 224 + + //
+ 225 + + @{
+ 226 + + */
+ 227 + +207 value() noexcept
+ 228 + +207 : sca_()
+ 229 + + {
+ 230 + +207 }
+ 231 + +
+ 232 + + /** Overload
+ 233 + +
+ 234 + + @param sp A pointer to the @ref boost::container::pmr::memory_resource
+ 235 + + to use.
+ 236 + + */
+ 237 + + explicit
+ 238 + +7052 value(storage_ptr sp) noexcept
+ 239 + +7052 : sca_(std::move(sp))
+ 240 + + {
+ 241 + +7052 }
+ 242 + +
+ 243 + + /// Overload
+ 244 + +9679 value(
+ 245 + + std::nullptr_t,
+ 246 + + storage_ptr sp = {}) noexcept
+ 247 + +9679 : sca_(std::move(sp))
+ 248 + + {
+ 249 + +9679 }
+ 250 + +
+ 251 + + /** Overload
+ 252 + +
+ 253 + + @param b The boolean to construct with.
+ 254 + + @param sp
+ 255 + + */
+ 256 + + #ifdef BOOST_JSON_DOCS
+ 257 + + value(
+ 258 + + bool b,
+ 259 + + storage_ptr sp = {}) noexcept;
+ 260 + + #else
+ 261 + + template<class T
+ 262 + + ,class = typename std::enable_if<
+ 263 + + std::is_same<T, bool>::value>::type
+ 264 + + >
+ 265 + +774 value(
+ 266 + + T b,
+ 267 + + storage_ptr sp = {}) noexcept
+ 268 + +774 : sca_(b, std::move(sp))
+ 269 + + {
+ 270 + +774 }
+ 271 + + #endif
+ 272 + +
+ 273 + + /** Overload
+ 274 + +
+ 275 + + @param i The number to construct with.
+ 276 + + @param sp
+ 277 + + */
+ 278 + +3 value(
+ 279 + + signed char i,
+ 280 + + storage_ptr sp = {}) noexcept
+ 281 + +3 : sca_(static_cast<std::int64_t>(
+ 282 + +3 i), std::move(sp))
+ 283 + + {
+ 284 + +3 }
+ 285 + +
+ 286 + + /// Overload
+ 287 + +4 value(
+ 288 + + short i,
+ 289 + + storage_ptr sp = {}) noexcept
+ 290 + +4 : sca_(static_cast<std::int64_t>(
+ 291 + +4 i), std::move(sp))
+ 292 + + {
+ 293 + +4 }
+ 294 + +
+ 295 + + /// Overload
+ 296 + +11257 value(
+ 297 + + int i,
+ 298 + + storage_ptr sp = {}) noexcept
+ 299 + +11257 : sca_(static_cast<std::int64_t>(i),
+ 300 + +11257 std::move(sp))
+ 301 + + {
+ 302 + +11257 }
+ 303 + +
+ 304 + + /// Overload
+ 305 + +5834 value(
+ 306 + + long i,
+ 307 + + storage_ptr sp = {}) noexcept
+ 308 + +5834 : sca_(static_cast<std::int64_t>(i),
+ 309 + +5834 std::move(sp))
+ 310 + + {
+ 311 + +5834 }
+ 312 + +
+ 313 + + /// Overload
+ 314 + +3 value(
+ 315 + + long long i,
+ 316 + + storage_ptr sp = {}) noexcept
+ 317 + +3 : sca_(static_cast<std::int64_t>(i),
+ 318 + +3 std::move(sp))
+ 319 + + {
+ 320 + +3 }
+ 321 + +
+ 322 + + /** Overload
+ 323 + +
+ 324 + + @param u The number to construct with.
+ 325 + + @param sp
+ 326 + + */
+ 327 + +23 value(
+ 328 + + unsigned char u,
+ 329 + + storage_ptr sp = {}) noexcept
+ 330 + +23 : sca_(static_cast<std::uint64_t>(
+ 331 + +23 u), std::move(sp))
+ 332 + + {
+ 333 + +23 }
+ 334 + +
+ 335 + + /// Overload
+ 336 + +3 value(
+ 337 + + unsigned short u,
+ 338 + + storage_ptr sp = {}) noexcept
+ 339 + +3 : sca_(static_cast<std::uint64_t>(u),
+ 340 + +3 std::move(sp))
+ 341 + + {
+ 342 + +3 }
+ 343 + +
+ 344 + + /// Overload
+ 345 + +52 value(
+ 346 + + unsigned int u,
+ 347 + + storage_ptr sp = {}) noexcept
+ 348 + +52 : sca_(static_cast<std::uint64_t>(u),
+ 349 + +52 std::move(sp))
+ 350 + + {
+ 351 + +52 }
+ 352 + +
+ 353 + + /// Overload
+ 354 + +215 value(
+ 355 + + unsigned long u,
+ 356 + + storage_ptr sp = {}) noexcept
+ 357 + +215 : sca_(static_cast<std::uint64_t>(u),
+ 358 + +215 std::move(sp))
+ 359 + + {
+ 360 + +215 }
+ 361 + +
+ 362 + + /// Overload
+ 363 + +2 value(
+ 364 + + unsigned long long u,
+ 365 + + storage_ptr sp = {}) noexcept
+ 366 + +2 : sca_(static_cast<std::uint64_t>(u),
+ 367 + +2 std::move(sp))
+ 368 + + {
+ 369 + +2 }
+ 370 + +
+ 371 + + /** Overload
+ 372 + +
+ 373 + + @param d The number to construct with.
+ 374 + + @param sp
+ 375 + + */
+ 376 + +2039949 value(
+ 377 + + double d,
+ 378 + + storage_ptr sp = {}) noexcept
+ 379 + +2039949 : sca_(d, std::move(sp))
+ 380 + + {
+ 381 + +2039949 }
+ 382 + +
+ 383 + + /** Overload
+ 384 + +
+ 385 + + @param s The string to construct with.
+ 386 + + @param sp
+ 387 + + */
+ 388 + +17178 value(
+ 389 + + string_view s,
+ 390 + + storage_ptr sp = {})
+ 391 + +17178 : str_(s, std::move(sp))
+ 392 + + {
+ 393 + +17170 }
+ 394 + +
+ 395 + + /// Overload
+ 396 + +134 value(
+ 397 + + char const* s,
+ 398 + + storage_ptr sp = {})
+ 399 + +134 : str_(s, std::move(sp))
+ 400 + + {
+ 401 + +134 }
+ 402 + +
+ 403 + + /// Overload
+ 404 + +399 value(
+ 405 + + string s) noexcept
+ 406 + +399 : str_(std::move(s))
+ 407 + + {
+ 408 + +399 }
+ 409 + +
+ 410 + + /// Overload
+ 411 + +12 value(
+ 412 + + string const& s,
+ 413 + + storage_ptr sp)
+ 414 + +12 : str_(
+ 415 + + s,
+ 416 + +12 std::move(sp))
+ 417 + + {
+ 418 + +12 }
+ 419 + +
+ 420 + + /// Overload
+ 421 + +9 value(
+ 422 + + string&& s,
+ 423 + + storage_ptr sp)
+ 424 + +18 : str_(
+ 425 + +9 std::move(s),
+ 426 + +9 std::move(sp))
+ 427 + + {
+ 428 + +9 }
+ 429 + +
+ 430 + + /// Overload
+ 431 + +8977 value(
+ 432 + + string_kind_t,
+ 433 + + storage_ptr sp = {}) noexcept
+ 434 + +8977 : str_(std::move(sp))
+ 435 + + {
+ 436 + +8977 }
+ 437 + +
+ 438 + + /** Overload
+ 439 + +
+ 440 + + @param arr The array to construct with.
+ 441 + + */
+ 442 + +180 value(array arr) noexcept
+ 443 + +180 : arr_(std::move(arr))
+ 444 + + {
+ 445 + +180 }
+ 446 + +
+ 447 + + /// Overload
+ 448 + +4 value(
+ 449 + + array const& arr,
+ 450 + + storage_ptr sp)
+ 451 + +4 : arr_(
+ 452 + + arr,
+ 453 + +4 std::move(sp))
+ 454 + + {
+ 455 + +4 }
+ 456 + +
+ 457 + + /// Overload
+ 458 + +23 value(
+ 459 + + array&& arr,
+ 460 + + storage_ptr sp)
+ 461 + +46 : arr_(
+ 462 + +23 std::move(arr),
+ 463 + +23 std::move(sp))
+ 464 + + {
+ 465 + +23 }
+ 466 + +
+ 467 + + /// Overload
+ 468 + +17 value(
+ 469 + + array_kind_t,
+ 470 + + storage_ptr sp = {}) noexcept
+ 471 + +17 : arr_(std::move(sp))
+ 472 + + {
+ 473 + +17 }
+ 474 + +
+ 475 + + /** Overload
+ 476 + +
+ 477 + + @param obj The object to construct with.
+ 478 + + */
+ 479 + +61 value(object obj) noexcept
+ 480 + +61 : obj_(std::move(obj))
+ 481 + + {
+ 482 + +61 }
+ 483 + +
+ 484 + + /// Overload
+ 485 + +4 value(
+ 486 + + object const& obj,
+ 487 + + storage_ptr sp)
+ 488 + +4 : obj_( obj, std::move(sp) )
+ 489 + + {
+ 490 + +4 }
+ 491 + +
+ 492 + + /// Overload
+ 493 + +57 value(
+ 494 + + object&& obj,
+ 495 + + storage_ptr sp)
+ 496 + +57 : obj_( std::move(obj), std::move(sp) )
+ 497 + + {
+ 498 + +57 }
+ 499 + +
+ 500 + + /// Overload
+ 501 + +18 value(
+ 502 + + object_kind_t,
+ 503 + + storage_ptr sp = {}) noexcept
+ 504 + +18 : obj_(std::move(sp))
+ 505 + + {
+ 506 + +18 }
+ 507 + +
+ 508 + + /** Overload
+ 509 + +
+ 510 + + @param init The initializer list to construct from.
+ 511 + + @param sp
+ 512 + + */
+ 513 + + BOOST_JSON_DECL
+ 514 + + value(
+ 515 + + std::initializer_list<value_ref> init,
+ 516 + + storage_ptr sp = {});
+ 517 + +
+ 518 + + /** Overload
+ 519 + +
+ 520 + + @param other Another `value`.
+ 521 + + */
+ 522 + +19 value(value const& other)
+ 523 + +19 : value(other, other.storage())
+ 524 + + {
+ 525 + +19 }
+ 526 + +
+ 527 + + /// Overload
+ 528 + + BOOST_JSON_DECL
+ 529 + + value(
+ 530 + + value const& other,
+ 531 + + storage_ptr sp);
+ 532 + +
+ 533 + + /// Overload
+ 534 + + BOOST_JSON_DECL
+ 535 + + value(value&& other) noexcept;
+ 536 + +
+ 537 + + /// Overload
+ 538 + + BOOST_JSON_DECL
+ 539 + + value(
+ 540 + + value&& other,
+ 541 + + storage_ptr sp);
+ 542 + +
+ 543 + + /// Overload
+ 544 + +2129126 value(pilfered<value> other) noexcept
+ 545 + +2129126 {
+ 546 + +2129126 relocate(this, other.get());
+ 547 + +2129126 ::new(&other.get().sca_) scalar();
+ 548 + +2129126 }
+ 549 + + /// @}
+ 550 + +
+ 551 + + //------------------------------------------------------
+ 552 + + //
+ 553 + + // Assignment
+ 554 + + //
+ 555 + + //------------------------------------------------------
+ 556 + +
+ 557 + + /** Assignment.
+ 558 + +
+ 559 + + Replaces the contents of this value.
+ 560 + +
+ 561 + + @li **(1)** replaces with an element-wise copy of the contents of
+ 562 + + `other`.
+ 563 + + @li **(2)** replaces with the contents `other` using move semantics
+ 564 + + (see below).
+ 565 + + @li **(3)** replaces with the value formed by constructing from `init`
+ 566 + + and `this->storage()` (see \<\<initializer_lists\>\>).
+ 567 + + @li **(4)** replaces with null.
+ 568 + + @li **(5)** replaces with the boolean value `b`.
+ 569 + + @li **(6)**--**(10)** replaces with the signed integer `i`.
+ 570 + + @li **(11)**--**(15)** replaces with the unsigned integer `u`.
+ 571 + + @li **(16)** replaces with the number `d`.
+ 572 + + @li **(17)**, **(19)** replaces with a copy of the string `s`.
+ 573 + + @li **(18)**, equivalent to `*this = string_view(s)`.
+ 574 + + @li **(20)** replaces with the string `s` using move semantics
+ 575 + + see below.
+ 576 + + @li **(21)** replaces with a copy of the array `arr`.
+ 577 + + @li **(22)** replaces with the array `arr` using move semantics
+ 578 + + (see below).
+ 579 + + @li **(23)** replaces with a copy of the object `obj`.
+ 580 + + @li **(24)** replaces with the object `obj` using move semantics
+ 581 + + (see below).
+ 582 + +
+ 583 + + Move assignment for `value` never changes the associated memory
+ 584 + + resource. Because of this if the memory resource of the assigned value
+ 585 + + differs from that of `*this`, the operation is equivalent to a copy.
+ 586 + + Otherwise, it replaces the underlying storage in constant time without
+ 587 + + the possibility of exceptions.
+ 588 + +
+ 589 + + @par Complexity
+ 590 + + @li **(1)** linear in the sizes of `*this` and `other`.
+ 591 + + @li **(2)** constant if `*this->storage() == *other.storage()`,
+ 592 + + otherwise linear in the sizes of `*this` and `other`.
+ 593 + + @li **(3)** linear in the sizes of `*this` and `init`.
+ 594 + + @li **(4)**--**(16)** linear in the size of `*this`.
+ 595 + + @li **(17)**, **(19)** linear in the size of `*this` and `s.size()`.
+ 596 + + @li **(18)** linear in the size of `*this` and `std::strlen(s)`.
+ 597 + + @li **(22)** constant if `*this->storage() == *s.storage()`,
+ 598 + + otherwise linear in the size of `*this` and `s.size()`.
+ 599 + + @li **(21)** linear in the size of `*this` and `arr.size()`.
+ 600 + + @li **(22)** constant if `*this->storage() == *arr.storage()`,
+ 601 + + otherwise linear in the size of `*this` and `arr.size()`.
+ 602 + + @li **(23)** linear in the size of `*this` and `obj.size()`.
+ 603 + + @li **(24)** constant if `*this->storage() == *obj.storage()`,
+ 604 + + otherwise linear in the size of `*this` and `obj.size()`.
+ 605 + +
+ 606 + + The size of `*this` is either the size of the underlying container
+ 607 + + (if there is one), or can be considered to be 1.
+ 608 + +
+ 609 + + @par Exception Safety
+ 610 + + @li **(1)**--**(3)**, **(17)**--**(24)** strong guarantee.
+ 611 + + @li **(4)**--**(16)** no-throw guarantee.
+ 612 + +
+ 613 + + Calls to `memory_resource::allocate` may throw.
+ 614 + +
+ 615 + + @param other The source value.
+ 616 + +
+ 617 + + @{
+ 618 + + */
+ 619 + + BOOST_JSON_DECL
+ 620 + + value&
+ 621 + + operator=(value const& other);
+ 622 + +
+ 623 + + /** Overload
+ 624 + +
+ 625 + + The contents of the value are replaced with the
+ 626 + + contents of `other` using move semantics:
+ 627 + +
+ 628 + + @li If `*other.storage() == *sp`, ownership of
+ 629 + + the underlying memory is transferred in constant
+ 630 + + time, with no possibility of exceptions.
+ 631 + + After assignment, the moved-from value becomes
+ 632 + + a null with its current storage pointer.
+ 633 + +
+ 634 + + @li If `*other.storage() != *sp`, an
+ 635 + + element-wise copy is performed if
+ 636 + + `other.is_structured() == true`, which may throw.
+ 637 + + In this case, the moved-from value is not
+ 638 + + changed.
+ 639 + + */
+ 640 + + BOOST_JSON_DECL
+ 641 + + value&
+ 642 + + operator=(value&& other);
+ 643 + +
+ 644 + + /** Overload
+ 645 + +
+ 646 + + @param init The initializer list to assign from.
+ 647 + + */
+ 648 + + BOOST_JSON_DECL
+ 649 + + value&
+ 650 + + operator=(
+ 651 + + std::initializer_list<value_ref> init);
+ 652 + +
+ 653 + + /// Overload
+ 654 + + value&
+ 655 + +18 operator=(std::nullptr_t) noexcept
+ 656 + + {
+ 657 + +18 if(is_scalar())
+ 658 + + {
+ 659 + +12 sca_.k = json::kind::null;
+ 660 + + }
+ 661 + + else
+ 662 + + {
+ 663 + +18 ::new(&sca_) scalar(
+ 664 + +6 destroy());
+ 665 + + }
+ 666 + +18 return *this;
+ 667 + + }
+ 668 + +
+ 669 + + /** Overload
+ 670 + +
+ 671 + + @param b The new value.
+ 672 + + */
+ 673 + + #ifdef BOOST_JSON_DOCS
+ 674 + + value& operator=(bool b) noexcept;
+ 675 + + #else
+ 676 + + template<class T
+ 677 + + ,class = typename std::enable_if<
+ 678 + + std::is_same<T, bool>::value>::type
+ 679 + + >
+ 680 + +51 value& operator=(T b) noexcept
+ 681 + + {
+ 682 + +51 if(is_scalar())
+ 683 + + {
+ 684 + +50 sca_.b = b;
+ 685 + +50 sca_.k = json::kind::bool_;
+ 686 + + }
+ 687 + + else
+ 688 + + {
+ 689 + +1 ::new(&sca_) scalar(
+ 690 + + b, destroy());
+ 691 + + }
+ 692 + +51 return *this;
+ 693 + + }
+ 694 + + #endif
+ 695 + +
+ 696 + + /** Overload
+ 697 + +
+ 698 + + @param i The new value.
+ 699 + + */
+ 700 + +2 value& operator=(signed char i) noexcept
+ 701 + + {
+ 702 + +2 return operator=(
+ 703 + +2 static_cast<long long>(i));
+ 704 + + }
+ 705 + +
+ 706 + + /// Overload
+ 707 + +8 value& operator=(short i) noexcept
+ 708 + + {
+ 709 + +8 return operator=(
+ 710 + +8 static_cast<long long>(i));
+ 711 + + }
+ 712 + +
+ 713 + + /// Overload
+ 714 + +6518 value& operator=(int i) noexcept
+ 715 + + {
+ 716 + +6518 return operator=(
+ 717 + +6518 static_cast<long long>(i));
+ 718 + + }
+ 719 + +
+ 720 + + /// Overload
+ 721 + +12 value& operator=(long i) noexcept
+ 722 + + {
+ 723 + +12 return operator=(
+ 724 + +12 static_cast<long long>(i));
+ 725 + + }
+ 726 + +
+ 727 + + /// Overload
+ 728 + +6548 value& operator=(long long i) noexcept
+ 729 + + {
+ 730 + +6548 if(is_scalar())
+ 731 + + {
+ 732 + +6545 sca_.i = i;
+ 733 + +6545 sca_.k = json::kind::int64;
+ 734 + + }
+ 735 + + else
+ 736 + + {
+ 737 + +9 ::new(&sca_) scalar(static_cast<
+ 738 + +3 std::int64_t>(i), destroy());
+ 739 + + }
+ 740 + +6548 return *this;
+ 741 + + }
+ 742 + +
+ 743 + + /** Overload
+ 744 + +
+ 745 + + @param u The new value.
+ 746 + + */
+ 747 + +6 value& operator=(unsigned char u) noexcept
+ 748 + + {
+ 749 + +6 return operator=(static_cast<
+ 750 + +6 unsigned long long>(u));
+ 751 + + }
+ 752 + +
+ 753 + + /// Overload
+ 754 + +8 value& operator=(unsigned short u) noexcept
+ 755 + + {
+ 756 + +8 return operator=(static_cast<
+ 757 + +8 unsigned long long>(u));
+ 758 + + }
+ 759 + +
+ 760 + + /// Overload
+ 761 + +8 value& operator=(unsigned int u) noexcept
+ 762 + + {
+ 763 + +8 return operator=(static_cast<
+ 764 + +8 unsigned long long>(u));
+ 765 + + }
+ 766 + +
+ 767 + + /// Overload
+ 768 + +17 value& operator=(unsigned long u) noexcept
+ 769 + + {
+ 770 + +17 return operator=(static_cast<
+ 771 + +17 unsigned long long>(u));
+ 772 + + }
+ 773 + +
+ 774 + + /// Overload
+ 775 + +47 value& operator=(unsigned long long u) noexcept
+ 776 + + {
+ 777 + +47 if(is_scalar())
+ 778 + + {
+ 779 + +46 sca_.u = u;
+ 780 + +46 sca_.k = json::kind::uint64;
+ 781 + + }
+ 782 + + else
+ 783 + + {
+ 784 + +3 ::new(&sca_) scalar(static_cast<
+ 785 + +1 std::uint64_t>(u), destroy());
+ 786 + + }
+ 787 + +47 return *this;
+ 788 + + }
+ 789 + +
+ 790 + + /** Overload
+ 791 + +
+ 792 + + @param d The new value.
+ 793 + + */
+ 794 + +32 value& operator=(double d) noexcept
+ 795 + + {
+ 796 + +32 if(is_scalar())
+ 797 + + {
+ 798 + +25 sca_.d = d;
+ 799 + +25 sca_.k = json::kind::double_;
+ 800 + + }
+ 801 + + else
+ 802 + + {
+ 803 + +21 ::new(&sca_) scalar(
+ 804 + +7 d, destroy());
+ 805 + + }
+ 806 + +32 return *this;
+ 807 + + }
+ 808 + +
+ 809 + + /** Overload
+ 810 + +
+ 811 + + @param s The new string.
+ 812 + + */
+ 813 + + BOOST_JSON_DECL
+ 814 + + value& operator=(string_view s);
+ 815 + +
+ 816 + + /// Overload
+ 817 + + BOOST_JSON_DECL
+ 818 + + value& operator=(char const* s);
+ 819 + +
+ 820 + + /// Overload
+ 821 + + BOOST_JSON_DECL
+ 822 + + value& operator=(string const& s);
+ 823 + +
+ 824 + + /** Overload
+ 825 + +
+ 826 + + The contents of the value are replaced with the
+ 827 + + contents of `s` using move semantics:
+ 828 + +
+ 829 + + @li If `*other.storage() == *this->storage()`,
+ 830 + + ownership of the underlying memory is transferred
+ 831 + + in constant time, with no possibility of exceptions.
+ 832 + + After assignment, the moved-from string becomes
+ 833 + + empty with its current storage pointer.
+ 834 + +
+ 835 + + @li If `*other.storage() != *this->storage()`, an
+ 836 + + element-wise copy is performed, which may throw.
+ 837 + + In this case, the moved-from string is not
+ 838 + + changed.
+ 839 + +
+ 840 + + @param s The string to move-assign from.
+ 841 + + */
+ 842 + + BOOST_JSON_DECL
+ 843 + + value& operator=(string&& s);
+ 844 + +
+ 845 + + /** Overload
+ 846 + +
+ 847 + + Replace `*this` with a copy of the array `arr`.
+ 848 + +
+ 849 + + @par Exception Safety
+ 850 + + Strong guarantee.
+ 851 + + Calls to `memory_resource::allocate` may throw.
+ 852 + +
+ 853 + + @par Complexity
+ 854 + + Linear in the sum of sizes of `*this` and `arr`
+ 855 + +
+ 856 + + @param arr The new array.
+ 857 + + */
+ 858 + + BOOST_JSON_DECL
+ 859 + + value& operator=(array const& arr);
+ 860 + +
+ 861 + + /** Overload
+ 862 + +
+ 863 + + The contents of the value are replaced with the
+ 864 + + contents of `arr` using move semantics:
+ 865 + +
+ 866 + + @li If `*arr.storage() == *this->storage()`,
+ 867 + + ownership of the underlying memory is transferred
+ 868 + + in constant time, with no possibility of exceptions.
+ 869 + + After assignment, the moved-from array becomes
+ 870 + + empty with its current storage pointer.
+ 871 + +
+ 872 + + @li If `*arr.storage() != *this->storage()`, an
+ 873 + + element-wise copy is performed, which may throw.
+ 874 + + In this case, the moved-from array is not
+ 875 + + changed.
+ 876 + +
+ 877 + + @par Complexity
+ 878 + + Constant, or linear in the size of `*this` plus `arr.size()`.
+ 879 + +
+ 880 + + @par Exception Safety
+ 881 + + Strong guarantee.
+ 882 + + Calls to `memory_resource::allocate` may throw.
+ 883 + +
+ 884 + + @param arr The array to move-assign from.
+ 885 + + */
+ 886 + + BOOST_JSON_DECL
+ 887 + + value& operator=(array&& arr);
+ 888 + +
+ 889 + + /** Overload
+ 890 + +
+ 891 + + Replace `*this` with a copy of the obect `obj`.
+ 892 + +
+ 893 + + @par Exception Safety
+ 894 + + Strong guarantee.
+ 895 + + Calls to `memory_resource::allocate` may throw.
+ 896 + +
+ 897 + + @par Complexity
+ 898 + + Linear in the sum of sizes of `*this` and `obj`
+ 899 + +
+ 900 + + @param obj The new object.
+ 901 + + */
+ 902 + + BOOST_JSON_DECL
+ 903 + + value& operator=(object const& obj);
+ 904 + +
+ 905 + + /** Overload
+ 906 + +
+ 907 + + The contents of the value are replaced with the
+ 908 + + contents of `obj` using move semantics:
+ 909 + +
+ 910 + + @li If `*obj.storage() == *this->storage()`,
+ 911 + + ownership of the underlying memory is transferred
+ 912 + + in constant time, with no possibility of exceptions.
+ 913 + + After assignment, the moved-from object becomes
+ 914 + + empty with its current storage pointer.
+ 915 + +
+ 916 + + @li If `*obj.storage() != *this->storage()`, an
+ 917 + + element-wise copy is performed, which may throw.
+ 918 + + In this case, the moved-from object is not
+ 919 + + changed.
+ 920 + +
+ 921 + + @par Complexity
+ 922 + + Constant, or linear in the size of `*this` plus `obj.size()`.
+ 923 + +
+ 924 + + @par Exception Safety
+ 925 + + Strong guarantee.
+ 926 + + Calls to `memory_resource::allocate` may throw.
+ 927 + +
+ 928 + + @param obj The object to move-assign from.
+ 929 + + */
+ 930 + + BOOST_JSON_DECL
+ 931 + + value& operator=(object&& obj);
+ 932 + + /// @}
+ 933 + +
+ 934 + + //------------------------------------------------------
+ 935 + + //
+ 936 + + // Modifiers
+ 937 + + //
+ 938 + + //------------------------------------------------------
+ 939 + +
+ 940 + + /** Replace with a null value.
+ 941 + +
+ 942 + + The current value is destroyed and the kind is changed to kind::null.
+ 943 + + The associated memeory resource is kept unchanged.
+ 944 + +
+ 945 + + @par Complexity
+ 946 + + Linear in the size of `*this`.
+ 947 + +
+ 948 + + @par Exception Safety
+ 949 + + No-throw guarantee.
+ 950 + + */
+ 951 + + void
+ 952 + +8 emplace_null() noexcept
+ 953 + + {
+ 954 + +8 *this = nullptr;
+ 955 + +8 }
+ 956 + +
+ 957 + + /** Replace with a `bool` value.
+ 958 + +
+ 959 + + The value is replaced with a `bool` initialized to `false`, destroying
+ 960 + + the previous contents, but keeping the memeory resource.
+ 961 + +
+ 962 + + @par Complexity
+ 963 + + Linear in the size of `*this`.
+ 964 + +
+ 965 + + @par Exception Safety
+ 966 + + No-throw guarantee.
+ 967 + +
+ 968 + + @return `this->get_bool()`.
+ 969 + + */
+ 970 + + bool&
+ 971 + +1 emplace_bool() noexcept
+ 972 + + {
+ 973 + +1 *this = false;
+ 974 + +1 return sca_.b;
+ 975 + + }
+ 976 + +
+ 977 + + /** Replace with a `std::int64_t` value.
+ 978 + +
+ 979 + + The value is replaced with a `std::int64_t` initialized to zero,
+ 980 + + destroying the previous contents, but keeping the memeory resource.
+ 981 + +
+ 982 + + @par Complexity
+ 983 + + Linear in the size of `*this`.
+ 984 + +
+ 985 + + @par Exception Safety
+ 986 + + No-throw guarantee.
+ 987 + +
+ 988 + + @return `this->get_int64()`.
+ 989 + + */
+ 990 + + std::int64_t&
+ 991 + +2 emplace_int64() noexcept
+ 992 + + {
+ 993 + +2 *this = std::int64_t{};
+ 994 + +2 return sca_.i;
+ 995 + + }
+ 996 + +
+ 997 + + /** Replace with a `std::uint64_t` value.
+ 998 + +
+ 999 + + The value is replaced with a `std::uint64_t` initialized to zero,
+ 1000 + + destroying the the previous contents, but keeping the memeory resource.
+ 1001 + +
+ 1002 + + @par Complexity
+ 1003 + + Linear in the size of `*this`.
+ 1004 + +
+ 1005 + + @par Exception Safety
+ 1006 + + No-throw guarantee.
+ 1007 + +
+ 1008 + + @return `this->get_uint64()`.
+ 1009 + + */
+ 1010 + + std::uint64_t&
+ 1011 + +1 emplace_uint64() noexcept
+ 1012 + + {
+ 1013 + +1 *this = std::uint64_t{};
+ 1014 + +1 return sca_.u;
+ 1015 + + }
+ 1016 + +
+ 1017 + + /** Replace with a `double` value.
+ 1018 + +
+ 1019 + + The value is replaced with a `double` initialized to zero, destroying
+ 1020 + + the previous contents, but keeping the memeory resource.
+ 1021 + +
+ 1022 + + @par Complexity
+ 1023 + + Linear in the size of `*this`.
+ 1024 + +
+ 1025 + + @par Exception Safety
+ 1026 + + No-throw guarantee.
+ 1027 + +
+ 1028 + + @return `this->get_double()`.
+ 1029 + + */
+ 1030 + + double&
+ 1031 + +1 emplace_double() noexcept
+ 1032 + + {
+ 1033 + +1 *this = double{};
+ 1034 + +1 return sca_.d;
+ 1035 + + }
+ 1036 + +
+ 1037 + + /** Replace with an empty @ref string.
+ 1038 + +
+ 1039 + + The value is replaced with an empty @ref string using the current
+ 1040 + + memory resource, destroying the previous contents. All previously
+ 1041 + + obtained iterators and references obtained beforehand are invalidated.
+ 1042 + +
+ 1043 + + @par Complexity
+ 1044 + + Linear in the size of `*this`.
+ 1045 + +
+ 1046 + + @par Exception Safety
+ 1047 + + No-throw guarantee.
+ 1048 + +
+ 1049 + + @return `this->get_string()`.
+ 1050 + + */
+ 1051 + + BOOST_JSON_DECL
+ 1052 + + string&
+ 1053 + + emplace_string() noexcept;
+ 1054 + +
+ 1055 + + /** Replace with an empty array.
+ 1056 + +
+ 1057 + + The value is replaced with an empty @ref array using the current memory
+ 1058 + + resource, destroying the previous contents. All previously obtained
+ 1059 + + iterators and references obtained beforehand are invalidated.
+ 1060 + +
+ 1061 + + @par Complexity
+ 1062 + + Linear in the size of `*this`.
+ 1063 + +
+ 1064 + + @par Exception Safety
+ 1065 + + No-throw guarantee.
+ 1066 + +
+ 1067 + + @return `this->get_array()`.
+ 1068 + + */
+ 1069 + + BOOST_JSON_DECL
+ 1070 + + array&
+ 1071 + + emplace_array() noexcept;
+ 1072 + +
+ 1073 + + /** Replace with an empty @ref object.
+ 1074 + +
+ 1075 + + The value is replaced with an empty @ref array using the current memory
+ 1076 + + resource, destroying the previous contents. All previously obtained
+ 1077 + + iterators and references obtained beforehand are invalidated.
+ 1078 + +
+ 1079 + + @par Complexity
+ 1080 + + Linear in the size of `*this`.
+ 1081 + +
+ 1082 + + @par Exception Safety
+ 1083 + + No-throw guarantee.
+ 1084 + +
+ 1085 + + @return `this->get_object()`.
+ 1086 + + */
+ 1087 + + BOOST_JSON_DECL
+ 1088 + + object&
+ 1089 + + emplace_object() noexcept;
+ 1090 + +
+ 1091 + + /** Swap the given values.
+ 1092 + +
+ 1093 + + Exchanges the contents of this value with another value. Ownership of
+ 1094 + + the respective @ref boost::container::pmr::memory_resource objects is
+ 1095 + + not transferred:
+ 1096 + +
+ 1097 + + @li If `this == &other`, this function has no effect.
+ 1098 + + @li If `*other.storage() == *this->storage()`, ownership of the
+ 1099 + + underlying memory is swapped in constant time, with no possibility
+ 1100 + + of exceptions. All iterators and references remain valid.
+ 1101 + + @li If `*other.storage() != *this->storage()`, the contents are
+ 1102 + + logically swapped by making copies, which can throw. In this case
+ 1103 + + all iterators and references are invalidated.
+ 1104 + +
+ 1105 + + @par Complexity
+ 1106 + + Constant or linear in the sum of the sizes of the values.
+ 1107 + +
+ 1108 + + @par Exception Safety
+ 1109 + + Strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 1110 + +
+ 1111 + + @param other The value to swap with.
+ 1112 + + */
+ 1113 + + BOOST_JSON_DECL
+ 1114 + + void
+ 1115 + + swap(value& other);
+ 1116 + +
+ 1117 + + /** Swap the given values.
+ 1118 + +
+ 1119 + + Exchanges the contents of value `lhs` with another value `rhs`.
+ 1120 + + Ownership of the respective @ref boost::container::pmr::memory_resource
+ 1121 + + objects is not transferred.
+ 1122 + +
+ 1123 + + @li If `&lhs == &rhs`, this function call has no effect.
+ 1124 + + @li If `*lhs.storage() == *rhs.storage()`, ownership of the underlying
+ 1125 + + memory is swapped in constant time, with no possibility of
+ 1126 + + exceptions. All iterators and references remain valid.
+ 1127 + + @li If `*lhs.storage() != *rhs.storage`, the contents are logically
+ 1128 + + swapped by a copy, which can throw. In this case all iterators and
+ 1129 + + references are invalidated.
+ 1130 + +
+ 1131 + + @par Complexity
+ 1132 + + Constant or linear in the sum of the sizes of the values.
+ 1133 + +
+ 1134 + + @par Exception Safety
+ 1135 + + Strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 1136 + +
+ 1137 + + @param lhs The value to exchange.
+ 1138 + + @param rhs The value to exchange.
+ 1139 + +
+ 1140 + + @see @ref value::swap
+ 1141 + + */
+ 1142 + + friend
+ 1143 + + void
+ 1144 + +3 swap(value& lhs, value& rhs)
+ 1145 + + {
+ 1146 + +3 lhs.swap(rhs);
+ 1147 + +3 }
+ 1148 + +
+ 1149 + + //------------------------------------------------------
+ 1150 + + //
+ 1151 + + // Observers
+ 1152 + + //
+ 1153 + + //------------------------------------------------------
+ 1154 + +
+ 1155 + + /** Returns the kind of this JSON value.
+ 1156 + +
+ 1157 + + This function returns the discriminating enumeration constant of type
+ 1158 + + @ref json::kind corresponding to the underlying representation stored
+ 1159 + + in the container.
+ 1160 + +
+ 1161 + + @par Complexity
+ 1162 + + Constant.
+ 1163 + +
+ 1164 + + @par Exception Safety
+ 1165 + + No-throw guarantee.
+ 1166 + + */
+ 1167 + + json::kind
+ 1168 + +4609459 kind() const noexcept
+ 1169 + + {
+ 1170 + + return static_cast<json::kind>(
+ 1171 + + static_cast<unsigned char>(
+ 1172 + +4609459 sca_.k) & 0x3f);
+ 1173 + + }
+ 1174 + +
+ 1175 + + /** Check if this is an @ref array.
+ 1176 + +
+ 1177 + + Returns `true` if the value's @ref kind() is `kind::array`.
+ 1178 + +
+ 1179 + + @returns `this->kind() == kind::array`.
+ 1180 + +
+ 1181 + + @par Complexity
+ 1182 + + Constant.
+ 1183 + +
+ 1184 + + @par Exception Safety
+ 1185 + + No-throw guarantee.
+ 1186 + + */
+ 1187 + + bool
+ 1188 + +6013 is_array() const noexcept
+ 1189 + + {
+ 1190 + +6013 return kind() == json::kind::array;
+ 1191 + + }
+ 1192 + +
+ 1193 + + /** Check if this is an @ref object.
+ 1194 + +
+ 1195 + + Returns `true` if the value's @ref kind() is `kind::object`.
+ 1196 + +
+ 1197 + + @returns `this->kind() == kind::object`.
+ 1198 + +
+ 1199 + + @par Complexity
+ 1200 + + Constant.
+ 1201 + +
+ 1202 + + @par Exception Safety
+ 1203 + + No-throw guarantee.
+ 1204 + + */
+ 1205 + + bool
+ 1206 + +53265 is_object() const noexcept
+ 1207 + + {
+ 1208 + +53265 return kind() == json::kind::object;
+ 1209 + + }
+ 1210 + +
+ 1211 + + /** Check if this is a @ref string.
+ 1212 + +
+ 1213 + + Returns `true` if the value's @ref kind() is `kind::string`.
+ 1214 + +
+ 1215 + + @returns `this->kind() == kind::string`.
+ 1216 + +
+ 1217 + + @par Complexity
+ 1218 + + Constant.
+ 1219 + +
+ 1220 + + @par Exception Safety
+ 1221 + + No-throw guarantee.
+ 1222 + + */
+ 1223 + + bool
+ 1224 + +88279 is_string() const noexcept
+ 1225 + + {
+ 1226 + +88279 return kind() == json::kind::string;
+ 1227 + + }
+ 1228 + +
+ 1229 + + /** Check if this is a `std::int64_t`.
+ 1230 + +
+ 1231 + + Returns `true` if the value's @ref kind() is `kind::int64`.
+ 1232 + +
+ 1233 + + @returns `this->kind() == kind::int64`.
+ 1234 + +
+ 1235 + + @par Complexity
+ 1236 + + Constant.
+ 1237 + +
+ 1238 + + @par Exception Safety
+ 1239 + + No-throw guarantee.
+ 1240 + + */
+ 1241 + + bool
+ 1242 + +14882 is_int64() const noexcept
+ 1243 + + {
+ 1244 + +14882 return kind() == json::kind::int64;
+ 1245 + + }
+ 1246 + +
+ 1247 + + /** Checks if this is a `std::uint64_t`.
+ 1248 + +
+ 1249 + + Returns `true` if the value's @ref kind() is `kind::uint64`.
+ 1250 + +
+ 1251 + + @returns `this->kind() == kind::uint64`.
+ 1252 + +
+ 1253 + + @par Complexity
+ 1254 + + Constant.
+ 1255 + +
+ 1256 + + @par Exception Safety
+ 1257 + + No-throw guarantee.
+ 1258 + + */
+ 1259 + + bool
+ 1260 + +340 is_uint64() const noexcept
+ 1261 + + {
+ 1262 + +340 return kind() == json::kind::uint64;
+ 1263 + + }
+ 1264 + +
+ 1265 + + /** Check if this is a `double`.
+ 1266 + +
+ 1267 + + Returns `true` if the value's @ref kind() is `kind::double_`.
+ 1268 + +
+ 1269 + + @returns `this->kind() == kind::double_`.
+ 1270 + +
+ 1271 + + @par Complexity
+ 1272 + + Constant.
+ 1273 + +
+ 1274 + + @par Exception Safety
+ 1275 + + No-throw guarantee.
+ 1276 + + */
+ 1277 + + bool
+ 1278 + +2078681 is_double() const noexcept
+ 1279 + + {
+ 1280 + +2078681 return kind() == json::kind::double_;
+ 1281 + + }
+ 1282 + +
+ 1283 + + /** Check if this is a `bool`.
+ 1284 + +
+ 1285 + + Returns `true` if the value's @ref kind() is `kind::bool_`.
+ 1286 + +
+ 1287 + + @returns `this->kind() == kind::bool_`.
+ 1288 + +
+ 1289 + + @par Complexity
+ 1290 + + Constant.
+ 1291 + +
+ 1292 + + @par Exception Safety
+ 1293 + + No-throw guarantee.
+ 1294 + + */
+ 1295 + + bool
+ 1296 + +952 is_bool() const noexcept
+ 1297 + + {
+ 1298 + +952 return kind() == json::kind::bool_;
+ 1299 + + }
+ 1300 + +
+ 1301 + + /** Check if this is a null value.
+ 1302 + +
+ 1303 + + Returns `true` if the value's @ref kind() is `kind::null`.
+ 1304 + +
+ 1305 + + @returns `this->kind() == kind::null`.
+ 1306 + +
+ 1307 + + @par Complexity
+ 1308 + + Constant.
+ 1309 + +
+ 1310 + + @par Exception Safety
+ 1311 + + No-throw guarantee.
+ 1312 + + */
+ 1313 + + bool
+ 1314 + +148 is_null() const noexcept
+ 1315 + + {
+ 1316 + +148 return kind() == json::kind::null;
+ 1317 + + }
+ 1318 + +
+ 1319 + + /** Checks if this is an @ref array or an @ref object.
+ 1320 + +
+ 1321 + + This function returns `true` if @ref kind() is either `kind::object` or
+ 1322 + + `kind::array`.
+ 1323 + +
+ 1324 + + @par Complexity
+ 1325 + + Constant.
+ 1326 + +
+ 1327 + + @par Exception Safety
+ 1328 + + No-throw guarantee.
+ 1329 + + */
+ 1330 + + bool
+ 1331 + +8 is_structured() const noexcept
+ 1332 + + {
+ 1333 + + // VFALCO Could use bit 0x20 for this
+ 1334 + + return
+ 1335 + +15 kind() == json::kind::object ||
+ 1336 + +15 kind() == json::kind::array;
+ 1337 + + }
+ 1338 + +
+ 1339 + + /** Check if this is not an @ref array or @ref object.
+ 1340 + +
+ 1341 + + This function returns `true` if @ref kind() is neither `kind::object`
+ 1342 + + nor `kind::array`.
+ 1343 + +
+ 1344 + + @par Complexity
+ 1345 + + Constant.
+ 1346 + +
+ 1347 + + @par Exception Safety
+ 1348 + + No-throw guarantee.
+ 1349 + + */
+ 1350 + + bool
+ 1351 + +8 is_primitive() const noexcept
+ 1352 + + {
+ 1353 + + // VFALCO Could use bit 0x20 for this
+ 1354 + + return
+ 1355 + +15 sca_.k != json::kind::object &&
+ 1356 + +15 sca_.k != json::kind::array;
+ 1357 + + }
+ 1358 + +
+ 1359 + + /** Check if this is a number.
+ 1360 + +
+ 1361 + + This function returns `true` when @ref kind() is one of `kind::int64`,
+ 1362 + + `kind::uint64`, or `kind::double_`.
+ 1363 + +
+ 1364 + + @par Complexity
+ 1365 + + Constant.
+ 1366 + +
+ 1367 + + @par Exception Safety
+ 1368 + + No-throw guarantee.
+ 1369 + + */
+ 1370 + + bool
+ 1371 + +83 is_number() const noexcept
+ 1372 + + {
+ 1373 + + // VFALCO Could use bit 0x40 for this
+ 1374 + + return
+ 1375 + +92 kind() == json::kind::int64 ||
+ 1376 + +92 kind() == json::kind::uint64 ||
+ 1377 + +91 kind() == json::kind::double_;
+ 1378 + + }
+ 1379 + +
+ 1380 + + //------------------------------------------------------
+ 1381 + +
+ 1382 + + /** Return a pointer to the underlying @ref array.
+ 1383 + +
+ 1384 + + If `this->kind() == kind::array`, returns a pointer to the underlying
+ 1385 + + array. Otherwise, returns `nullptr`.
+ 1386 + +
+ 1387 + + @par Example
+ 1388 + + The return value is used in both a boolean context and
+ 1389 + + to assign a variable:
+ 1390 + + @code
+ 1391 + + if( auto p = jv.if_array() )
+ 1392 + + return *p;
+ 1393 + + @endcode
+ 1394 + +
+ 1395 + + @par Complexity
+ 1396 + + Constant.
+ 1397 + +
+ 1398 + + @par Exception Safety
+ 1399 + + No-throw guarantee.
+ 1400 + +
+ 1401 + + @{
+ 1402 + + */
+ 1403 + + array const*
+ 1404 + +254 if_array() const noexcept
+ 1405 + + {
+ 1406 + +254 if(kind() == json::kind::array)
+ 1407 + +217 return &arr_;
+ 1408 + +37 return nullptr;
+ 1409 + + }
+ 1410 + +
+ 1411 + + array*
+ 1412 + +9 if_array() noexcept
+ 1413 + + {
+ 1414 + +9 if(kind() == json::kind::array)
+ 1415 + +2 return &arr_;
+ 1416 + +7 return nullptr;
+ 1417 + + }
+ 1418 + + /// @}
+ 1419 + +
+ 1420 + + /** Return a pointer to the underlying @ref object.
+ 1421 + +
+ 1422 + + If `this->kind() == kind::object`, returns a pointer to the underlying
+ 1423 + + object. Otherwise, returns `nullptr`.
+ 1424 + +
+ 1425 + + @par Example
+ 1426 + + The return value is used in both a boolean context and
+ 1427 + + to assign a variable:
+ 1428 + + @code
+ 1429 + + if( auto p = jv.if_object() )
+ 1430 + + return *p;
+ 1431 + + @endcode
+ 1432 + +
+ 1433 + + @par Complexity
+ 1434 + + Constant.
+ 1435 + +
+ 1436 + + @par Exception Safety
+ 1437 + + No-throw guarantee.
+ 1438 + +
+ 1439 + + @{
+ 1440 + + */
+ 1441 + + object const*
+ 1442 + +94 if_object() const noexcept
+ 1443 + + {
+ 1444 + +94 if(kind() == json::kind::object)
+ 1445 + +69 return &obj_;
+ 1446 + +25 return nullptr;
+ 1447 + + }
+ 1448 + +
+ 1449 + + object*
+ 1450 + +10 if_object() noexcept
+ 1451 + + {
+ 1452 + +10 if(kind() == json::kind::object)
+ 1453 + +3 return &obj_;
+ 1454 + +7 return nullptr;
+ 1455 + + }
+ 1456 + + /// @}
+ 1457 + +
+ 1458 + + /** Return a pointer to the underlying @ref string.
+ 1459 + +
+ 1460 + + If `this->kind() == kind::string`, returns a pointer to the underlying
+ 1461 + + object. Otherwise, returns `nullptr`.
+ 1462 + +
+ 1463 + + @par Example
+ 1464 + + The return value is used in both a boolean context and
+ 1465 + + to assign a variable:
+ 1466 + + @code
+ 1467 + + if( auto p = jv.if_string() )
+ 1468 + + return *p;
+ 1469 + + @endcode
+ 1470 + +
+ 1471 + + @par Complexity
+ 1472 + + Constant.
+ 1473 + +
+ 1474 + + @par Exception Safety
+ 1475 + + No-throw guarantee.
+ 1476 + +
+ 1477 + + @{
+ 1478 + + */
+ 1479 + + string const*
+ 1480 + +252 if_string() const noexcept
+ 1481 + + {
+ 1482 + +252 if(kind() == json::kind::string)
+ 1483 + +184 return &str_;
+ 1484 + +68 return nullptr;
+ 1485 + + }
+ 1486 + +
+ 1487 + + string*
+ 1488 + +10 if_string() noexcept
+ 1489 + + {
+ 1490 + +10 if(kind() == json::kind::string)
+ 1491 + +3 return &str_;
+ 1492 + +7 return nullptr;
+ 1493 + + }
+ 1494 + + /// @}
+ 1495 + +
+ 1496 + + /** Return a pointer to the underlying `std::int64_t`.
+ 1497 + +
+ 1498 + + If `this->kind() == kind::int64`, returns a pointer to the underlying
+ 1499 + + integer. Otherwise, returns `nullptr`.
+ 1500 + +
+ 1501 + + @par Example
+ 1502 + + The return value is used in both a boolean context and
+ 1503 + + to assign a variable:
+ 1504 + + @code
+ 1505 + + if( auto p = jv.if_int64() )
+ 1506 + + return *p;
+ 1507 + + @endcode
+ 1508 + +
+ 1509 + + @par Complexity
+ 1510 + + Constant.
+ 1511 + +
+ 1512 + + @par Exception Safety
+ 1513 + + No-throw guarantee.
+ 1514 + +
+ 1515 + + @{
+ 1516 + + */
+ 1517 + + std::int64_t const*
+ 1518 + +8 if_int64() const noexcept
+ 1519 + + {
+ 1520 + +8 if(kind() == json::kind::int64)
+ 1521 + +1 return &sca_.i;
+ 1522 + +7 return nullptr;
+ 1523 + + }
+ 1524 + +
+ 1525 + + std::int64_t*
+ 1526 + +10 if_int64() noexcept
+ 1527 + + {
+ 1528 + +10 if(kind() == json::kind::int64)
+ 1529 + +3 return &sca_.i;
+ 1530 + +7 return nullptr;
+ 1531 + + }
+ 1532 + + /// @}
+ 1533 + +
+ 1534 + + /** Return a pointer to the underlying `std::uint64_t`.
+ 1535 + +
+ 1536 + + If `this->kind() == kind::uint64`, returns a pointer to the underlying
+ 1537 + + unsigned integer. Otherwise, returns `nullptr`.
+ 1538 + +
+ 1539 + + @par Example
+ 1540 + + The return value is used in both a boolean context and
+ 1541 + + to assign a variable:
+ 1542 + + @code
+ 1543 + + if( auto p = jv.if_uint64() )
+ 1544 + + return *p;
+ 1545 + + @endcode
+ 1546 + +
+ 1547 + + @par Complexity
+ 1548 + + Constant.
+ 1549 + +
+ 1550 + + @par Exception Safety
+ 1551 + + No-throw guarantee.
+ 1552 + +
+ 1553 + + @{
+ 1554 + + */
+ 1555 + + std::uint64_t const*
+ 1556 + +8 if_uint64() const noexcept
+ 1557 + + {
+ 1558 + +8 if(kind() == json::kind::uint64)
+ 1559 + +1 return &sca_.u;
+ 1560 + +7 return nullptr;
+ 1561 + + }
+ 1562 + +
+ 1563 + + std::uint64_t*
+ 1564 + +8 if_uint64() noexcept
+ 1565 + + {
+ 1566 + +8 if(kind() == json::kind::uint64)
+ 1567 + +1 return &sca_.u;
+ 1568 + +7 return nullptr;
+ 1569 + + }
+ 1570 + + /// @}
+ 1571 + +
+ 1572 + + /** Return a pointer to the underlying `double`.
+ 1573 + +
+ 1574 + + If `this->kind() == kind::double_`, returns a pointer to the underlying
+ 1575 + + double. Otherwise, returns `nullptr`.
+ 1576 + +
+ 1577 + + @par Example
+ 1578 + + The return value is used in both a boolean context and
+ 1579 + + to assign a variable:
+ 1580 + + @code
+ 1581 + + if( auto p = jv.if_double() )
+ 1582 + + return *p;
+ 1583 + + @endcode
+ 1584 + +
+ 1585 + + @par Complexity
+ 1586 + + Constant.
+ 1587 + +
+ 1588 + + @par Exception Safety
+ 1589 + + No-throw guarantee.
+ 1590 + +
+ 1591 + + @{
+ 1592 + + */
+ 1593 + + double const*
+ 1594 + +8 if_double() const noexcept
+ 1595 + + {
+ 1596 + +8 if(kind() == json::kind::double_)
+ 1597 + +1 return &sca_.d;
+ 1598 + +7 return nullptr;
+ 1599 + + }
+ 1600 + +
+ 1601 + + double*
+ 1602 + +8 if_double() noexcept
+ 1603 + + {
+ 1604 + +8 if(kind() == json::kind::double_)
+ 1605 + +1 return &sca_.d;
+ 1606 + +7 return nullptr;
+ 1607 + + }
+ 1608 + + /// @}
+ 1609 + +
+ 1610 + + /** Return a pointer to the underlying `bool` .
+ 1611 + +
+ 1612 + + If `this->kind() == kind::bool_`, returns a pointer to the underlying
+ 1613 + + boolean. Otherwise, returns `nullptr`.
+ 1614 + +
+ 1615 + + @par Example
+ 1616 + + The return value is used in both a boolean context and
+ 1617 + + to assign a variable:
+ 1618 + + @code
+ 1619 + + if( auto p = jv.if_bool() )
+ 1620 + + return *p;
+ 1621 + + @endcode
+ 1622 + +
+ 1623 + + @par Complexity
+ 1624 + + Constant.
+ 1625 + +
+ 1626 + + @par Exception Safety
+ 1627 + + No-throw guarantee.
+ 1628 + +
+ 1629 + + @{
+ 1630 + + */
+ 1631 + + bool const*
+ 1632 + +57 if_bool() const noexcept
+ 1633 + + {
+ 1634 + +57 if(kind() == json::kind::bool_)
+ 1635 + +43 return &sca_.b;
+ 1636 + +14 return nullptr;
+ 1637 + + }
+ 1638 + +
+ 1639 + + bool*
+ 1640 + +8 if_bool() noexcept
+ 1641 + + {
+ 1642 + +8 if(kind() == json::kind::bool_)
+ 1643 + +1 return &sca_.b;
+ 1644 + +7 return nullptr;
+ 1645 + + }
+ 1646 + + /// @}
+ 1647 + +
+ 1648 + + //------------------------------------------------------
+ 1649 + +
+ 1650 + + /** Return the stored number cast to an arithmetic type.
+ 1651 + +
+ 1652 + + This function attempts to return the stored value converted to the
+ 1653 + + arithmetic type `T` which may not be `bool`:
+ 1654 + +
+ 1655 + + @li If `T` is an integral type and the stored value is a number which
+ 1656 + + can be losslessly converted, the conversion is performed without
+ 1657 + + error and the converted number is returned.
+ 1658 + + @li If `T` is an integral type and the stored value is a number which
+ 1659 + + cannot be losslessly converted, then the operation fails with
+ 1660 + + an error.
+ 1661 + + @li If `T` is a floating point type and the stored value is a number,
+ 1662 + + the conversion is performed without error. The converted number is
+ 1663 + + returned, with a possible loss of precision.
+ 1664 + + @li Otherwise, if the stored value is not a number; that is, if
+ 1665 + + @ref is_number() returns `false`, then the operation fails with
+ 1666 + + an error.
+ 1667 + +
+ 1668 + + @par Constraints
+ 1669 + + @code
+ 1670 + + std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
+ 1671 + + @endcode
+ 1672 + +
+ 1673 + + @par Complexity
+ 1674 + + Constant.
+ 1675 + +
+ 1676 + + @par Exception Safety
+ 1677 + + @li **(1)**, **(2)** no-throw guarantee.
+ 1678 + + @li **(3)** strong guarantee.
+ 1679 + +
+ 1680 + + @return The converted number.
+ 1681 + +
+ 1682 + + @param ec Set to the error, if any occurred.
+ 1683 + +
+ 1684 + + @return The converted number.
+ 1685 + +
+ 1686 + + @{
+ 1687 + + */
+ 1688 + + template<class T>
+ 1689 + + #ifdef BOOST_JSON_DOCS
+ 1690 + + T
+ 1691 + + #else
+ 1692 + + typename std::enable_if<
+ 1693 + + std::is_arithmetic<T>::value &&
+ 1694 + + ! std::is_same<T, bool>::value,
+ 1695 + + T>::type
+ 1696 + + #endif
+ 1697 + +3594 to_number(system::error_code& ec) const noexcept
+ 1698 + + {
+ 1699 + + error e;
+ 1700 + +3594 auto result = to_number<T>(e);
+ 1701 + +3594 BOOST_JSON_FAIL(ec, e);
+ 1702 + +3594 return result;
+ 1703 + + }
+ 1704 + +
+ 1705 + + template<class T>
+ 1706 + + #ifdef BOOST_JSON_DOCS
+ 1707 + + T
+ 1708 + + #else
+ 1709 + + typename std::enable_if<
+ 1710 + + std::is_arithmetic<T>::value &&
+ 1711 + + ! std::is_same<T, bool>::value,
+ 1712 + + T>::type
+ 1713 + + #endif
+ 1714 + +1 to_number(std::error_code& ec) const noexcept
+ 1715 + + {
+ 1716 + +1 system::error_code jec;
+ 1717 + +1 auto result = to_number<T>(jec);
+ 1718 + +1 ec = jec;
+ 1719 + +1 return result;
+ 1720 + + }
+ 1721 + +
+ 1722 + + /** Overload
+ 1723 + +
+ 1724 + + @throws boost::system::system_error Overload **(3)** reports errors by
+ 1725 + + throwing an exception.
+ 1726 + + */
+ 1727 + + template<class T>
+ 1728 + + #ifdef BOOST_JSON_DOCS
+ 1729 + + T
+ 1730 + + #else
+ 1731 + + typename std::enable_if<
+ 1732 + + std::is_arithmetic<T>::value &&
+ 1733 + + ! std::is_same<T, bool>::value,
+ 1734 + + T>::type
+ 1735 + + #endif
+ 1736 + +194 to_number() const
+ 1737 + + {
+ 1738 + +194 return try_to_number<T>().value();
+ 1739 + + }
+ 1740 + + /// @}
+ 1741 + +
+ 1742 + + /** Return the stored number as @ref boost::system::result.
+ 1743 + +
+ 1744 + + This function attempts to return the stored value converted to the
+ 1745 + + arithmetic type `T` which may not be `bool`:
+ 1746 + +
+ 1747 + + @li If `T` is an integral type and the stored value is a number which
+ 1748 + + can be losslessly converted, the conversion is performed without
+ 1749 + + error and `result<T>` containing the converted number is returned.
+ 1750 + + @li If `T` is an integral type and the stored value is a number which
+ 1751 + + cannot be losslessly converted, then `result<T>` containing the
+ 1752 + + corresponding `error_code` is returned.
+ 1753 + + @li If `T` is a floating point type and the stored value is a number,
+ 1754 + + the conversion is performed without error. `result<T>` containing
+ 1755 + + the converted number, with a possible loss of precision, is
+ 1756 + + returned.
+ 1757 + + @li Otherwise, if the stored value is not a number; that is, if
+ 1758 + + `this->is_number()` returns `false`, then `result<T>` containing
+ 1759 + + the corresponding `error_code` is returned.
+ 1760 + +
+ 1761 + + @par Constraints
+ 1762 + + @code
+ 1763 + + std::is_arithmetic< T >::value && ! std::is_same< T, bool >::value
+ 1764 + + @endcode
+ 1765 + +
+ 1766 + + @par Complexity
+ 1767 + + Constant.
+ 1768 + +
+ 1769 + + @par Exception Safety
+ 1770 + + No-throw guarantee.
+ 1771 + +
+ 1772 + + @return `boost::system::result<T>` with either the converted number or
+ 1773 + + an `error_code`.
+ 1774 + + */
+ 1775 + + template<class T>
+ 1776 + + #ifdef BOOST_JSON_DOCS
+ 1777 + + system::result<T>
+ 1778 + + #else
+ 1779 + + typename std::enable_if<
+ 1780 + + std::is_arithmetic<T>::value && ! std::is_same<T, bool>::value,
+ 1781 + + system::result<T>
+ 1782 + + >::type
+ 1783 + + #endif
+ 1784 + +196 try_to_number() const noexcept
+ 1785 + + {
+ 1786 + +196 system::error_code ec;
+ 1787 + +196 T result = to_number<T>(ec);
+ 1788 + +196 if( ec )
+ 1789 + +78 return {system::in_place_error, ec};
+ 1790 + +
+ 1791 + +118 return {system::in_place_value, result};
+ 1792 + + }
+ 1793 + +
+ 1794 + + //------------------------------------------------------
+ 1795 + + //
+ 1796 + + // Accessors
+ 1797 + + //
+ 1798 + + //------------------------------------------------------
+ 1799 + +
+ 1800 + + /** Return the associated memory resource.
+ 1801 + +
+ 1802 + + This function returns a smart pointer to the
+ 1803 + + @ref boost::container::pmr::memory_resource used by the container.
+ 1804 + +
+ 1805 + + @par Complexity
+ 1806 + + Constant.
+ 1807 + +
+ 1808 + + @par Exception Safety
+ 1809 + + No-throw guarantee.
+ 1810 + + */
+ 1811 + + storage_ptr const&
+ 1812 + +75659 storage() const noexcept
+ 1813 + + {
+ 1814 + +75659 return sp_;
+ 1815 + + }
+ 1816 + +
+ 1817 + + /** Return the associated allocator.
+ 1818 + +
+ 1819 + + This function returns an instance of @ref allocator_type constructed
+ 1820 + + from the associated @ref boost::container::pmr::memory_resource.
+ 1821 + +
+ 1822 + + @par Complexity
+ 1823 + + Constant.
+ 1824 + +
+ 1825 + + @par Exception Safety
+ 1826 + + No-throw guarantee.
+ 1827 + + */
+ 1828 + + allocator_type
+ 1829 + +1 get_allocator() const noexcept
+ 1830 + + {
+ 1831 + +1 return sp_.get();
+ 1832 + + }
+ 1833 + +
+ 1834 + + //------------------------------------------------------
+ 1835 + +
+ 1836 + + /** Return `result` with a reference to the underlying @ref array
+ 1837 + +
+ 1838 + + If @ref is_array() is `true`, the result contains a reference to the
+ 1839 + + underlying @ref array, otherwise it contains an `error_code`.
+ 1840 + +
+ 1841 + + @par Example
+ 1842 + + The return value can be used in both a boolean context and
+ 1843 + + to assign a variable:
+ 1844 + + @code
+ 1845 + + if( auto r = jv.try_as_array() )
+ 1846 + + return *r;
+ 1847 + + @endcode
+ 1848 + +
+ 1849 + + But can also be used to throw an exception on error:
+ 1850 + + @code
+ 1851 + + return jv.try_as_array().value();
+ 1852 + + @endcode
+ 1853 + +
+ 1854 + + @par Complexity
+ 1855 + + Constant.
+ 1856 + +
+ 1857 + + @par Exception Safety
+ 1858 + + No-throw guarantee.
+ 1859 + +
+ 1860 + + @{
+ 1861 + + */
+ 1862 + + BOOST_JSON_DECL
+ 1863 + + system::result<array&>
+ 1864 + + try_as_array() noexcept;
+ 1865 + +
+ 1866 + + BOOST_JSON_DECL
+ 1867 + + system::result<array const&>
+ 1868 + + try_as_array() const noexcept;
+ 1869 + + /// @}
+ 1870 + +
+ 1871 + + /** Return `result` with a reference to the underlying @ref object.
+ 1872 + +
+ 1873 + + If @ref is_object() is `true`, the result contains a reference to the
+ 1874 + + underlying @ref object, otherwise it contains an `error_code`.
+ 1875 + +
+ 1876 + + @par Example
+ 1877 + + The return value can be used in both a boolean context and
+ 1878 + + to assign a variable:
+ 1879 + + @code
+ 1880 + + if( auto r = jv.try_as_object() )
+ 1881 + + return *r;
+ 1882 + + @endcode
+ 1883 + +
+ 1884 + + But can also be used to throw an exception on error:
+ 1885 + + @code
+ 1886 + + return jv.try_as_object().value();
+ 1887 + + @endcode
+ 1888 + +
+ 1889 + + @par Complexity
+ 1890 + + Constant.
+ 1891 + +
+ 1892 + + @par Exception Safety
+ 1893 + + No-throw guarantee.
+ 1894 + +
+ 1895 + + @{
+ 1896 + + */
+ 1897 + + BOOST_JSON_DECL
+ 1898 + + system::result<object&>
+ 1899 + + try_as_object() noexcept;
+ 1900 + +
+ 1901 + + BOOST_JSON_DECL
+ 1902 + + system::result<object const&>
+ 1903 + + try_as_object() const noexcept;
+ 1904 + + /// @}
+ 1905 + +
+ 1906 + + /** Return `result` with a reference to the underlying @ref string.
+ 1907 + +
+ 1908 + + If @ref is_string() is `true`, the result contains a reference to the
+ 1909 + + underlying @ref string, otherwise it contains an `error_code`.
+ 1910 + +
+ 1911 + + @par Example
+ 1912 + + The return value can be used in both a boolean context and
+ 1913 + + to assign a variable:
+ 1914 + + @code
+ 1915 + + if( auto r = jv.try_as_string() )
+ 1916 + + return *r;
+ 1917 + + @endcode
+ 1918 + +
+ 1919 + + But can also be used to throw an exception on error:
+ 1920 + + @code
+ 1921 + + return jv.try_as_string().value();
+ 1922 + + @endcode
+ 1923 + +
+ 1924 + + @par Complexity
+ 1925 + + Constant.
+ 1926 + +
+ 1927 + + @par Exception Safety
+ 1928 + + No-throw guarantee.
+ 1929 + +
+ 1930 + + @{
+ 1931 + + */
+ 1932 + + BOOST_JSON_DECL
+ 1933 + + system::result<string&>
+ 1934 + + try_as_string() noexcept;
+ 1935 + +
+ 1936 + + BOOST_JSON_DECL
+ 1937 + + system::result<string const&>
+ 1938 + + try_as_string() const noexcept;
+ 1939 + + /// @}
+ 1940 + +
+ 1941 + + /** Return `result` with the underlying `std::int64_t`
+ 1942 + +
+ 1943 + + If @ref is_int64() is `true`, the result contains a reference to **(1)**
+ 1944 + + or a copy of **(2)** the underlying `std::int64_t`, otherwise it
+ 1945 + + contains an `error_code`.
+ 1946 + +
+ 1947 + + @par Example
+ 1948 + + The return value can be used in both a boolean context and
+ 1949 + + to assign a variable:
+ 1950 + + @code
+ 1951 + + if( auto r = jv.try_as_int64() )
+ 1952 + + return *r;
+ 1953 + + @endcode
+ 1954 + +
+ 1955 + + But can also be used to throw an exception on error:
+ 1956 + + @code
+ 1957 + + return jv.try_as_int64().value();
+ 1958 + + @endcode
+ 1959 + +
+ 1960 + + @par Complexity
+ 1961 + + Constant.
+ 1962 + +
+ 1963 + + @par Exception Safety
+ 1964 + + No-throw guarantee.
+ 1965 + +
+ 1966 + + @{
+ 1967 + + */
+ 1968 + + BOOST_JSON_DECL
+ 1969 + + system::result<std::int64_t&>
+ 1970 + + try_as_int64() noexcept;
+ 1971 + +
+ 1972 + + BOOST_JSON_DECL
+ 1973 + + system::result<std::int64_t>
+ 1974 + + try_as_int64() const noexcept;
+ 1975 + + /// @}
+ 1976 + +
+ 1977 + + /** Return `result` with the underlying `std::uint64_t`.
+ 1978 + +
+ 1979 + + If @ref is_uint64() is `true`, the result contains a reference to **(1)**
+ 1980 + + or a copy of **(2)** the underlying `std::uint64_t`, otherwise it
+ 1981 + + contains an `error_code`.
+ 1982 + +
+ 1983 + + @par Example
+ 1984 + + The return value can be used in both a boolean context and
+ 1985 + + to assign a variable:
+ 1986 + + @code
+ 1987 + + if( auto r = jv.try_as_uint64() )
+ 1988 + + return *r;
+ 1989 + + @endcode
+ 1990 + +
+ 1991 + + But can also be used to throw an exception on error:
+ 1992 + + @code
+ 1993 + + return jv.try_as_uint64().value();
+ 1994 + + @endcode
+ 1995 + +
+ 1996 + + @par Complexity
+ 1997 + + Constant.
+ 1998 + +
+ 1999 + + @par Exception Safety
+ 2000 + + No-throw guarantee.
+ 2001 + +
+ 2002 + + @{
+ 2003 + + */
+ 2004 + + BOOST_JSON_DECL
+ 2005 + + system::result<std::uint64_t&>
+ 2006 + + try_as_uint64() noexcept;
+ 2007 + +
+ 2008 + + BOOST_JSON_DECL
+ 2009 + + system::result<std::uint64_t>
+ 2010 + + try_as_uint64() const noexcept;
+ 2011 + + /// @}
+ 2012 + +
+ 2013 + + /** Return `result` with the underlying `double`
+ 2014 + +
+ 2015 + + If @ref is_double() is `true`, the result contains a reference to **(1)**
+ 2016 + + or a copy of **(2)** the underlying `double`, otherwise it
+ 2017 + + contains an `error_code`.
+ 2018 + +
+ 2019 + + @par Example
+ 2020 + + The return value can be used in both a boolean context and
+ 2021 + + to assign a variable:
+ 2022 + + @code
+ 2023 + + if( auto r = jv.try_as_double() )
+ 2024 + + return *r;
+ 2025 + + @endcode
+ 2026 + +
+ 2027 + + But can also be used to throw an exception on error:
+ 2028 + + @code
+ 2029 + + return jv.try_as_double().value();
+ 2030 + + @endcode
+ 2031 + +
+ 2032 + + @par Complexity
+ 2033 + + Constant.
+ 2034 + +
+ 2035 + + @par Exception Safety
+ 2036 + + No-throw guarantee.
+ 2037 + +
+ 2038 + + @{
+ 2039 + + */
+ 2040 + + BOOST_JSON_DECL
+ 2041 + + system::result<double&>
+ 2042 + + try_as_double() noexcept;
+ 2043 + +
+ 2044 + + BOOST_JSON_DECL
+ 2045 + + system::result<double>
+ 2046 + + try_as_double() const noexcept;
+ 2047 + + /// @}
+ 2048 + +
+ 2049 + + /** Return `result` with the underlying `bool`
+ 2050 + +
+ 2051 + + If @ref is_bool() is `true`, the result contains a reference to **(1)**
+ 2052 + + or a copy to **(2)** the underlying `bool`, otherwise it contains an
+ 2053 + + `error_code`.
+ 2054 + +
+ 2055 + + @par Example
+ 2056 + + The return value can be used in both a boolean context and
+ 2057 + + to assign a variable:
+ 2058 + + @code
+ 2059 + + if( auto r = jv.try_as_bool() )
+ 2060 + + return *r;
+ 2061 + + @endcode
+ 2062 + +
+ 2063 + + But can also be used to throw an exception on error:
+ 2064 + + @code
+ 2065 + + return jv.try_as_bool().value();
+ 2066 + + @endcode
+ 2067 + +
+ 2068 + + @par Complexity
+ 2069 + + Constant.
+ 2070 + +
+ 2071 + + @par Exception Safety
+ 2072 + + No-throw guarantee.
+ 2073 + +
+ 2074 + + @{
+ 2075 + + */
+ 2076 + + BOOST_JSON_DECL
+ 2077 + + system::result<bool&>
+ 2078 + + try_as_bool() noexcept;
+ 2079 + +
+ 2080 + + BOOST_JSON_DECL
+ 2081 + + system::result<bool>
+ 2082 + + try_as_bool() const noexcept;
+ 2083 + + /// @}
+ 2084 + +
+ 2085 + + /** Return engaged `result` if the `value` is null.
+ 2086 + +
+ 2087 + + If @ref is_null() is `true`, the result is engaged, otherwise it
+ 2088 + + contains an `error_code`.
+ 2089 + +
+ 2090 + + @par Example
+ 2091 + + The return value can be used in both a boolean context and
+ 2092 + + to assign a variable:
+ 2093 + + @code
+ 2094 + + if( auto r = jv.try_as_null() )
+ 2095 + + return *r;
+ 2096 + + @endcode
+ 2097 + +
+ 2098 + + But can also be used to throw an exception on error:
+ 2099 + + @code
+ 2100 + + return jv.try_as_null().value();
+ 2101 + + @endcode
+ 2102 + +
+ 2103 + + @par Complexity
+ 2104 + + Constant.
+ 2105 + +
+ 2106 + + @par Exception Safety
+ 2107 + + No-throw guarantee.
+ 2108 + + */
+ 2109 + + BOOST_JSON_DECL
+ 2110 + + system::result<std::nullptr_t>
+ 2111 + + try_as_null() const noexcept;
+ 2112 + +
+ 2113 + + //------------------------------------------------------
+ 2114 + +
+ 2115 + + /** Return the underlying @ref object, or throw an exception.
+ 2116 + +
+ 2117 + + If @ref is_object() is `true`, returns a reference to the underlying
+ 2118 + + @ref object, otherwise throws an exception.
+ 2119 + +
+ 2120 + + @par Exception Safety
+ 2121 + + Strong guarantee.
+ 2122 + +
+ 2123 + + @throw boost::system::system_error `! this->is_object()`.
+ 2124 + +
+ 2125 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 2126 + + source location of the call site by default.
+ 2127 + +
+ 2128 + + @par Complexity
+ 2129 + + Constant.
+ 2130 + +
+ 2131 + + @{
+ 2132 + + */
+ 2133 + + object&
+ 2134 + +165 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &
+ 2135 + + {
+ 2136 + +165 auto& self = const_cast<value const&>(*this);
+ 2137 + +165 return const_cast<object&>( self.as_object(loc) );
+ 2138 + + }
+ 2139 + +
+ 2140 + + /// Overload
+ 2141 + + object&&
+ 2142 + +97 as_object(source_location const& loc = BOOST_CURRENT_LOCATION) &&
+ 2143 + + {
+ 2144 + +97 return std::move( as_object(loc) );
+ 2145 + + }
+ 2146 + +
+ 2147 + + /// Overload
+ 2148 + + BOOST_JSON_DECL
+ 2149 + + object const&
+ 2150 + + as_object(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
+ 2151 + + /// @}
+ 2152 + +
+ 2153 + + /** Return the underlying @ref array, or throw an exception.
+ 2154 + +
+ 2155 + + If @ref is_array() is `true`, returns a reference to the underlying
+ 2156 + + @ref array, otherwise throws an exception.
+ 2157 + +
+ 2158 + + @par Exception Safety
+ 2159 + + Strong guarantee.
+ 2160 + +
+ 2161 + + @throw boost::system::system_error `! this->is_array()`.
+ 2162 + +
+ 2163 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 2164 + + source location of the call site by default.
+ 2165 + +
+ 2166 + + @par Complexity
+ 2167 + + Constant.
+ 2168 + +
+ 2169 + + @{
+ 2170 + + */
+ 2171 + + array&
+ 2172 + +92 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &
+ 2173 + + {
+ 2174 + +92 auto& self = const_cast<value const&>(*this);
+ 2175 + +92 return const_cast<array&>( self.as_array(loc) );
+ 2176 + + }
+ 2177 + +
+ 2178 + + /// Overload
+ 2179 + + array&&
+ 2180 + +10 as_array(source_location const& loc = BOOST_CURRENT_LOCATION) &&
+ 2181 + + {
+ 2182 + +10 return std::move( as_array(loc) );
+ 2183 + + }
+ 2184 + +
+ 2185 + + /// Overload
+ 2186 + + BOOST_JSON_DECL
+ 2187 + + array const&
+ 2188 + + as_array(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
+ 2189 + + /// @}
+ 2190 + +
+ 2191 + + /** Return the underlying @ref string, or throw an exception.
+ 2192 + +
+ 2193 + + If @ref is_string() is `true`, returns a reference to the underlying
+ 2194 + + @ref string, otherwise throws an exception.
+ 2195 + +
+ 2196 + + @par Exception Safety
+ 2197 + + Strong guarantee.
+ 2198 + +
+ 2199 + + @throw boost::system::system_error `! this->is_string()`.
+ 2200 + +
+ 2201 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 2202 + + source location of the call site by default.
+ 2203 + +
+ 2204 + + @par Complexity
+ 2205 + + Constant.
+ 2206 + +
+ 2207 + + @{
+ 2208 + + */
+ 2209 + + string&
+ 2210 + +34 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &
+ 2211 + + {
+ 2212 + +34 auto& self = const_cast<value const&>(*this);
+ 2213 + +34 return const_cast<string&>( self.as_string(loc) );
+ 2214 + + }
+ 2215 + +
+ 2216 + + /// Overload
+ 2217 + + string&&
+ 2218 + +12 as_string(source_location const& loc = BOOST_CURRENT_LOCATION) &&
+ 2219 + + {
+ 2220 + +12 return std::move( as_string(loc) );
+ 2221 + + }
+ 2222 + +
+ 2223 + + /// Overload
+ 2224 + + BOOST_JSON_DECL
+ 2225 + + string const&
+ 2226 + + as_string(source_location const& loc = BOOST_CURRENT_LOCATION) const&;
+ 2227 + + /// @}
+ 2228 + +
+ 2229 + + /** Return the underlying `std::int64_t`, or throw an exception.
+ 2230 + +
+ 2231 + + If @ref is_int64() is `true`, returns a reference to **(1)** or a copy
+ 2232 + + of **(2)** the underlying `std::int64_t`, otherwise throws an
+ 2233 + + exception.
+ 2234 + +
+ 2235 + + @note This function is the intended for direct access to the underlying
+ 2236 + + object, __if__ it has the type `std::int64_t`. It does not convert the
+ 2237 + + underlying object to the type `std::int64_t` even if a lossless
+ 2238 + + conversion is possible. If you are not sure which kind your `value`
+ 2239 + + has, and you only care about getting a `std::int64_t` number, consider
+ 2240 + + using @ref to_number instead.
+ 2241 + +
+ 2242 + + @par Exception Safety
+ 2243 + + Strong guarantee.
+ 2244 + +
+ 2245 + + @throw boost::system::system_error `! this->is_int64()`.
+ 2246 + +
+ 2247 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 2248 + + source location of the call site by default.
+ 2249 + +
+ 2250 + + @par Complexity
+ 2251 + + Constant.
+ 2252 + +
+ 2253 + + @{
+ 2254 + + */
+ 2255 + + BOOST_JSON_DECL
+ 2256 + + std::int64_t&
+ 2257 + + as_int64(source_location const& loc = BOOST_CURRENT_LOCATION);
+ 2258 + +
+ 2259 + + /// Overload
+ 2260 + + BOOST_JSON_DECL
+ 2261 + + std::int64_t
+ 2262 + + as_int64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
+ 2263 + + /// @}
+ 2264 + +
+ 2265 + + /** Return the underlying `std::uint64_t`, or throw an exception.
+ 2266 + +
+ 2267 + + If @ref is_uint64() is `true`, returns a reference to **(1)** or a
+ 2268 + + copy of **(2)** the underlying `std::uint64_t`, otherwise throws an
+ 2269 + + exception.
+ 2270 + +
+ 2271 + + @note This function is intended for direct access to the underlying
+ 2272 + + object, __if__ it has the type `std::uint64_t`. It does not convert the
+ 2273 + + underlying object to the type `std::uint64_t` even if a lossless
+ 2274 + + conversion is possible. If you are not sure which kind your `value`
+ 2275 + + has, and you only care about getting a `std::uint64_t` number, consider
+ 2276 + + using @ref to_number instead.
+ 2277 + +
+ 2278 + + @par Exception Safety
+ 2279 + + Strong guarantee.
+ 2280 + +
+ 2281 + + @throw boost::system::system_error `! this->is_uint64()`.
+ 2282 + +
+ 2283 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 2284 + + source location of the call site by default.
+ 2285 + +
+ 2286 + + @par Complexity
+ 2287 + + Constant.
+ 2288 + +
+ 2289 + + @{
+ 2290 + + */
+ 2291 + + BOOST_JSON_DECL
+ 2292 + + std::uint64_t&
+ 2293 + + as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION);
+ 2294 + +
+ 2295 + + /// Overload
+ 2296 + + BOOST_JSON_DECL
+ 2297 + + std::uint64_t
+ 2298 + + as_uint64(source_location const& loc = BOOST_CURRENT_LOCATION) const;
+ 2299 + + /// @}
+ 2300 + +
+ 2301 + + /** Return the underlying `double`, or throw an exception.
+ 2302 + +
+ 2303 + + If @ref is_double() is `true`, returns a reference to **(1)** or a copy
+ 2304 + + of **(2)** the underlying `double`, otherwise throws an exception.
+ 2305 + +
+ 2306 + + @note This function is intended for direct access to the underlying
+ 2307 + + object, __if__ it has the type `double`. It does not convert the
+ 2308 + + underlying object to type `double` even if a lossless conversion is
+ 2309 + + possible. If you are not sure which kind your `value` has, and you only
+ 2310 + + care about getting a `double` number, consider using @ref to_number
+ 2311 + + instead.
+ 2312 + +
+ 2313 + + @par Exception Safety
+ 2314 + + Strong guarantee.
+ 2315 + +
+ 2316 + + @throw boost::system::system_error `! this->is_double()`.
+ 2317 + +
+ 2318 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 2319 + + source location of the call site by default.
+ 2320 + +
+ 2321 + + @par Complexity
+ 2322 + + Constant.
+ 2323 + +
+ 2324 + + @{
+ 2325 + + */
+ 2326 + + BOOST_JSON_DECL
+ 2327 + + double&
+ 2328 + + as_double(source_location const& loc = BOOST_CURRENT_LOCATION);
+ 2329 + +
+ 2330 + + /// Overload
+ 2331 + + BOOST_JSON_DECL
+ 2332 + + double
+ 2333 + + as_double(source_location const& loc = BOOST_CURRENT_LOCATION) const;
+ 2334 + + /// @}
+ 2335 + +
+ 2336 + + /** Return the underlying `bool`, or throw an exception.
+ 2337 + +
+ 2338 + + If @ref is_bool() is `true`, returns a reference to **(1)** or a copy
+ 2339 + + of **(2)** the underlying `bool`, otherwise throws an exception.
+ 2340 + +
+ 2341 + + @par Exception Safety
+ 2342 + + Strong guarantee.
+ 2343 + +
+ 2344 + + @throw boost::system::system_error `! this->is_bool()`.
+ 2345 + +
+ 2346 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 2347 + + source location of the call site by default.
+ 2348 + +
+ 2349 + + @par Complexity
+ 2350 + + Constant.
+ 2351 + +
+ 2352 + + @{
+ 2353 + + */
+ 2354 + + BOOST_JSON_DECL
+ 2355 + + bool&
+ 2356 + + as_bool(source_location const& loc = BOOST_CURRENT_LOCATION);
+ 2357 + +
+ 2358 + + /// Overload
+ 2359 + + BOOST_JSON_DECL
+ 2360 + + bool
+ 2361 + + as_bool(source_location const& loc = BOOST_CURRENT_LOCATION) const;
+ 2362 + + /// @}
+ 2363 + +
+ 2364 + + //------------------------------------------------------
+ 2365 + +
+ 2366 + + /** Return the underlying @ref object, without checking.
+ 2367 + +
+ 2368 + + This is the fastest way to access the underlying representation when
+ 2369 + + the kind is known in advance.
+ 2370 + +
+ 2371 + + @par Preconditions
+ 2372 + +
+ 2373 + + @code
+ 2374 + + this->is_object()
+ 2375 + + @endcode
+ 2376 + +
+ 2377 + + @par Complexity
+ 2378 + + Constant.
+ 2379 + +
+ 2380 + + @par Exception Safety
+ 2381 + + No-throw guarantee.
+ 2382 + +
+ 2383 + + @{
+ 2384 + + */
+ 2385 + + object&
+ 2386 + +38 get_object() & noexcept
+ 2387 + + {
+ 2388 + +38 BOOST_ASSERT(is_object());
+ 2389 + +38 return obj_;
+ 2390 + + }
+ 2391 + +
+ 2392 + + object&&
+ 2393 + +1 get_object() && noexcept
+ 2394 + + {
+ 2395 + +1 BOOST_ASSERT(is_object());
+ 2396 + +1 return std::move(obj_);
+ 2397 + + }
+ 2398 + +
+ 2399 + + object const&
+ 2400 + +52946 get_object() const& noexcept
+ 2401 + + {
+ 2402 + +52946 BOOST_ASSERT(is_object());
+ 2403 + +52946 return obj_;
+ 2404 + + }
+ 2405 + + /// @}
+ 2406 + +
+ 2407 + + /** Return the underlying @ref array, without checking.
+ 2408 + +
+ 2409 + + This is the fastest way to access the underlying representation when
+ 2410 + + the kind is known in advance.
+ 2411 + +
+ 2412 + + @par Preconditions
+ 2413 + +
+ 2414 + + @code
+ 2415 + + this->is_array()
+ 2416 + + @endcode
+ 2417 + +
+ 2418 + + @par Complexity
+ 2419 + + Constant.
+ 2420 + +
+ 2421 + + @par Exception Safety
+ 2422 + + No-throw guarantee.
+ 2423 + +
+ 2424 + + @{
+ 2425 + + */
+ 2426 + + array&
+ 2427 + +25 get_array() & noexcept
+ 2428 + + {
+ 2429 + +25 BOOST_ASSERT(is_array());
+ 2430 + +25 return arr_;
+ 2431 + + }
+ 2432 + +
+ 2433 + + array&&
+ 2434 + +1 get_array() && noexcept
+ 2435 + + {
+ 2436 + +1 BOOST_ASSERT(is_array());
+ 2437 + +1 return std::move(arr_);
+ 2438 + + }
+ 2439 + +
+ 2440 + + array const&
+ 2441 + +5699 get_array() const& noexcept
+ 2442 + + {
+ 2443 + +5699 BOOST_ASSERT(is_array());
+ 2444 + +5699 return arr_;
+ 2445 + + }
+ 2446 + + /// @}
+ 2447 + +
+ 2448 + + /** Return the underlying @ref string, without checking.
+ 2449 + +
+ 2450 + + This is the fastest way to access the underlying representation when
+ 2451 + + the kind is known in advance.
+ 2452 + +
+ 2453 + + @par Preconditions
+ 2454 + +
+ 2455 + + @code
+ 2456 + + this->is_string()
+ 2457 + + @endcode
+ 2458 + +
+ 2459 + + @par Complexity
+ 2460 + + Constant.
+ 2461 + +
+ 2462 + + @par Exception Safety
+ 2463 + + No-throw guarantee.
+ 2464 + +
+ 2465 + + @{
+ 2466 + + */
+ 2467 + + string&
+ 2468 + +8971 get_string() & noexcept
+ 2469 + + {
+ 2470 + +8971 BOOST_ASSERT(is_string());
+ 2471 + +8971 return str_;
+ 2472 + + }
+ 2473 + +
+ 2474 + + string&&
+ 2475 + +1 get_string() && noexcept
+ 2476 + + {
+ 2477 + +1 BOOST_ASSERT(is_string());
+ 2478 + +1 return std::move(str_);
+ 2479 + + }
+ 2480 + +
+ 2481 + + string const&
+ 2482 + +40931 get_string() const& noexcept
+ 2483 + + {
+ 2484 + +40931 BOOST_ASSERT(is_string());
+ 2485 + +40931 return str_;
+ 2486 + + }
+ 2487 + + /// @}
+ 2488 + +
+ 2489 + + /** Return the underlying `std::int64_t`, without checking.
+ 2490 + +
+ 2491 + + This is the fastest way to access the underlying representation when
+ 2492 + + the kind is known in advance.
+ 2493 + +
+ 2494 + + @par Preconditions
+ 2495 + +
+ 2496 + + @code
+ 2497 + + this->is_int64()
+ 2498 + + @endcode
+ 2499 + +
+ 2500 + + @par Complexity
+ 2501 + + Constant.
+ 2502 + +
+ 2503 + + @par Exception Safety
+ 2504 + + No-throw guarantee.
+ 2505 + +
+ 2506 + + @{
+ 2507 + + */
+ 2508 + + std::int64_t&
+ 2509 + +4 get_int64() noexcept
+ 2510 + + {
+ 2511 + +4 BOOST_ASSERT(is_int64());
+ 2512 + +4 return sca_.i;
+ 2513 + + }
+ 2514 + +
+ 2515 + + std::int64_t
+ 2516 + +14294 get_int64() const noexcept
+ 2517 + + {
+ 2518 + +14294 BOOST_ASSERT(is_int64());
+ 2519 + +14294 return sca_.i;
+ 2520 + + }
+ 2521 + + /// @}
+ 2522 + +
+ 2523 + + /** Return the underlying `std::uint64_t`, without checking.
+ 2524 + +
+ 2525 + + This is the fastest way to access the underlying representation when
+ 2526 + + the kind is known in advance.
+ 2527 + +
+ 2528 + + @par Preconditions
+ 2529 + +
+ 2530 + + @code
+ 2531 + + this->is_uint64()
+ 2532 + + @endcode
+ 2533 + +
+ 2534 + + @par Complexity
+ 2535 + + Constant.
+ 2536 + +
+ 2537 + + @par Exception Safety
+ 2538 + + No-throw guarantee.
+ 2539 + +
+ 2540 + + @{
+ 2541 + + */
+ 2542 + + std::uint64_t&
+ 2543 + +4 get_uint64() noexcept
+ 2544 + + {
+ 2545 + +4 BOOST_ASSERT(is_uint64());
+ 2546 + +4 return sca_.u;
+ 2547 + + }
+ 2548 + +
+ 2549 + + std::uint64_t
+ 2550 + +212 get_uint64() const noexcept
+ 2551 + + {
+ 2552 + +212 BOOST_ASSERT(is_uint64());
+ 2553 + +212 return sca_.u;
+ 2554 + + }
+ 2555 + + /// @}
+ 2556 + +
+ 2557 + + /** Return the underlying `double`, without checking.
+ 2558 + +
+ 2559 + + This is the fastest way to access the underlying
+ 2560 + + representation when the kind is known in advance.
+ 2561 + +
+ 2562 + + @par Preconditions
+ 2563 + +
+ 2564 + + @code
+ 2565 + + this->is_double()
+ 2566 + + @endcode
+ 2567 + +
+ 2568 + + @par Complexity
+ 2569 + + Constant.
+ 2570 + +
+ 2571 + + @par Exception Safety
+ 2572 + + No-throw guarantee.
+ 2573 + +
+ 2574 + + @{
+ 2575 + + */
+ 2576 + + double&
+ 2577 + +4 get_double() noexcept
+ 2578 + + {
+ 2579 + +4 BOOST_ASSERT(is_double());
+ 2580 + +4 return sca_.d;
+ 2581 + + }
+ 2582 + +
+ 2583 + + double
+ 2584 + +39178 get_double() const noexcept
+ 2585 + + {
+ 2586 + +39178 BOOST_ASSERT(is_double());
+ 2587 + +39178 return sca_.d;
+ 2588 + + }
+ 2589 + + /// @}
+ 2590 + +
+ 2591 + + /** Return the underlying `bool`, without checking.
+ 2592 + +
+ 2593 + + This is the fastest way to access the underlying representation when
+ 2594 + + the kind is known in advance.
+ 2595 + +
+ 2596 + + @par Preconditions
+ 2597 + +
+ 2598 + + @code
+ 2599 + + this->is_bool()
+ 2600 + + @endcode
+ 2601 + +
+ 2602 + + @par Complexity
+ 2603 + + Constant.
+ 2604 + +
+ 2605 + + @par Exception Safety
+ 2606 + + No-throw guarantee.
+ 2607 + +
+ 2608 + + @{
+ 2609 + + */
+ 2610 + + bool&
+ 2611 + +4 get_bool() noexcept
+ 2612 + + {
+ 2613 + +4 BOOST_ASSERT(is_bool());
+ 2614 + +4 return sca_.b;
+ 2615 + + }
+ 2616 + +
+ 2617 + + bool
+ 2618 + +804 get_bool() const noexcept
+ 2619 + + {
+ 2620 + +804 BOOST_ASSERT(is_bool());
+ 2621 + +804 return sca_.b;
+ 2622 + + }
+ 2623 + + /// @}
+ 2624 + +
+ 2625 + + //------------------------------------------------------
+ 2626 + +
+ 2627 + + /** Access an element, with bounds checking.
+ 2628 + +
+ 2629 + + Returns `boost::system::result` containing a reference to the element
+ 2630 + + of the underlying ccontainer, if such element exists. If the underlying
+ 2631 + + value is not a container of the suitable type or the container doesn't
+ 2632 + + have a corresponding element the result contains an `error_code`.
+ 2633 + +
+ 2634 + + , if `pos` is within its range. If `pos` is
+ 2635 + + outside of that range, or the underlying value is not an object the
+ 2636 + +
+ 2637 + + Returns @ref boost::system::result containing a reference to the
+ 2638 + + element of the underlying @ref array, if `pos` is within its range. If
+ 2639 + + `pos` is outside of that range, or the underlying value is not an array
+ 2640 + + the result contains an `error_code`.
+ 2641 + +
+ 2642 + + This function is used to access elements of
+ 2643 + + the underlying container, or throw an exception if that could not be
+ 2644 + + done.
+ 2645 + +
+ 2646 + + @li **(1)**, **(2)** require the underlying container to be an
+ 2647 + + @ref object, and look for an element with the key `key`.
+ 2648 + + @li **(3)**, **(4)** require the underlying container to be an
+ 2649 + + @ref array, and look for an element at index `pos`.
+ 2650 + +
+ 2651 + + @par Exception Safety
+ 2652 + + No-throw guarantee.
+ 2653 + +
+ 2654 + + @param key The key of the element to find.
+ 2655 + +
+ 2656 + + @par Complexity
+ 2657 + + Constant.
+ 2658 + +
+ 2659 + + @par Exception Safety
+ 2660 + + No-throw guarantee.
+ 2661 + +
+ 2662 + + @{
+ 2663 + + */
+ 2664 + + BOOST_JSON_DECL
+ 2665 + + boost::system::result<value&>
+ 2666 + + try_at(string_view key) noexcept;
+ 2667 + +
+ 2668 + + BOOST_JSON_DECL
+ 2669 + + boost::system::result<value const&>
+ 2670 + + try_at(string_view key) const noexcept;
+ 2671 + +
+ 2672 + + /** Overload
+ 2673 + +
+ 2674 + + @param pos A zero-based array index.
+ 2675 + + */
+ 2676 + + BOOST_JSON_DECL
+ 2677 + + boost::system::result<value&>
+ 2678 + + try_at(std::size_t pos) noexcept;
+ 2679 + +
+ 2680 + + /// Overload
+ 2681 + + BOOST_JSON_DECL
+ 2682 + + boost::system::result<value const&>
+ 2683 + + try_at(std::size_t pos) const noexcept;
+ 2684 + + /// @}
+ 2685 + +
+ 2686 + +
+ 2687 + + /** Access an element, with bounds checking.
+ 2688 + +
+ 2689 + + This function is used to access elements of
+ 2690 + + the underlying container, or throw an exception if that could not be
+ 2691 + + done.
+ 2692 + +
+ 2693 + + @li **(1)**--**(3)** is equivalent to
+ 2694 + + `this->as_object(loc).at(key, loc)`.
+ 2695 + + @li **(4)**--**(6)** is equivalent to
+ 2696 + + `this->as_array(loc).at(pos, loc)`.
+ 2697 + +
+ 2698 + + @par Complexity
+ 2699 + + Constant.
+ 2700 + +
+ 2701 + + @par Exception Safety
+ 2702 + + Strong guarantee.
+ 2703 + +
+ 2704 + + @param key The key of the element to find.
+ 2705 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 2706 + + source location of the call site by default.
+ 2707 + +
+ 2708 + + @throw boost::system::system_error The underlying type of value is not
+ 2709 + + the container type corresponding to the first argument (i.e.
+ 2710 + + using an index with an @ref object).
+ 2711 + + @throw boost::system::system_error An element corresponding to the
+ 2712 + + first argument was not found.
+ 2713 + +
+ 2714 + + @see @ref as_array, @ref as_object.
+ 2715 + +
+ 2716 + + @{
+ 2717 + + */
+ 2718 + + value&
+ 2719 + +12 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &
+ 2720 + + {
+ 2721 + +12 return as_object(loc).at(key, loc);
+ 2722 + + }
+ 2723 + +
+ 2724 + + /// Overload
+ 2725 + + value&&
+ 2726 + +1 at(string_view key, source_location const& loc = BOOST_CURRENT_LOCATION) &&
+ 2727 + + {
+ 2728 + +1 return std::move( as_object(loc) ).at(key, loc);
+ 2729 + + }
+ 2730 + +
+ 2731 + + /// Overload
+ 2732 + + value const&
+ 2733 + +18 at(
+ 2734 + + string_view key,
+ 2735 + + source_location const& loc = BOOST_CURRENT_LOCATION) const&
+ 2736 + + {
+ 2737 + +18 return as_object(loc).at(key, loc);
+ 2738 + + }
+ 2739 + +
+ 2740 + + /** Overload
+ 2741 + +
+ 2742 + + @param pos A zero-based array index.
+ 2743 + + @param loc
+ 2744 + + */
+ 2745 + + value &
+ 2746 + +12 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &
+ 2747 + + {
+ 2748 + +12 return as_array(loc).at(pos, loc);
+ 2749 + + }
+ 2750 + +
+ 2751 + + /// Overload
+ 2752 + + value&&
+ 2753 + +10 at(std::size_t pos, source_location const& loc = BOOST_CURRENT_LOCATION) &&
+ 2754 + + {
+ 2755 + +10 return std::move( as_array(loc) ).at(pos, loc);
+ 2756 + + }
+ 2757 + +
+ 2758 + + /// Overload
+ 2759 + + value const&
+ 2760 + +56 at(std::size_t pos,
+ 2761 + + source_location const& loc = BOOST_CURRENT_LOCATION) const&
+ 2762 + + {
+ 2763 + +56 return as_array(loc).at(pos, loc);
+ 2764 + + }
+ 2765 + + /// @}
+ 2766 + +
+ 2767 + + /** Access an element via JSON Pointer.
+ 2768 + +
+ 2769 + + This function is used to access a (potentially nested) element of the
+ 2770 + + value using a JSON Pointer string.
+ 2771 + +
+ 2772 + + @par Complexity
+ 2773 + + Linear in the sizes of `ptr` and underlying array, object, or string.
+ 2774 + +
+ 2775 + + @par Exception Safety
+ 2776 + + No-throw guarantee.
+ 2777 + +
+ 2778 + + @param ptr JSON Pointer string.
+ 2779 + +
+ 2780 + + @return @ref boost::system::result containing either a reference to the
+ 2781 + + element identified by `ptr` or a corresponding `error_code`.
+ 2782 + +
+ 2783 + + @see
+ 2784 + + [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
+ 2785 + +
+ 2786 + + @{
+ 2787 + + */
+ 2788 + + BOOST_JSON_DECL
+ 2789 + + system::result<value const&>
+ 2790 + + try_at_pointer(string_view ptr) const noexcept;
+ 2791 + +
+ 2792 + + BOOST_JSON_DECL
+ 2793 + + system::result<value&>
+ 2794 + + try_at_pointer(string_view ptr) noexcept;
+ 2795 + + /// @}
+ 2796 + +
+ 2797 + + /** Access an element via JSON Pointer.
+ 2798 + +
+ 2799 + + This function is used to access a (potentially nested) element of the
+ 2800 + + value using a JSON Pointer string.
+ 2801 + +
+ 2802 + + @par Complexity
+ 2803 + + Linear in the sizes of `ptr` and the underlying container.
+ 2804 + +
+ 2805 + + @par Exception Safety
+ 2806 + + Strong guarantee.
+ 2807 + +
+ 2808 + + @param ptr JSON Pointer string.
+ 2809 + + @param loc @ref boost::source_location to use in thrown exception; the
+ 2810 + + source location of the call site by default.
+ 2811 + +
+ 2812 + + @return reference to the element identified by `ptr`.
+ 2813 + +
+ 2814 + + @throw boost::system::system_error if an error occurs.
+ 2815 + +
+ 2816 + + @see
+ 2817 + + [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
+ 2818 + +
+ 2819 + + @{
+ 2820 + + */
+ 2821 + + BOOST_JSON_DECL
+ 2822 + + value const&
+ 2823 + + at_pointer(
+ 2824 + + string_view ptr,
+ 2825 + + source_location const& loc = BOOST_CURRENT_LOCATION) const&;
+ 2826 + +
+ 2827 + + /// Overload
+ 2828 + + inline
+ 2829 + + value&&
+ 2830 + + at_pointer(
+ 2831 + + string_view ptr,
+ 2832 + + source_location const& loc = BOOST_CURRENT_LOCATION) &&;
+ 2833 + +
+ 2834 + + /// Overload
+ 2835 + + inline
+ 2836 + + value&
+ 2837 + + at_pointer(
+ 2838 + + string_view ptr,
+ 2839 + + source_location const& loc = BOOST_CURRENT_LOCATION) &;
+ 2840 + + /// @}
+ 2841 + +
+ 2842 + + /** Access an element via JSON Pointer.
+ 2843 + +
+ 2844 + + This function is used to access a (potentially nested) element of the
+ 2845 + + value using a JSON Pointer string.
+ 2846 + +
+ 2847 + + @par Complexity
+ 2848 + + Linear in the sizes of `ptr` and underlying container.
+ 2849 + +
+ 2850 + + @par Exception Safety
+ 2851 + + No-throw guarantee.
+ 2852 + +
+ 2853 + + @param ptr JSON Pointer string.
+ 2854 + + @param ec Set to the error, if any occurred.
+ 2855 + +
+ 2856 + + @return pointer to the element identified by `ptr`.
+ 2857 + +
+ 2858 + + @see
+ 2859 + + [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901)
+ 2860 + +
+ 2861 + + @{
+ 2862 + + */
+ 2863 + + BOOST_JSON_DECL
+ 2864 + + value const*
+ 2865 + + find_pointer(string_view ptr, system::error_code& ec) const noexcept;
+ 2866 + +
+ 2867 + + BOOST_JSON_DECL
+ 2868 + + value*
+ 2869 + + find_pointer(string_view ptr, system::error_code& ec) noexcept;
+ 2870 + +
+ 2871 + + BOOST_JSON_DECL
+ 2872 + + value const*
+ 2873 + + find_pointer(string_view ptr, std::error_code& ec) const noexcept;
+ 2874 + +
+ 2875 + + BOOST_JSON_DECL
+ 2876 + + value*
+ 2877 + + find_pointer(string_view ptr, std::error_code& ec) noexcept;
+ 2878 + + /// @}
+ 2879 + +
+ 2880 + + //------------------------------------------------------
+ 2881 + +
+ 2882 + + /** Set an element via JSON Pointer.
+ 2883 + +
+ 2884 + + This function is used to insert or assign to a potentially nested
+ 2885 + + element of the value using a JSON Pointer string. The function may
+ 2886 + + create intermediate elements corresponding to pointer segments.
+ 2887 + +
+ 2888 + + The particular conditions when and what kind of intermediate element
+ 2889 + + is created is governed by the `ptr` parameter.
+ 2890 + +
+ 2891 + + Each pointer token is considered in sequence. For each token
+ 2892 + +
+ 2893 + + - if the containing value is an @ref object, then a new `null`
+ 2894 + + element is created with key equal to unescaped token string;
+ 2895 + + otherwise
+ 2896 + +
+ 2897 + + - if the containing value is an @ref array, and the token represents a
+ 2898 + + past-the-end marker, then a `null` element is appended to the array;
+ 2899 + + otherwise
+ 2900 + +
+ 2901 + + - if the containing value is an @ref array, and the token represents a
+ 2902 + + number, then if the difference between the number and array's size
+ 2903 + + is smaller than `opts.max_created_elements`, then the size of the
+ 2904 + + array is increased, so that the number can reference an element in the
+ 2905 + + array; otherwise
+ 2906 + +
+ 2907 + + - if the containing value is of different @ref kind and
+ 2908 + + `opts.replace_any_scalar` is `true`, or the value is `null`, then
+ 2909 + +
+ 2910 + + - if `opts.create_arrays` is `true` and the token either represents
+ 2911 + + past-the-end marker or a number, then the value is replaced with
+ 2912 + + an empty array and the token is considered again; otherwise
+ 2913 + +
+ 2914 + + - if `opts.create_objects` is `true`, then the value is replaced
+ 2915 + + with an empty object and the token is considered again; otherwise
+ 2916 + +
+ 2917 + + - an error is produced.
+ 2918 + +
+ 2919 + + @par Complexity
+ 2920 + + Linear in the sum of size of `ptr`, size of underlying array, object,
+ 2921 + + or string and `opts.max_created_elements`.
+ 2922 + +
+ 2923 + + @par Exception Safety
+ 2924 + + Basic guarantee. Calls to `memory_resource::allocate` may throw.
+ 2925 + +
+ 2926 + + @param sv JSON Pointer string.
+ 2927 + + @param ref The value to assign to pointed element.
+ 2928 + + @param opts The options for the algorithm.
+ 2929 + +
+ 2930 + + @return @ref boost::system::result containing either a reference to the
+ 2931 + + element identified by `ptr` or a corresponding `error_code`.
+ 2932 + +
+ 2933 + + @see
+ 2934 + + @ref set_pointer_options,
+ 2935 + + [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901).
+ 2936 + + */
+ 2937 + + BOOST_JSON_DECL
+ 2938 + + system::result<value&>
+ 2939 + + try_set_at_pointer(
+ 2940 + + string_view sv,
+ 2941 + + value_ref ref,
+ 2942 + + set_pointer_options const& opts = {} );
+ 2943 + +
+ 2944 + + /** Set an element via JSON Pointer.
+ 2945 + +
+ 2946 + + This function is used to insert or assign to a potentially nested
+ 2947 + + element of the value using a JSON Pointer string. The function may
+ 2948 + + create intermediate elements corresponding to pointer segments.
+ 2949 + +
+ 2950 + + The particular conditions when and what kind of intermediate element
+ 2951 + + is created is governed by the `ptr` parameter.
+ 2952 + +
+ 2953 + + Each pointer token is considered in sequence. For each token
+ 2954 + +
+ 2955 + + - if the containing value is an @ref object, then a new `null`
+ 2956 + + element is created with key equal to unescaped token string; otherwise
+ 2957 + +
+ 2958 + + - if the containing value is an @ref array, and the token represents a
+ 2959 + + past-the-end marker, then a `null` element is appended to the array;
+ 2960 + + otherwise
+ 2961 + +
+ 2962 + + - if the containing value is an @ref array, and the token represents a
+ 2963 + + number, then if the difference between the number and array's size
+ 2964 + + is smaller than `opts.max_created_elements`, then the size of the
+ 2965 + + array is increased, so that the number can reference an element in the
+ 2966 + + array; otherwise
+ 2967 + +
+ 2968 + + - if the containing value is of different @ref kind and
+ 2969 + + `opts.replace_any_scalar` is `true`, or the value is `null`, then
+ 2970 + +
+ 2971 + + - if `opts.create_arrays` is `true` and the token either represents
+ 2972 + + past-the-end marker or a number, then the value is replaced with
+ 2973 + + an empty array and the token is considered again; otherwise
+ 2974 + +
+ 2975 + + - if `opts.create_objects` is `true`, then the value is replaced
+ 2976 + + with an empty object and the token is considered again; otherwise
+ 2977 + +
+ 2978 + + - an error is produced.
+ 2979 + +
+ 2980 + + @par Complexity
+ 2981 + + Linear in the sum of size of `ptr`, size of underlying array, object,
+ 2982 + + or string and `opts.max_created_elements`.
+ 2983 + +
+ 2984 + + @par Exception Safety
+ 2985 + + Basic guarantee.
+ 2986 + + Calls to `memory_resource::allocate` may throw.
+ 2987 + +
+ 2988 + + @param sv JSON Pointer string.
+ 2989 + +
+ 2990 + + @param ref The value to assign to pointed element.
+ 2991 + +
+ 2992 + + @param opts The options for the algorithm.
+ 2993 + +
+ 2994 + + @return Reference to the element identified by `ptr`.
+ 2995 + +
+ 2996 + + @throws boost::system::system_error Overload **(1)** reports errors by
+ 2997 + + throwing exceptions.
+ 2998 + +
+ 2999 + + @see @ref set_pointer_options,
+ 3000 + + [RFC 6901 - JavaScript Object Notation (JSON) Pointer](https://datatracker.ietf.org/doc/html/rfc6901">).
+ 3001 + +
+ 3002 + + @{
+ 3003 + + */
+ 3004 + + BOOST_JSON_DECL
+ 3005 + + value&
+ 3006 + + set_at_pointer(
+ 3007 + + string_view sv,
+ 3008 + + value_ref ref,
+ 3009 + + set_pointer_options const& opts = {} );
+ 3010 + +
+ 3011 + + /** Overload
+ 3012 + +
+ 3013 + + @param ec Set to the error, if any occurred.
+ 3014 + + @param sv
+ 3015 + + @param ref
+ 3016 + + @param opts
+ 3017 + + */
+ 3018 + + BOOST_JSON_DECL
+ 3019 + + value*
+ 3020 + + set_at_pointer(
+ 3021 + + string_view sv,
+ 3022 + + value_ref ref,
+ 3023 + + system::error_code& ec,
+ 3024 + + set_pointer_options const& opts = {} );
+ 3025 + +
+ 3026 + + /// Overload
+ 3027 + + BOOST_JSON_DECL
+ 3028 + + value*
+ 3029 + + set_at_pointer(
+ 3030 + + string_view sv,
+ 3031 + + value_ref ref,
+ 3032 + + std::error_code& ec,
+ 3033 + + set_pointer_options const& opts = {} );
+ 3034 + + /// @}
+ 3035 + +
+ 3036 + + //------------------------------------------------------
+ 3037 + +
+ 3038 + + /** Check if two values are equal.
+ 3039 + +
+ 3040 + + Two values are equal when they are the same kind and their referenced
+ 3041 + + values are equal, or when they are both integral types and their
+ 3042 + + integral representations are equal.
+ 3043 + +
+ 3044 + + @par Complexity
+ 3045 + + Constant or linear in the size of the underlying @ref array, @ref object,
+ 3046 + + or @ref string.
+ 3047 + +
+ 3048 + + @par Exception Safety
+ 3049 + + No-throw guarantee.
+ 3050 + + */
+ 3051 + + // inline friend speeds up overload resolution
+ 3052 + + friend
+ 3053 + + bool
+ 3054 + +4156 operator==(
+ 3055 + + value const& lhs,
+ 3056 + + value const& rhs) noexcept
+ 3057 + + {
+ 3058 + +4156 return lhs.equal(rhs);
+ 3059 + + }
+ 3060 + +
+ 3061 + + /** Check if two values are not equal.
+ 3062 + +
+ 3063 + + Two values are equal when they are the same kind and their referenced
+ 3064 + + values are equal, or when they are both integral types and their
+ 3065 + + integral representations are equal.
+ 3066 + +
+ 3067 + + @par Complexity
+ 3068 + + Constant or linear in the size of the underlying @ref array,
+ 3069 + + @ref object, or @ref string.
+ 3070 + +
+ 3071 + + @par Exception Safety
+ 3072 + + No-throw guarantee.
+ 3073 + + */
+ 3074 + + friend
+ 3075 + + bool
+ 3076 + +3978 operator!=(
+ 3077 + + value const& lhs,
+ 3078 + + value const& rhs) noexcept
+ 3079 + + {
+ 3080 + +3978 return ! (lhs == rhs);
+ 3081 + + }
+ 3082 + +
+ 3083 + + /** Serialize @ref value to an output stream.
+ 3084 + +
+ 3085 + + This function serializes a `value` as JSON text into the output stream.
+ 3086 + +
+ 3087 + + @return Reference to `os`.
+ 3088 + +
+ 3089 + + @par Complexity
+ 3090 + + Constant or linear in the size of `jv`.
+ 3091 + +
+ 3092 + + @par Exception Safety
+ 3093 + + Strong guarantee.
+ 3094 + + Calls to `memory_resource::allocate` may throw.
+ 3095 + +
+ 3096 + + @param os The output stream to serialize to.
+ 3097 + +
+ 3098 + + @param jv The value to serialize.
+ 3099 + + */
+ 3100 + + BOOST_JSON_DECL
+ 3101 + + friend
+ 3102 + + std::ostream&
+ 3103 + + operator<<(
+ 3104 + + std::ostream& os,
+ 3105 + + value const& jv);
+ 3106 + +
+ 3107 + + /** Parse @ref value from an input stream.
+ 3108 + +
+ 3109 + + This function parses JSON from an input stream into a `value`. If
+ 3110 + + parsing fails, @ref std::ios_base::failbit will be set for `is` and
+ 3111 + + `jv` will be left unchanged. Regardless of whether @ref
+ 3112 + + std::ios_base::skipws flag is set on `is`, consumes whitespace before
+ 3113 + + and after JSON, because whitespace is considered a part of JSON.
+ 3114 + + Behaves as
+ 3115 + + [_FormattedInputFunction_](https://en.cppreference.com/w/cpp/named_req/FormattedInputFunction).
+ 3116 + +
+ 3117 + + @note This operator cannot assume that the stream only contains a
+ 3118 + + single JSON document, which may result in **very underwhelming
+ 3119 + + performance**, if the stream isn't cooperative. If you know that your
+ 3120 + + input consists of a single JSON document, consider using @ref parse
+ 3121 + + function instead.
+ 3122 + +
+ 3123 + + @return Reference to `is`.
+ 3124 + +
+ 3125 + + @par Complexity
+ 3126 + + Linear in the size of JSON data.
+ 3127 + +
+ 3128 + + @par Exception Safety
+ 3129 + + Basic guarantee.
+ 3130 + + Calls to `memory_resource::allocate` may throw.
+ 3131 + + The stream may throw as configured by @ref std::ios::exceptions.
+ 3132 + +
+ 3133 + + @param is The input stream to parse from.
+ 3134 + +
+ 3135 + + @param jv The value to parse into.
+ 3136 + +
+ 3137 + + @see @ref parse.
+ 3138 + + */
+ 3139 + + BOOST_JSON_DECL
+ 3140 + + friend
+ 3141 + + std::istream&
+ 3142 + + operator>>(
+ 3143 + + std::istream& is,
+ 3144 + + value& jv);
+ 3145 + +
+ 3146 + + /** Helper for @ref boost::hash support.
+ 3147 + +
+ 3148 + + Computes a hash value for `jv`. This function is used by
+ 3149 + + `boost::hash<value>`. Similar overloads for @ref array, @ref object,
+ 3150 + + and @ref string do not exist, because those types are supported by
+ 3151 + + `boost::hash` out of the box.
+ 3152 + +
+ 3153 + + @return hash value for `jv`.
+ 3154 + +
+ 3155 + + @param jv `value` for which a hash is to be computed.
+ 3156 + +
+ 3157 + + @see [Boost.ContainerHash](https://boost.org/libs/container_hash).
+ 3158 + + */
+ 3159 + + #ifndef BOOST_JSON_DOCS
+ 3160 + + template<
+ 3161 + + class T,
+ 3162 + + typename std::enable_if<
+ 3163 + + std::is_same< detail::remove_cvref<T>, value >::value >::type*
+ 3164 + + = nullptr>
+ 3165 + + friend
+ 3166 + + std::size_t
+ 3167 + +248 hash_value( T const& jv ) noexcept
+ 3168 + + #else
+ 3169 + + friend
+ 3170 + + inline
+ 3171 + + std::size_t
+ 3172 + + hash_value( value const& jv ) noexcept
+ 3173 + + #endif
+ 3174 + + {
+ 3175 + +248 return detail::hash_value_impl(jv);
+ 3176 + + }
+ 3177 + +
+ 3178 + + private:
+ 3179 + + static
+ 3180 + + void
+ 3181 + +2133459 relocate(
+ 3182 + + value* dest,
+ 3183 + + value const& src) noexcept
+ 3184 + + {
+ 3185 + +2133459 std::memcpy(
+ 3186 + + static_cast<void*>(dest),
+ 3187 + + &src,
+ 3188 + + sizeof(src));
+ 3189 + +2133459 }
+ 3190 + +
+ 3191 + + BOOST_JSON_DECL
+ 3192 + + storage_ptr
+ 3193 + + destroy() noexcept;
+ 3194 + +
+ 3195 + + BOOST_JSON_DECL
+ 3196 + + bool
+ 3197 + + equal(value const& other) const noexcept;
+ 3198 + +
+ 3199 + + template<class T>
+ 3200 + + auto
+ 3201 + +3408 to_number(error& e) const noexcept ->
+ 3202 + + typename std::enable_if<
+ 3203 + + std::is_signed<T>::value &&
+ 3204 + + ! std::is_floating_point<T>::value,
+ 3205 + + T>::type
+ 3206 + + {
+ 3207 + +3408 if(sca_.k == json::kind::int64)
+ 3208 + + {
+ 3209 + +3321 auto const i = sca_.i;
+ 3210 + +6636 if( i >= (std::numeric_limits<T>::min)() &&
+ 3211 + +3315 i <= (std::numeric_limits<T>::max)())
+ 3212 + + {
+ 3213 + +3309 e = {};
+ 3214 + +3309 return static_cast<T>(i);
+ 3215 + + }
+ 3216 + +12 e = error::not_exact;
+ 3217 + + }
+ 3218 + +87 else if(sca_.k == json::kind::uint64)
+ 3219 + + {
+ 3220 + +20 auto const u = sca_.u;
+ 3221 + +20 if(u <= static_cast<std::uint64_t>((
+ 3222 + +20 std::numeric_limits<T>::max)()))
+ 3223 + + {
+ 3224 + +10 e = {};
+ 3225 + +10 return static_cast<T>(u);
+ 3226 + + }
+ 3227 + +10 e = error::not_exact;
+ 3228 + + }
+ 3229 + +67 else if(sca_.k == json::kind::double_)
+ 3230 + + {
+ 3231 + +20 auto const d = sca_.d;
+ 3232 + +20 if( d >= static_cast<double>(
+ 3233 + +40 (detail::to_number_limit<T>::min)()) &&
+ 3234 + + d <= static_cast<double>(
+ 3235 + +40 (detail::to_number_limit<T>::max)()) &&
+ 3236 + +20 static_cast<T>(d) == d)
+ 3237 + + {
+ 3238 + +9 e = {};
+ 3239 + +9 return static_cast<T>(d);
+ 3240 + + }
+ 3241 + +11 e = error::not_exact;
+ 3242 + + }
+ 3243 + + else
+ 3244 + + {
+ 3245 + +47 e = error::not_number;
+ 3246 + + }
+ 3247 + +80 return T{};
+ 3248 + + }
+ 3249 + +
+ 3250 + + template<class T>
+ 3251 + + auto
+ 3252 + +119 to_number(error& e) const noexcept ->
+ 3253 + + typename std::enable_if<
+ 3254 + + std::is_unsigned<T>::value &&
+ 3255 + + ! std::is_same<T, bool>::value,
+ 3256 + + T>::type
+ 3257 + + {
+ 3258 + +119 if(sca_.k == json::kind::int64)
+ 3259 + + {
+ 3260 + +44 auto const i = sca_.i;
+ 3261 + +72 if( i >= 0 && static_cast<std::uint64_t>(i) <=
+ 3262 + +28 (std::numeric_limits<T>::max)())
+ 3263 + + {
+ 3264 + +22 e = {};
+ 3265 + +22 return static_cast<T>(i);
+ 3266 + + }
+ 3267 + +22 e = error::not_exact;
+ 3268 + + }
+ 3269 + +75 else if(sca_.k == json::kind::uint64)
+ 3270 + + {
+ 3271 + +58 auto const u = sca_.u;
+ 3272 + +58 if(u <= (std::numeric_limits<T>::max)())
+ 3273 + + {
+ 3274 + +52 e = {};
+ 3275 + +52 return static_cast<T>(u);
+ 3276 + + }
+ 3277 + +6 e = error::not_exact;
+ 3278 + + }
+ 3279 + +17 else if(sca_.k == json::kind::double_)
+ 3280 + + {
+ 3281 + +12 auto const d = sca_.d;
+ 3282 + +8 if( d >= 0 &&
+ 3283 + +20 d <= (detail::to_number_limit<T>::max)() &&
+ 3284 + +8 static_cast<T>(d) == d)
+ 3285 + + {
+ 3286 + +4 e = {};
+ 3287 + +4 return static_cast<T>(d);
+ 3288 + + }
+ 3289 + +8 e = error::not_exact;
+ 3290 + + }
+ 3291 + + else
+ 3292 + + {
+ 3293 + +5 e = error::not_number;
+ 3294 + + }
+ 3295 + +41 return T{};
+ 3296 + + }
+ 3297 + +
+ 3298 + + template<class T>
+ 3299 + + auto
+ 3300 + +67 to_number(error& e) const noexcept ->
+ 3301 + + typename std::enable_if<
+ 3302 + + std::is_floating_point<
+ 3303 + + T>::value, T>::type
+ 3304 + + {
+ 3305 + +67 if(sca_.k == json::kind::int64)
+ 3306 + + {
+ 3307 + +16 e = {};
+ 3308 + +16 return static_cast<T>(sca_.i);
+ 3309 + + }
+ 3310 + +51 if(sca_.k == json::kind::uint64)
+ 3311 + + {
+ 3312 + +10 e = {};
+ 3313 + +10 return static_cast<T>(sca_.u);
+ 3314 + + }
+ 3315 + +41 if(sca_.k == json::kind::double_)
+ 3316 + + {
+ 3317 + +27 e = {};
+ 3318 + +27 return static_cast<T>(sca_.d);
+ 3319 + + }
+ 3320 + +14 e = error::not_number;
+ 3321 + +14 return {};
+ 3322 + + }
+ 3323 + + };
+ 3324 + +
+ 3325 + + // Make sure things are as big as we think they should be
+ 3326 + + #if BOOST_JSON_ARCH == 64
+ 3327 + + BOOST_CORE_STATIC_ASSERT( sizeof(value) == 24 );
+ 3328 + + #elif BOOST_JSON_ARCH == 32
+ 3329 + + BOOST_CORE_STATIC_ASSERT( sizeof(value) == 16 );
+ 3330 + + #else
+ 3331 + + # error Unknown architecture
+ 3332 + + #endif
+ 3333 + +
+ 3334 + + //----------------------------------------------------------
+ 3335 + +
+ 3336 + + /** A key/value pair.
+ 3337 + +
+ 3338 + + This is the type of element used by the @ref object container.
+ 3339 + + */
+ 3340 + + class key_value_pair
+ 3341 + + {
+ 3342 + + #ifndef BOOST_JSON_DOCS
+ 3343 + + friend struct detail::access;
+ 3344 + + using access = detail::access;
+ 3345 + + #endif
+ 3346 + +
+ 3347 + + BOOST_JSON_DECL
+ 3348 + + static char const empty_[1];
+ 3349 + +
+ 3350 + + inline
+ 3351 + + key_value_pair(
+ 3352 + + pilfered<json::value> k,
+ 3353 + + pilfered<json::value> v) noexcept;
+ 3354 + +
+ 3355 + + public:
+ 3356 + + /** Assignment
+ 3357 + +
+ 3358 + + This type is not copy or move-assignable. The copy assignment operator
+ 3359 + + is deleted.
+ 3360 + + */
+ 3361 + + key_value_pair&
+ 3362 + + operator=(key_value_pair const&) = delete;
+ 3363 + +
+ 3364 + + /** Destructor.
+ 3365 + +
+ 3366 + + The value is destroyed and all internally allocated memory is freed.
+ 3367 + + */
+ 3368 + +59048 ~key_value_pair() noexcept
+ 3369 + +52298 {
+ 3370 + +59048 auto const& sp = value_.storage();
+ 3371 + +59048 if(sp.is_not_shared_and_deallocate_is_trivial())
+ 3372 + + return;
+ 3373 + +59048 if(key_ == empty_)
+ 3374 + +6750 return;
+ 3375 + +52298 sp->deallocate(const_cast<char*>(key_),
+ 3376 + +52298 len_ + 1, alignof(char));
+ 3377 + +59048 }
+ 3378 + +
+ 3379 + + /** Constructors.
+ 3380 + +
+ 3381 + + Construct a key/value pair.
+ 3382 + +
+ 3383 + + @li **(1)** uses a copy of the characters of `key`, and constructs the
+ 3384 + + value as if by `value(std::forward<Args>(args)...)`.
+ 3385 + + @li **(2)** equivalent to `key_value_pair(p.first, p.second, sp)`.
+ 3386 + + @li **(3)** equivalent to
+ 3387 + + `key_value_pair(p.first, std::move(p.second), sp)`.
+ 3388 + + @li **(4)** equivalent to
+ 3389 + + `key_value_pair(other.key(), other.value(), sp)`.
+ 3390 + + @li **(5)** equivalent to
+ 3391 + + `key_value_pair(other.key(), other.value(), other.storage())`.
+ 3392 + + @li **(6)** the pair s constructed by acquiring ownership of the
+ 3393 + + contents of `other` using move semantics.
+ 3394 + + @li **(7)** the pair is constructed by acquiring ownership of the
+ 3395 + + contents of `other` using pilfer semantics. This is more efficient
+ 3396 + + than move construction, when it is known that the moved-from object
+ 3397 + + will be immediately destroyed afterwards.
+ 3398 + +
+ 3399 + + With **(2)**, **(3)**, **(4)** the pair uses the memory resource of
+ 3400 + + `sp`. With **(5)**, **(6)**, **(7)** it uses the memory resource of
+ 3401 + + `other.storage()`. With **(1)** it uses whatever memory resource
+ 3402 + + `value(std::forward<Args>(args)...)` would use. In any case the pair
+ 3403 + + acquires shared ownership of its memory resource
+ 3404 + +
+ 3405 + + After **(6)** `other` holds an empty key, and a null value with its
+ 3406 + + current storage pointer.
+ 3407 + +
+ 3408 + + After **(7)** `other` is not in a usable state and may only be destroyed.
+ 3409 + +
+ 3410 + + @par Complexity
+ 3411 + + Constant.
+ 3412 + +
+ 3413 + + @par Exception Safety
+ 3414 + + Strong guarantee. Calls to `memory_resource::allocate` may throw.
+ 3415 + + @param key The key string to use.
+ 3416 + + @param args Optional arguments forwarded to the @ref value constructor.
+ 3417 + +
+ 3418 + + @throw boost::system::system_error The size of the key would exceed
+ 3419 + + @ref string::max_size.
+ 3420 + +
+ 3421 + + @see @ref pilfer,
+ 3422 + + [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
+ 3423 + +
+ 3424 + + @{
+ 3425 + + */
+ 3426 + + template<class... Args>
+ 3427 + + explicit
+ 3428 + +7882 key_value_pair(
+ 3429 + + string_view key,
+ 3430 + + Args&&... args)
+ 3431 + +7883 : value_(std::forward<Args>(args)...)
+ 3432 + + {
+ 3433 + +7881 if(key.size() > string::max_size())
+ 3434 + + {
+ 3435 + + BOOST_STATIC_CONSTEXPR source_location loc = BOOST_CURRENT_LOCATION;
+ 3436 + +1 detail::throw_system_error( error::key_too_large, &loc );
+ 3437 + + }
+ 3438 + + auto s = reinterpret_cast<
+ 3439 + +7880 char*>(value_.storage()->
+ 3440 + +7880 allocate(key.size() + 1, alignof(char)));
+ 3441 + +7574 std::memcpy(s, key.data(), key.size());
+ 3442 + +7574 s[key.size()] = 0;
+ 3443 + +7574 key_ = s;
+ 3444 + +7574 len_ = static_cast<
+ 3445 + +7574 std::uint32_t>(key.size());
+ 3446 + +7881 }
+ 3447 + +
+ 3448 + + /** Overload
+ 3449 + +
+ 3450 + + @param p A `std::pair` with the key string and @ref value to construct
+ 3451 + + with.
+ 3452 + + @param sp A pointer to the @ref boost::container::pmr::memory_resource
+ 3453 + + to use.
+ 3454 + + */
+ 3455 + + explicit
+ 3456 + + key_value_pair(
+ 3457 + + std::pair<
+ 3458 + + string_view,
+ 3459 + + json::value> const& p,
+ 3460 + + storage_ptr sp = {})
+ 3461 + + : key_value_pair(
+ 3462 + + p.first,
+ 3463 + + p.second,
+ 3464 + + std::move(sp))
+ 3465 + + {
+ 3466 + + }
+ 3467 + +
+ 3468 + + /// Overload
+ 3469 + + explicit
+ 3470 + +3125 key_value_pair(
+ 3471 + + std::pair<
+ 3472 + + string_view,
+ 3473 + + json::value>&& p,
+ 3474 + + storage_ptr sp = {})
+ 3475 + +3125 : key_value_pair(
+ 3476 + + p.first,
+ 3477 + +3125 std::move(p).second,
+ 3478 + +6250 std::move(sp))
+ 3479 + + {
+ 3480 + +2978 }
+ 3481 + +
+ 3482 + + /** Overload
+ 3483 + +
+ 3484 + + @param other Another key/value pair.
+ 3485 + + @param sp
+ 3486 + + */
+ 3487 + + BOOST_JSON_DECL
+ 3488 + + key_value_pair(
+ 3489 + + key_value_pair const& other,
+ 3490 + + storage_ptr sp);
+ 3491 + +
+ 3492 + + /// Overload
+ 3493 + +758 key_value_pair(
+ 3494 + + key_value_pair const& other)
+ 3495 + +758 : key_value_pair(other,
+ 3496 + +758 other.storage())
+ 3497 + + {
+ 3498 + +758 }
+ 3499 + +
+ 3500 + + /// Overload
+ 3501 + +1 key_value_pair(
+ 3502 + + key_value_pair&& other) noexcept
+ 3503 + +1 : value_(std::move(other.value_))
+ 3504 + +2 , key_(detail::exchange(
+ 3505 + +1 other.key_, empty_))
+ 3506 + +2 , len_(detail::exchange(
+ 3507 + +1 other.len_, 0))
+ 3508 + + {
+ 3509 + +1 }
+ 3510 + +
+ 3511 + + /// Overload
+ 3512 + +6749 key_value_pair(
+ 3513 + + pilfered<key_value_pair> other) noexcept
+ 3514 + +6749 : value_(pilfer(other.get().value_))
+ 3515 + +13498 , key_(detail::exchange(
+ 3516 + +6749 other.get().key_, empty_))
+ 3517 + +13498 , len_(detail::exchange(
+ 3518 + +6749 other.get().len_, 0))
+ 3519 + + {
+ 3520 + +6749 }
+ 3521 + + /// @}
+ 3522 + +
+ 3523 + + /** The associated memory resource.
+ 3524 + +
+ 3525 + + Returns a pointer to the memory resource used to construct the value.
+ 3526 + +
+ 3527 + + @par Complexity
+ 3528 + + Constant.
+ 3529 + +
+ 3530 + + @par Exception Safety
+ 3531 + + No-throw guarantee.
+ 3532 + + */
+ 3533 + + storage_ptr const&
+ 3534 + +758 storage() const noexcept
+ 3535 + + {
+ 3536 + +758 return value_.storage();
+ 3537 + + }
+ 3538 + +
+ 3539 + + /** The pair's key.
+ 3540 + +
+ 3541 + + After construction, the key may not be modified.
+ 3542 + +
+ 3543 + + @par Complexity
+ 3544 + + Constant.
+ 3545 + +
+ 3546 + + @par Exception Safety
+ 3547 + + No-throw guarantee.
+ 3548 + + */
+ 3549 + + string_view const
+ 3550 + +142599 key() const noexcept
+ 3551 + + {
+ 3552 + +142599 return { key_, len_ };
+ 3553 + + }
+ 3554 + +
+ 3555 + + /** The pair's key as a null-terminated string.
+ 3556 + +
+ 3557 + + @par Complexity
+ 3558 + + Constant.
+ 3559 + +
+ 3560 + + @par Exception Safety
+ 3561 + + No-throw guarantee.
+ 3562 + + */
+ 3563 + + char const*
+ 3564 + +1 key_c_str() const noexcept
+ 3565 + + {
+ 3566 + +1 return key_;
+ 3567 + + }
+ 3568 + +
+ 3569 + + /** The pair's value.
+ 3570 + +
+ 3571 + + @par Complexity
+ 3572 + + Constant.
+ 3573 + +
+ 3574 + + @par Exception Safety
+ 3575 + + No-throw guarantee.
+ 3576 + +
+ 3577 + + @{
+ 3578 + + */
+ 3579 + + json::value const&
+ 3580 + +65221 value() const& noexcept
+ 3581 + + {
+ 3582 + +65221 return value_;
+ 3583 + + }
+ 3584 + +
+ 3585 + + json::value&&
+ 3586 + + value() && noexcept
+ 3587 + + {
+ 3588 + + return std::move( value() );
+ 3589 + + }
+ 3590 + +
+ 3591 + + json::value&
+ 3592 + +1076 value() & noexcept
+ 3593 + + {
+ 3594 + +1076 return value_;
+ 3595 + + }
+ 3596 + + /// @}
+ 3597 + +
+ 3598 + + private:
+ 3599 + + json::value value_;
+ 3600 + + char const* key_;
+ 3601 + + std::uint32_t len_;
+ 3602 + + std::uint32_t next_;
+ 3603 + + };
+ 3604 + +
+ 3605 + + //----------------------------------------------------------
+ 3606 + +
+ 3607 + + #ifdef BOOST_JSON_DOCS
+ 3608 + +
+ 3609 + + /** Tuple-like element access.
+ 3610 + +
+ 3611 + + This overload of `get` permits the key and value of a @ref key_value_pair
+ 3612 + + to be accessed by index. For example:
+ 3613 + +
+ 3614 + + @code
+ 3615 + + key_value_pair kvp("num", 42);
+ 3616 + + string_view key = get<0>(kvp);
+ 3617 + + value& jv = get<1>(kvp);
+ 3618 + + @endcode
+ 3619 + +
+ 3620 + + @par Structured Bindings
+ 3621 + + When using C++17 or greater, objects of type @ref key_value_pair may be
+ 3622 + + used to initialize structured bindings:
+ 3623 + +
+ 3624 + + @code
+ 3625 + + key_value_pair kvp("num", 42);
+ 3626 + + auto& [key, value] = kvp;
+ 3627 + + @endcode
+ 3628 + +
+ 3629 + + Depending on the value of `I`, the return type will be:
+ 3630 + +
+ 3631 + + @li `string_view const` if `I == 0`, or
+ 3632 + + @li `value&`, `value const&`, or `value&&` if `I == 1`.
+ 3633 + +
+ 3634 + + Using any other value for `I` is ill-formed.
+ 3635 + +
+ 3636 + + @par Constraints
+ 3637 + + `std::is_same_v< std::remove_cvref_t<T>, key_value_pair >`
+ 3638 + +
+ 3639 + + @tparam I The element index to access.
+ 3640 + +
+ 3641 + + @return `kvp.key()` if `I == 0`, or `kvp.value()` if `I == 1`.
+ 3642 + +
+ 3643 + + @param kvp The @ref key_value_pair object to access.
+ 3644 + + */
+ 3645 + + template<
+ 3646 + + std::size_t I,
+ 3647 + + class T>
+ 3648 + + __see_below__
+ 3649 + + get(T&& kvp) noexcept;
+ 3650 + +
+ 3651 + + #else
+ 3652 + +
+ 3653 + + template<std::size_t I>
+ 3654 + + auto
+ 3655 + + get(key_value_pair const&) noexcept ->
+ 3656 + + typename std::conditional<I == 0,
+ 3657 + + string_view const,
+ 3658 + + value const&>::type
+ 3659 + + {
+ 3660 + + static_assert(I == 0,
+ 3661 + + "key_value_pair index out of range");
+ 3662 + + }
+ 3663 + +
+ 3664 + + template<std::size_t I>
+ 3665 + + auto
+ 3666 + + get(key_value_pair&) noexcept ->
+ 3667 + + typename std::conditional<I == 0,
+ 3668 + + string_view const,
+ 3669 + + value&>::type
+ 3670 + + {
+ 3671 + + static_assert(I == 0,
+ 3672 + + "key_value_pair index out of range");
+ 3673 + + }
+ 3674 + +
+ 3675 + + template<std::size_t I>
+ 3676 + + auto
+ 3677 + + get(key_value_pair&&) noexcept ->
+ 3678 + + typename std::conditional<I == 0,
+ 3679 + + string_view const,
+ 3680 + + value&&>::type
+ 3681 + + {
+ 3682 + + static_assert(I == 0,
+ 3683 + + "key_value_pair index out of range");
+ 3684 + + }
+ 3685 + +
+ 3686 + + /** Extracts a key_value_pair's key using tuple-like interface
+ 3687 + + */
+ 3688 + + template<>
+ 3689 + + inline
+ 3690 + + string_view const
+ 3691 + +19609 get<0>(key_value_pair const& kvp) noexcept
+ 3692 + + {
+ 3693 + +19609 return kvp.key();
+ 3694 + + }
+ 3695 + +
+ 3696 + + /** Extracts a key_value_pair's key using tuple-like interface
+ 3697 + + */
+ 3698 + + template<>
+ 3699 + + inline
+ 3700 + + string_view const
+ 3701 + +7 get<0>(key_value_pair& kvp) noexcept
+ 3702 + + {
+ 3703 + +7 return kvp.key();
+ 3704 + + }
+ 3705 + +
+ 3706 + + /** Extracts a key_value_pair's key using tuple-like interface
+ 3707 + + */
+ 3708 + + template<>
+ 3709 + + inline
+ 3710 + + string_view const
+ 3711 + + get<0>(key_value_pair&& kvp) noexcept
+ 3712 + + {
+ 3713 + + return kvp.key();
+ 3714 + + }
+ 3715 + +
+ 3716 + + /** Extracts a key_value_pair's value using tuple-like interface
+ 3717 + + */
+ 3718 + + template<>
+ 3719 + + inline
+ 3720 + + value const&
+ 3721 + +28299 get<1>(key_value_pair const& kvp) noexcept
+ 3722 + + {
+ 3723 + +28299 return kvp.value();
+ 3724 + + }
+ 3725 + +
+ 3726 + + /** Extracts a key_value_pair's value using tuple-like interface
+ 3727 + + */
+ 3728 + + template<>
+ 3729 + + inline
+ 3730 + + value&
+ 3731 + +7 get<1>(key_value_pair& kvp) noexcept
+ 3732 + + {
+ 3733 + +7 return kvp.value();
+ 3734 + + }
+ 3735 + +
+ 3736 + + /** Extracts a key_value_pair's value using tuple-like interface
+ 3737 + + */
+ 3738 + + template<>
+ 3739 + + inline
+ 3740 + + value&&
+ 3741 + + get<1>(key_value_pair&& kvp) noexcept
+ 3742 + + {
+ 3743 + + return std::move(kvp.value());
+ 3744 + + }
+ 3745 + +
+ 3746 + + #endif
+ 3747 + +
+ 3748 + + } // namespace json
+ 3749 + + } // namespace boost
+ 3750 + +
+ 3751 + + #ifdef __clang__
+ 3752 + + # pragma clang diagnostic push
+ 3753 + + # pragma clang diagnostic ignored "-Wmismatched-tags"
+ 3754 + + #endif
+ 3755 + +
+ 3756 + + #ifndef BOOST_JSON_DOCS
+ 3757 + +
+ 3758 + + namespace std {
+ 3759 + +
+ 3760 + + /** Tuple-like size access for key_value_pair
+ 3761 + + */
+ 3762 + + template<>
+ 3763 + + struct tuple_size< ::boost::json::key_value_pair >
+ 3764 + + : std::integral_constant<std::size_t, 2>
+ 3765 + + {
+ 3766 + + };
+ 3767 + +
+ 3768 + + /** Tuple-like access for the key type of key_value_pair
+ 3769 + + */
+ 3770 + + template<>
+ 3771 + + struct tuple_element<0, ::boost::json::key_value_pair>
+ 3772 + + {
+ 3773 + + using type = ::boost::json::string_view const;
+ 3774 + + };
+ 3775 + +
+ 3776 + + /** Tuple-like access for the value type of key_value_pair
+ 3777 + + */
+ 3778 + + template<>
+ 3779 + + struct tuple_element<1, ::boost::json::key_value_pair>
+ 3780 + + {
+ 3781 + + using type = ::boost::json::value&;
+ 3782 + + };
+ 3783 + +
+ 3784 + + /** Tuple-like access for the value type of key_value_pair
+ 3785 + + */
+ 3786 + + template<>
+ 3787 + + struct tuple_element<1, ::boost::json::key_value_pair const>
+ 3788 + + {
+ 3789 + + using type = ::boost::json::value const&;
+ 3790 + + };
+ 3791 + +
+ 3792 + + } // std
+ 3793 + +
+ 3794 + + #endif
+ 3795 + +
+ 3796 + + // std::hash specialization
+ 3797 + + #ifndef BOOST_JSON_DOCS
+ 3798 + + namespace std {
+ 3799 + + template <>
+ 3800 + + struct hash< ::boost::json::value > {
+ 3801 + + BOOST_JSON_DECL
+ 3802 + + std::size_t
+ 3803 + + operator()(::boost::json::value const& jv) const noexcept;
+ 3804 + + };
+ 3805 + + } // std
+ 3806 + + #endif
+ 3807 + +
+ 3808 + +
+ 3809 + + #ifdef __clang__
+ 3810 + + # pragma clang diagnostic pop
+ 3811 + + #endif
+ 3812 + +
+ 3813 + + // These are here because value, array,
+ 3814 + + // and object form cyclic references.
+ 3815 + +
+ 3816 + + #include <boost/json/detail/impl/array.hpp>
+ 3817 + + #include <boost/json/impl/array.hpp>
+ 3818 + + #include <boost/json/impl/object.hpp>
+ 3819 + + #include <boost/json/impl/value.hpp>
+ 3820 + +
+ 3821 + + // These must come after array and object
+ 3822 + + #include <boost/json/impl/value_ref.hpp>
+ 3823 + +
+ 3824 + + #endif
+ 3825 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value.hpp.927a100eb53bf40397be1d8b22da1871.html b/json/gcovr/index.value.hpp.927a100eb53bf40397be1d8b22da1871.html new file mode 100644 index 00000000..82d85811 --- /dev/null +++ b/json/gcovr/index.value.hpp.927a100eb53bf40397be1d8b22da1871.html @@ -0,0 +1,2366 @@ + + + + + + impl/value.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/value.hpp

+
+ + 100.0% Lines (3/3) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/value.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@yandex.ru)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_VALUE_HPP
+ 11 + + #define BOOST_JSON_IMPL_VALUE_HPP
+ 12 + +
+ 13 + + namespace boost {
+ 14 + + namespace json {
+ 15 + +
+ 16 + + value&
+ 17 + +33 value::at_pointer(string_view ptr, source_location const& loc) &
+ 18 + + {
+ 19 + +33 auto const& self = *this;
+ 20 + +33 return const_cast<value&>( self.at_pointer(ptr, loc) );
+ 21 + + }
+ 22 + +
+ 23 + + value&&
+ 24 + + value::at_pointer(string_view ptr, source_location const& loc) &&
+ 25 + + {
+ 26 + + return std::move( at_pointer(ptr, loc) );
+ 27 + + }
+ 28 + +
+ 29 + + } // namespace json
+ 30 + + } // namespace boost
+ 31 + +
+ 32 + + #endif // BOOST_JSON_IMPL_VALUE_HPP
+ 33 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value.ipp.210aedf137631846f16fbe0ee4f0812c.html b/json/gcovr/index.value.ipp.210aedf137631846f16fbe0ee4f0812c.html new file mode 100644 index 00000000..0b4876ee --- /dev/null +++ b/json/gcovr/index.value.ipp.210aedf137631846f16fbe0ee4f0812c.html @@ -0,0 +1,9990 @@ + + + + + + impl/value.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/value.ipp

+
+ + 98.7% Lines (456/462) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/value.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_VALUE_IPP
+ 11 + + #define BOOST_JSON_IMPL_VALUE_IPP
+ 12 + +
+ 13 + + #include <boost/container_hash/hash.hpp>
+ 14 + + #include <boost/json/value.hpp>
+ 15 + + #include <boost/json/parser.hpp>
+ 16 + + #include <cstring>
+ 17 + + #include <istream>
+ 18 + + #include <limits>
+ 19 + + #include <new>
+ 20 + + #include <utility>
+ 21 + +
+ 22 + + namespace boost {
+ 23 + + namespace json {
+ 24 + +
+ 25 + + namespace
+ 26 + + {
+ 27 + +
+ 28 + + int parse_depth_xalloc = std::ios::xalloc();
+ 29 + + int parse_flags_xalloc = std::ios::xalloc();
+ 30 + +
+ 31 + + struct value_hasher
+ 32 + + {
+ 33 + + std::size_t& seed;
+ 34 + +
+ 35 + + template< class T >
+ 36 + +248 void operator()( T&& t ) const noexcept
+ 37 + + {
+ 38 + +248 boost::hash_combine( seed, t );
+ 39 + +248 }
+ 40 + + };
+ 41 + +
+ 42 + + enum class stream_parse_flags
+ 43 + + {
+ 44 + + allow_comments = 1 << 0,
+ 45 + + allow_trailing_commas = 1 << 1,
+ 46 + + allow_invalid_utf8 = 1 << 2,
+ 47 + + };
+ 48 + +
+ 49 + + long
+ 50 + +3 to_bitmask( parse_options const& opts )
+ 51 + + {
+ 52 + + using E = stream_parse_flags;
+ 53 + + return
+ 54 + +3 (opts.allow_comments ?
+ 55 + +3 static_cast<long>(E::allow_comments) : 0) |
+ 56 + +3 (opts.allow_trailing_commas ?
+ 57 + + static_cast<long>(E::allow_trailing_commas) : 0) |
+ 58 + +3 (opts.allow_invalid_utf8 ?
+ 59 + +3 static_cast<long>(E::allow_invalid_utf8) : 0);
+ 60 + + }
+ 61 + +
+ 62 + + parse_options
+ 63 + +9 get_parse_options( std::istream& is )
+ 64 + + {
+ 65 + +9 long const flags = is.iword(parse_flags_xalloc);
+ 66 + +
+ 67 + + using E = stream_parse_flags;
+ 68 + +9 parse_options opts;
+ 69 + +9 opts.allow_comments =
+ 70 + +9 flags & static_cast<long>(E::allow_comments) ? true : false;
+ 71 + +9 opts.allow_trailing_commas =
+ 72 + +9 flags & static_cast<long>(E::allow_trailing_commas) ? true : false;
+ 73 + +9 opts.allow_invalid_utf8 =
+ 74 + +9 flags & static_cast<long>(E::allow_invalid_utf8) ? true : false;
+ 75 + +9 return opts;
+ 76 + + }
+ 77 + +
+ 78 + + } // namespace
+ 79 + +
+ 80 + +2178431 value::
+ 81 + + ~value() noexcept
+ 82 + + {
+ 83 + +2178431 switch(kind())
+ 84 + + {
+ 85 + +2112785 case json::kind::null:
+ 86 + + case json::kind::bool_:
+ 87 + + case json::kind::int64:
+ 88 + + case json::kind::uint64:
+ 89 + + case json::kind::double_:
+ 90 + +2112785 sca_.~scalar();
+ 91 + +2112785 break;
+ 92 + +
+ 93 + +27371 case json::kind::string:
+ 94 + +27371 str_.~string();
+ 95 + +27371 break;
+ 96 + +
+ 97 + +3073 case json::kind::array:
+ 98 + +3073 arr_.~array();
+ 99 + +3073 break;
+ 100 + +
+ 101 + +35202 case json::kind::object:
+ 102 + +35202 obj_.~object();
+ 103 + +35202 break;
+ 104 + + }
+ 105 + +2178431 }
+ 106 + +
+ 107 + +9490 value::
+ 108 + + value(
+ 109 + + value const& other,
+ 110 + +9490 storage_ptr sp)
+ 111 + + {
+ 112 + +9490 switch(other.kind())
+ 113 + + {
+ 114 + +2034 case json::kind::null:
+ 115 + +6102 ::new(&sca_) scalar(
+ 116 + +2034 std::move(sp));
+ 117 + +2034 break;
+ 118 + +
+ 119 + +121 case json::kind::bool_:
+ 120 + +363 ::new(&sca_) scalar(
+ 121 + +121 other.sca_.b,
+ 122 + +121 std::move(sp));
+ 123 + +121 break;
+ 124 + +
+ 125 + +7006 case json::kind::int64:
+ 126 + +21018 ::new(&sca_) scalar(
+ 127 + +7006 other.sca_.i,
+ 128 + +7006 std::move(sp));
+ 129 + +7006 break;
+ 130 + +
+ 131 + +35 case json::kind::uint64:
+ 132 + +105 ::new(&sca_) scalar(
+ 133 + +35 other.sca_.u,
+ 134 + +35 std::move(sp));
+ 135 + +35 break;
+ 136 + +
+ 137 + +12 case json::kind::double_:
+ 138 + +36 ::new(&sca_) scalar(
+ 139 + +12 other.sca_.d,
+ 140 + +12 std::move(sp));
+ 141 + +12 break;
+ 142 + +
+ 143 + +130 case json::kind::string:
+ 144 + +17 ::new(&str_) string(
+ 145 + +130 other.str_,
+ 146 + +164 std::move(sp));
+ 147 + +113 break;
+ 148 + +
+ 149 + +122 case json::kind::array:
+ 150 + +26 ::new(&arr_) array(
+ 151 + +122 other.arr_,
+ 152 + +174 std::move(sp));
+ 153 + +96 break;
+ 154 + +
+ 155 + +30 case json::kind::object:
+ 156 + +10 ::new(&obj_) object(
+ 157 + +30 other.obj_,
+ 158 + +50 std::move(sp));
+ 159 + +20 break;
+ 160 + + }
+ 161 + +9437 }
+ 162 + +
+ 163 + +3784 value::
+ 164 + +3784 value(value&& other) noexcept
+ 165 + + {
+ 166 + +3784 relocate(this, other);
+ 167 + +3784 ::new(&other.sca_) scalar(sp_);
+ 168 + +3784 }
+ 169 + +
+ 170 + +11417 value::
+ 171 + + value(
+ 172 + + value&& other,
+ 173 + +11417 storage_ptr sp)
+ 174 + + {
+ 175 + +11417 switch(other.kind())
+ 176 + + {
+ 177 + +77 case json::kind::null:
+ 178 + +229 ::new(&sca_) scalar(
+ 179 + +77 std::move(sp));
+ 180 + +77 break;
+ 181 + +
+ 182 + +189 case json::kind::bool_:
+ 183 + +567 ::new(&sca_) scalar(
+ 184 + +189 other.sca_.b, std::move(sp));
+ 185 + +189 break;
+ 186 + +
+ 187 + +10422 case json::kind::int64:
+ 188 + +31266 ::new(&sca_) scalar(
+ 189 + +10422 other.sca_.i, std::move(sp));
+ 190 + +10422 break;
+ 191 + +
+ 192 + +75 case json::kind::uint64:
+ 193 + +225 ::new(&sca_) scalar(
+ 194 + +75 other.sca_.u, std::move(sp));
+ 195 + +75 break;
+ 196 + +
+ 197 + +34 case json::kind::double_:
+ 198 + +102 ::new(&sca_) scalar(
+ 199 + +34 other.sca_.d, std::move(sp));
+ 200 + +34 break;
+ 201 + +
+ 202 + +335 case json::kind::string:
+ 203 + +4 ::new(&str_) string(
+ 204 + +335 std::move(other.str_),
+ 205 + +678 std::move(sp));
+ 206 + +331 break;
+ 207 + +
+ 208 + +221 case json::kind::array:
+ 209 + +5 ::new(&arr_) array(
+ 210 + +221 std::move(other.arr_),
+ 211 + +452 std::move(sp));
+ 212 + +216 break;
+ 213 + +
+ 214 + +64 case json::kind::object:
+ 215 + +13 ::new(&obj_) object(
+ 216 + +64 std::move(other.obj_),
+ 217 + +154 std::move(sp));
+ 218 + +51 break;
+ 219 + + }
+ 220 + +11395 }
+ 221 + +
+ 222 + + //----------------------------------------------------------
+ 223 + + //
+ 224 + + // Conversion
+ 225 + + //
+ 226 + + //----------------------------------------------------------
+ 227 + +
+ 228 + +326 value::
+ 229 + + value(
+ 230 + + std::initializer_list<value_ref> init,
+ 231 + +326 storage_ptr sp)
+ 232 + + {
+ 233 + +326 if(value_ref::maybe_object(init))
+ 234 + + {
+ 235 + + ::new(&obj_) object(
+ 236 + + value_ref::make_object(
+ 237 + +101 init, std::move(sp)));
+ 238 + + }
+ 239 + + else
+ 240 + + {
+ 241 + +225 if( init.size() == 1 )
+ 242 + + {
+ 243 + +12 ::new(&sca_) scalar();
+ 244 + +12 value temp = init.begin()->make_value( std::move(sp) );
+ 245 + +12 swap(temp);
+ 246 + +12 }
+ 247 + + else
+ 248 + + {
+ 249 + + ::new(&arr_) array(
+ 250 + + value_ref::make_array(
+ 251 + +213 init, std::move(sp)));
+ 252 + + }
+ 253 + + }
+ 254 + +326 }
+ 255 + +
+ 256 + + //----------------------------------------------------------
+ 257 + + //
+ 258 + + // Assignment
+ 259 + + //
+ 260 + + //----------------------------------------------------------
+ 261 + +
+ 262 + + value&
+ 263 + +35 value::
+ 264 + + operator=(value const& other)
+ 265 + + {
+ 266 + +70 value(other,
+ 267 + +29 storage()).swap(*this);
+ 268 + +29 return *this;
+ 269 + + }
+ 270 + +
+ 271 + + value&
+ 272 + +72 value::
+ 273 + + operator=(value&& other)
+ 274 + + {
+ 275 + +144 value(std::move(other),
+ 276 + +53 storage()).swap(*this);
+ 277 + +53 return *this;
+ 278 + + }
+ 279 + +
+ 280 + + value&
+ 281 + +11 value::
+ 282 + + operator=(
+ 283 + + std::initializer_list<value_ref> init)
+ 284 + + {
+ 285 + +22 value(init,
+ 286 + +11 storage()).swap(*this);
+ 287 + +11 return *this;
+ 288 + + }
+ 289 + +
+ 290 + + value&
+ 291 + +2 value::
+ 292 + + operator=(string_view s)
+ 293 + + {
+ 294 + +2 value(s, storage()).swap(*this);
+ 295 + +2 return *this;
+ 296 + + }
+ 297 + +
+ 298 + + value&
+ 299 + +28 value::
+ 300 + + operator=(char const* s)
+ 301 + + {
+ 302 + +28 value(s, storage()).swap(*this);
+ 303 + +28 return *this;
+ 304 + + }
+ 305 + +
+ 306 + + value&
+ 307 + +12 value::
+ 308 + + operator=(string const& str)
+ 309 + + {
+ 310 + +12 value(str, storage()).swap(*this);
+ 311 + +12 return *this;
+ 312 + + }
+ 313 + +
+ 314 + + value&
+ 315 + +2 value::
+ 316 + + operator=(string&& str)
+ 317 + + {
+ 318 + +4 value(std::move(str),
+ 319 + +2 storage()).swap(*this);
+ 320 + +2 return *this;
+ 321 + + }
+ 322 + +
+ 323 + + value&
+ 324 + +1 value::
+ 325 + + operator=(array const& arr)
+ 326 + + {
+ 327 + +1 value(arr, storage()).swap(*this);
+ 328 + +1 return *this;
+ 329 + + }
+ 330 + +
+ 331 + + value&
+ 332 + +5 value::
+ 333 + + operator=(array&& arr)
+ 334 + + {
+ 335 + +10 value(std::move(arr),
+ 336 + +5 storage()).swap(*this);
+ 337 + +5 return *this;
+ 338 + + }
+ 339 + +
+ 340 + + value&
+ 341 + +1 value::
+ 342 + + operator=(object const& obj)
+ 343 + + {
+ 344 + +1 value(obj, storage()).swap(*this);
+ 345 + +1 return *this;
+ 346 + + }
+ 347 + +
+ 348 + + value&
+ 349 + +22 value::
+ 350 + + operator=(object&& obj)
+ 351 + + {
+ 352 + +44 value(std::move(obj),
+ 353 + +22 storage()).swap(*this);
+ 354 + +22 return *this;
+ 355 + + }
+ 356 + +
+ 357 + + //----------------------------------------------------------
+ 358 + + //
+ 359 + + // Accessors
+ 360 + + //
+ 361 + + //----------------------------------------------------------
+ 362 + +
+ 363 + + system::result<array&>
+ 364 + +16 value::try_as_array() noexcept
+ 365 + + {
+ 366 + +16 if( is_array() )
+ 367 + +9 return arr_;
+ 368 + +
+ 369 + +7 system::error_code ec;
+ 370 + +7 BOOST_JSON_FAIL(ec, error::not_array);
+ 371 + +7 return ec;
+ 372 + + }
+ 373 + +
+ 374 + + system::result<array const&>
+ 375 + +183 value::try_as_array() const noexcept
+ 376 + + {
+ 377 + +183 if( is_array() )
+ 378 + +155 return arr_;
+ 379 + +
+ 380 + +28 system::error_code ec;
+ 381 + +28 BOOST_JSON_FAIL(ec, error::not_array);
+ 382 + +28 return ec;
+ 383 + + }
+ 384 + +
+ 385 + + system::result<object&>
+ 386 + +9 value::try_as_object() noexcept
+ 387 + + {
+ 388 + +9 if( is_object() )
+ 389 + +2 return obj_;
+ 390 + +
+ 391 + +7 system::error_code ec;
+ 392 + +7 BOOST_JSON_FAIL(ec, error::not_object);
+ 393 + +7 return ec;
+ 394 + + }
+ 395 + +
+ 396 + + system::result<object const&>
+ 397 + +206 value::try_as_object() const noexcept
+ 398 + + {
+ 399 + +206 if( is_object() )
+ 400 + +178 return obj_;
+ 401 + +
+ 402 + +28 system::error_code ec;
+ 403 + +28 BOOST_JSON_FAIL(ec, error::not_object);
+ 404 + +28 return ec;
+ 405 + + }
+ 406 + +
+ 407 + + system::result<string&>
+ 408 + +9 value::try_as_string() noexcept
+ 409 + + {
+ 410 + +9 if( is_string() )
+ 411 + +2 return str_;
+ 412 + +
+ 413 + +7 system::error_code ec;
+ 414 + +7 BOOST_JSON_FAIL(ec, error::not_string);
+ 415 + +7 return ec;
+ 416 + + }
+ 417 + +
+ 418 + + system::result<string const&>
+ 419 + +121 value::try_as_string() const noexcept
+ 420 + + {
+ 421 + +121 if( is_string() )
+ 422 + +92 return str_;
+ 423 + +
+ 424 + +29 system::error_code ec;
+ 425 + +29 BOOST_JSON_FAIL(ec, error::not_string);
+ 426 + +29 return ec;
+ 427 + + }
+ 428 + +
+ 429 + + system::result<std::int64_t&>
+ 430 + +52 value::try_as_int64() noexcept
+ 431 + + {
+ 432 + +52 if( is_int64() )
+ 433 + +38 return sca_.i;
+ 434 + +
+ 435 + +14 system::error_code ec;
+ 436 + +14 BOOST_JSON_FAIL(ec, error::not_int64);
+ 437 + +14 return ec;
+ 438 + + }
+ 439 + +
+ 440 + + system::result<std::int64_t>
+ 441 + +33 value::try_as_int64() const noexcept
+ 442 + + {
+ 443 + +33 if( is_int64() )
+ 444 + +19 return sca_.i;
+ 445 + +
+ 446 + +14 system::error_code ec;
+ 447 + +14 BOOST_JSON_FAIL(ec, error::not_int64);
+ 448 + +14 return ec;
+ 449 + + }
+ 450 + +
+ 451 + + system::result<std::uint64_t&>
+ 452 + +16 value::try_as_uint64() noexcept
+ 453 + + {
+ 454 + +16 if( is_uint64() )
+ 455 + +2 return sca_.u;
+ 456 + +
+ 457 + +14 system::error_code ec;
+ 458 + +14 BOOST_JSON_FAIL(ec, error::not_uint64);
+ 459 + +14 return ec;
+ 460 + + }
+ 461 + +
+ 462 + + system::result<std::uint64_t>
+ 463 + +16 value::try_as_uint64() const noexcept
+ 464 + + {
+ 465 + +16 if( is_uint64() )
+ 466 + +2 return sca_.u;
+ 467 + +
+ 468 + +14 system::error_code ec;
+ 469 + +14 BOOST_JSON_FAIL(ec, error::not_uint64);
+ 470 + +14 return ec;
+ 471 + + }
+ 472 + +
+ 473 + + system::result<double&>
+ 474 + +2000657 value::try_as_double() noexcept
+ 475 + + {
+ 476 + +2000657 if( is_double() )
+ 477 + +2000643 return sca_.d;
+ 478 + +
+ 479 + +14 system::error_code ec;
+ 480 + +14 BOOST_JSON_FAIL(ec, error::not_double);
+ 481 + +14 return ec;
+ 482 + + }
+ 483 + +
+ 484 + + system::result<double>
+ 485 + +580 value::try_as_double() const noexcept
+ 486 + + {
+ 487 + +580 if( is_double() )
+ 488 + +566 return sca_.d;
+ 489 + +
+ 490 + +14 system::error_code ec;
+ 491 + +14 BOOST_JSON_FAIL(ec, error::not_double);
+ 492 + +14 return ec;
+ 493 + + }
+ 494 + +
+ 495 + + system::result<bool&>
+ 496 + +19 value::try_as_bool() noexcept
+ 497 + + {
+ 498 + +19 if( is_bool() )
+ 499 + +4 return sca_.b;
+ 500 + +
+ 501 + +15 system::error_code ec;
+ 502 + +15 BOOST_JSON_FAIL(ec, error::not_bool);
+ 503 + +15 return ec;
+ 504 + + }
+ 505 + +
+ 506 + + system::result<bool>
+ 507 + +30 value::try_as_bool() const noexcept
+ 508 + + {
+ 509 + +30 if( is_bool() )
+ 510 + +16 return sca_.b;
+ 511 + +
+ 512 + +14 system::error_code ec;
+ 513 + +14 BOOST_JSON_FAIL(ec, error::not_bool);
+ 514 + +14 return ec;
+ 515 + + }
+ 516 + +
+ 517 + + system::result<std::nullptr_t>
+ 518 + +2 value::try_as_null() const noexcept
+ 519 + + {
+ 520 + +2 if( is_null() )
+ 521 + +1 return nullptr;
+ 522 + +
+ 523 + +1 system::error_code ec;
+ 524 + +1 BOOST_JSON_FAIL(ec, error::not_null);
+ 525 + +1 return ec;
+ 526 + + }
+ 527 + +
+ 528 + + boost::system::result<value&>
+ 529 + +1 value::try_at(string_view key) noexcept
+ 530 + + {
+ 531 + +1 auto r = try_as_object();
+ 532 + +1 if( !r )
+ 533 + + return r.error();
+ 534 + +1 return r->try_at(key);
+ 535 + + }
+ 536 + +
+ 537 + + boost::system::result<value const&>
+ 538 + +3 value::try_at(string_view key) const noexcept
+ 539 + + {
+ 540 + +3 auto r = try_as_object();
+ 541 + +3 if( !r )
+ 542 + + return r.error();
+ 543 + +3 return r->try_at(key);
+ 544 + + }
+ 545 + +
+ 546 + + boost::system::result<value&>
+ 547 + +8 value::try_at(std::size_t pos) noexcept
+ 548 + + {
+ 549 + +8 auto r = try_as_array();
+ 550 + +8 if( !r )
+ 551 + + return r.error();
+ 552 + +8 return r->try_at(pos);
+ 553 + + }
+ 554 + +
+ 555 + + boost::system::result<value const&>
+ 556 + +2 value::try_at(std::size_t pos) const noexcept
+ 557 + + {
+ 558 + +2 auto r = try_as_array();
+ 559 + +2 if( !r )
+ 560 + + return r.error();
+ 561 + +2 return r->try_at(pos);
+ 562 + + }
+ 563 + +
+ 564 + + object const&
+ 565 + +195 value::as_object(source_location const& loc) const&
+ 566 + + {
+ 567 + +195 return try_as_object().value(loc);
+ 568 + + }
+ 569 + +
+ 570 + + array const&
+ 571 + +173 value::as_array(source_location const& loc) const&
+ 572 + + {
+ 573 + +173 return try_as_array().value(loc);
+ 574 + + }
+ 575 + +
+ 576 + + string const&
+ 577 + +113 value::as_string(source_location const& loc) const&
+ 578 + + {
+ 579 + +113 return try_as_string().value(loc);
+ 580 + + }
+ 581 + +
+ 582 + + std::int64_t&
+ 583 + +44 value::as_int64(source_location const& loc)
+ 584 + + {
+ 585 + +44 return try_as_int64().value(loc);
+ 586 + + }
+ 587 + +
+ 588 + + std::int64_t
+ 589 + +26 value::as_int64(source_location const& loc) const
+ 590 + + {
+ 591 + +26 return try_as_int64().value(loc);
+ 592 + + }
+ 593 + +
+ 594 + + std::uint64_t&
+ 595 + +8 value::as_uint64(source_location const& loc)
+ 596 + + {
+ 597 + +8 return try_as_uint64().value(loc);
+ 598 + + }
+ 599 + +
+ 600 + + std::uint64_t
+ 601 + +8 value::as_uint64(source_location const& loc) const
+ 602 + + {
+ 603 + +8 return try_as_uint64().value(loc);
+ 604 + + }
+ 605 + +
+ 606 + + double&
+ 607 + +2000649 value::as_double(source_location const& loc)
+ 608 + + {
+ 609 + +2000649 return try_as_double().value(loc);
+ 610 + + }
+ 611 + +
+ 612 + + double
+ 613 + +572 value::as_double(source_location const& loc) const
+ 614 + + {
+ 615 + +572 return try_as_double().value(loc);
+ 616 + + }
+ 617 + +
+ 618 + + bool&
+ 619 + +10 value::as_bool(source_location const& loc)
+ 620 + + {
+ 621 + +10 return try_as_bool().value(loc);
+ 622 + + }
+ 623 + +
+ 624 + + bool
+ 625 + +22 value::as_bool(source_location const& loc) const
+ 626 + + {
+ 627 + +22 return try_as_bool().value(loc);
+ 628 + + }
+ 629 + +
+ 630 + + //----------------------------------------------------------
+ 631 + + //
+ 632 + + // Modifiers
+ 633 + + //
+ 634 + + //----------------------------------------------------------
+ 635 + +
+ 636 + + string&
+ 637 + +98 value::
+ 638 + + emplace_string() noexcept
+ 639 + + {
+ 640 + +98 return *::new(&str_) string(destroy());
+ 641 + + }
+ 642 + +
+ 643 + + array&
+ 644 + +246 value::
+ 645 + + emplace_array() noexcept
+ 646 + + {
+ 647 + +246 return *::new(&arr_) array(destroy());
+ 648 + + }
+ 649 + +
+ 650 + + object&
+ 651 + +55 value::
+ 652 + + emplace_object() noexcept
+ 653 + + {
+ 654 + +55 return *::new(&obj_) object(destroy());
+ 655 + + }
+ 656 + +
+ 657 + + void
+ 658 + +184 value::
+ 659 + + swap(value& other)
+ 660 + + {
+ 661 + +184 if(*storage() == *other.storage())
+ 662 + + {
+ 663 + + // fast path
+ 664 + + union U
+ 665 + + {
+ 666 + + value tmp;
+ 667 + +183 U(){}
+ 668 + +183 ~U(){}
+ 669 + + };
+ 670 + +183 U u;
+ 671 + +183 relocate(&u.tmp, *this);
+ 672 + +183 relocate(this, other);
+ 673 + +183 relocate(&other, u.tmp);
+ 674 + +183 return;
+ 675 + +183 }
+ 676 + +
+ 677 + + // copy
+ 678 + + value temp1(
+ 679 + +1 std::move(*this),
+ 680 + +2 other.storage());
+ 681 + + value temp2(
+ 682 + +1 std::move(other),
+ 683 + +2 this->storage());
+ 684 + +1 other.~value();
+ 685 + +1 ::new(&other) value(pilfer(temp1));
+ 686 + +1 this->~value();
+ 687 + +1 ::new(this) value(pilfer(temp2));
+ 688 + +1 }
+ 689 + +
+ 690 + + std::istream&
+ 691 + +10 operator>>(
+ 692 + + std::istream& is,
+ 693 + + value& jv)
+ 694 + + {
+ 695 + + using Traits = std::istream::traits_type;
+ 696 + +
+ 697 + + // sentry prepares the stream for reading and finalizes it in destructor
+ 698 + +10 std::istream::sentry sentry(is);
+ 699 + +10 if( !sentry )
+ 700 + +1 return is;
+ 701 + +
+ 702 + +9 parse_options opts = get_parse_options( is );
+ 703 + +9 if( auto depth = static_cast<std::size_t>( is.iword(parse_depth_xalloc) ) )
+ 704 + +3 opts.max_depth = depth;
+ 705 + +
+ 706 + + unsigned char parser_buf[BOOST_JSON_STACK_BUFFER_SIZE / 2];
+ 707 + +9 stream_parser p( {}, opts, parser_buf );
+ 708 + +9 p.reset( jv.storage() );
+ 709 + +
+ 710 + + char read_buf[BOOST_JSON_STACK_BUFFER_SIZE / 2];
+ 711 + +9 std::streambuf& buf = *is.rdbuf();
+ 712 + +9 std::ios::iostate err = std::ios::goodbit;
+ 713 + + #ifndef BOOST_NO_EXCEPTIONS
+ 714 + + try
+ 715 + + #endif
+ 716 + + {
+ 717 + + while( true )
+ 718 + + {
+ 719 + +15 system::error_code ec;
+ 720 + +
+ 721 + + // we peek the buffer; this either makes sure that there's no
+ 722 + + // more input, or makes sure there's something in the internal
+ 723 + + // buffer (so in_avail will return a positive number)
+ 724 + +15 std::istream::int_type c = is.rdbuf()->sgetc();
+ 725 + + // if we indeed reached EOF, we check if we parsed a full JSON
+ 726 + + // document; if not, we error out
+ 727 + +13 if( Traits::eq_int_type(c, Traits::eof()) )
+ 728 + + {
+ 729 + +3 err |= std::ios::eofbit;
+ 730 + +3 p.finish(ec);
+ 731 + +3 if( ec.failed() )
+ 732 + +4 break;
+ 733 + + }
+ 734 + +
+ 735 + + // regardless of reaching EOF, we might have parsed a full JSON
+ 736 + + // document; if so, we successfully finish
+ 737 + +12 if( p.done() )
+ 738 + + {
+ 739 + +3 jv = p.release();
+ 740 + +3 return is;
+ 741 + + }
+ 742 + +
+ 743 + + // at this point we definitely have more input, specifically in
+ 744 + + // buf's internal buffer; we also definitely haven't parsed a whole
+ 745 + + // document
+ 746 + +9 std::streamsize available = buf.in_avail();
+ 747 + + // if this assert fails, the streambuf is buggy
+ 748 + +9 BOOST_ASSERT( available > 0 );
+ 749 + +
+ 750 + +18 available = ( std::min )(
+ 751 + +9 static_cast<std::size_t>(available), sizeof(read_buf) );
+ 752 + + // we read from the internal buffer of buf into our buffer
+ 753 + +9 available = buf.sgetn( read_buf, available );
+ 754 + +
+ 755 + +9 std::size_t consumed = p.write_some(
+ 756 + + read_buf, static_cast<std::size_t>(available), ec );
+ 757 + + // if the parser hasn't consumed the entire input we've took from
+ 758 + + // buf, we put the remaining data back; this should succeed,
+ 759 + + // because we only read data from buf's internal buffer
+ 760 + +21 while( consumed++ < static_cast<std::size_t>(available) )
+ 761 + + {
+ 762 + +12 std::istream::int_type const status = buf.sungetc();
+ 763 + +12 BOOST_ASSERT( status != Traits::eof() );
+ 764 + + (void)status;
+ 765 + + }
+ 766 + +
+ 767 + +9 if( ec.failed() )
+ 768 + +3 break;
+ 769 + +6 }
+ 770 + + }
+ 771 + + #ifndef BOOST_NO_EXCEPTIONS
+ 772 + +2 catch(...)
+ 773 + + {
+ 774 + + try
+ 775 + + {
+ 776 + +2 is.setstate(std::ios::badbit);
+ 777 + + }
+ 778 + + // we ignore the exception, because we need to throw the original
+ 779 + + // exception instead
+ 780 + +1 catch( std::ios::failure const& ) { }
+ 781 + +
+ 782 + +2 if( is.exceptions() & std::ios::badbit )
+ 783 + +1 throw;
+ 784 + +2 }
+ 785 + + #endif
+ 786 + +
+ 787 + +5 is.setstate(err | std::ios::failbit);
+ 788 + +5 return is;
+ 789 + +9 }
+ 790 + +
+ 791 + + std::istream&
+ 792 + +3 operator>>(
+ 793 + + std::istream& is,
+ 794 + + parse_options const& opts)
+ 795 + + {
+ 796 + +3 is.iword(parse_flags_xalloc) = to_bitmask(opts);
+ 797 + +3 is.iword(parse_depth_xalloc) = static_cast<long>(opts.max_depth);
+ 798 + +3 return is;
+ 799 + + }
+ 800 + +
+ 801 + + //----------------------------------------------------------
+ 802 + + //
+ 803 + + // private
+ 804 + + //
+ 805 + + //----------------------------------------------------------
+ 806 + +
+ 807 + + storage_ptr
+ 808 + +417 value::
+ 809 + + destroy() noexcept
+ 810 + + {
+ 811 + +417 switch(kind())
+ 812 + + {
+ 813 + +398 case json::kind::null:
+ 814 + + case json::kind::bool_:
+ 815 + + case json::kind::int64:
+ 816 + + case json::kind::uint64:
+ 817 + + case json::kind::double_:
+ 818 + +398 break;
+ 819 + +
+ 820 + +14 case json::kind::string:
+ 821 + + {
+ 822 + +14 auto sp = str_.storage();
+ 823 + +14 str_.~string();
+ 824 + +14 return sp;
+ 825 + +14 }
+ 826 + +
+ 827 + +2 case json::kind::array:
+ 828 + + {
+ 829 + +2 auto sp = arr_.storage();
+ 830 + +2 arr_.~array();
+ 831 + +2 return sp;
+ 832 + +2 }
+ 833 + +
+ 834 + +3 case json::kind::object:
+ 835 + + {
+ 836 + +3 auto sp = obj_.storage();
+ 837 + +3 obj_.~object();
+ 838 + +3 return sp;
+ 839 + +3 }
+ 840 + +
+ 841 + + }
+ 842 + +398 return std::move(sp_);
+ 843 + + }
+ 844 + +
+ 845 + + bool
+ 846 + +4156 value::
+ 847 + + equal(value const& other) const noexcept
+ 848 + + {
+ 849 + +4156 switch(kind())
+ 850 + + {
+ 851 + +21 default: // unreachable()?
+ 852 + + case json::kind::null:
+ 853 + +21 return other.kind() == json::kind::null;
+ 854 + +
+ 855 + +16 case json::kind::bool_:
+ 856 + + return
+ 857 + +25 other.kind() == json::kind::bool_ &&
+ 858 + +25 get_bool() == other.get_bool();
+ 859 + +
+ 860 + +3931 case json::kind::int64:
+ 861 + +3931 switch(other.kind())
+ 862 + + {
+ 863 + +3904 case json::kind::int64:
+ 864 + +3904 return get_int64() == other.get_int64();
+ 865 + +26 case json::kind::uint64:
+ 866 + +26 if(get_int64() < 0)
+ 867 + +1 return false;
+ 868 + +25 return static_cast<std::uint64_t>(
+ 869 + +25 get_int64()) == other.get_uint64();
+ 870 + +1 default:
+ 871 + +1 return false;
+ 872 + + }
+ 873 + +
+ 874 + +7 case json::kind::uint64:
+ 875 + +7 switch(other.kind())
+ 876 + + {
+ 877 + +2 case json::kind::uint64:
+ 878 + +2 return get_uint64() == other.get_uint64();
+ 879 + +3 case json::kind::int64:
+ 880 + +3 if(other.get_int64() < 0)
+ 881 + +2 return false;
+ 882 + +1 return static_cast<std::uint64_t>(
+ 883 + +1 other.get_int64()) == get_uint64();
+ 884 + +2 default:
+ 885 + +2 return false;
+ 886 + + }
+ 887 + +
+ 888 + +55 case json::kind::double_:
+ 889 + + return
+ 890 + +108 other.kind() == json::kind::double_ &&
+ 891 + +108 get_double() == other.get_double();
+ 892 + +
+ 893 + +45 case json::kind::string:
+ 894 + + return
+ 895 + +87 other.kind() == json::kind::string &&
+ 896 + +87 get_string() == other.get_string();
+ 897 + +
+ 898 + +61 case json::kind::array:
+ 899 + + return
+ 900 + +120 other.kind() == json::kind::array &&
+ 901 + +120 get_array() == other.get_array();
+ 902 + +
+ 903 + +20 case json::kind::object:
+ 904 + + return
+ 905 + +37 other.kind() == json::kind::object &&
+ 906 + +37 get_object() == other.get_object();
+ 907 + + }
+ 908 + + }
+ 909 + +
+ 910 + + //----------------------------------------------------------
+ 911 + + //
+ 912 + + // key_value_pair
+ 913 + + //
+ 914 + + //----------------------------------------------------------
+ 915 + +
+ 916 + + // empty keys point here
+ 917 + + BOOST_JSON_REQUIRE_CONST_INIT
+ 918 + + char const
+ 919 + + key_value_pair::empty_[1] = { 0 };
+ 920 + +
+ 921 + +38150 key_value_pair::
+ 922 + + key_value_pair(
+ 923 + + pilfered<json::value> key,
+ 924 + +38150 pilfered<json::value> value) noexcept
+ 925 + +38150 : value_(value)
+ 926 + + {
+ 927 + + std::size_t len;
+ 928 + +38150 key_ = access::release_key(key.get(), len);
+ 929 + +38150 len_ = static_cast<std::uint32_t>(len);
+ 930 + +38150 }
+ 931 + +
+ 932 + +6858 key_value_pair::
+ 933 + + key_value_pair(
+ 934 + + key_value_pair const& other,
+ 935 + +6858 storage_ptr sp)
+ 936 + +6862 : value_(other.value_, std::move(sp))
+ 937 + + {
+ 938 + + auto p = reinterpret_cast<
+ 939 + +6854 char*>(value_.storage()->
+ 940 + +6854 allocate(other.len_ + 1,
+ 941 + + alignof(char)));
+ 942 + +6596 std::memcpy(
+ 943 + +6596 p, other.key_, other.len_);
+ 944 + +6596 len_ = other.len_;
+ 945 + +6596 p[len_] = 0;
+ 946 + +6596 key_ = p;
+ 947 + +6854 }
+ 948 + +
+ 949 + + //----------------------------------------------------------
+ 950 + +
+ 951 + + namespace detail
+ 952 + + {
+ 953 + +
+ 954 + + std::size_t
+ 955 + +248 hash_value_impl( value const& jv ) noexcept
+ 956 + + {
+ 957 + +248 std::size_t seed = 0;
+ 958 + +
+ 959 + +248 kind const k = jv.kind();
+ 960 + +248 boost::hash_combine( seed, k != kind::int64 ? k : kind::uint64 );
+ 961 + +
+ 962 + +248 visit( value_hasher{seed}, jv );
+ 963 + +248 return seed;
+ 964 + + }
+ 965 + +
+ 966 + + } // namespace detail
+ 967 + + } // namespace json
+ 968 + + } // namespace boost
+ 969 + +
+ 970 + + //----------------------------------------------------------
+ 971 + + //
+ 972 + + // std::hash specialization
+ 973 + + //
+ 974 + + //----------------------------------------------------------
+ 975 + +
+ 976 + + std::size_t
+ 977 + +62 std::hash<::boost::json::value>::operator()(
+ 978 + + ::boost::json::value const& jv) const noexcept
+ 979 + + {
+ 980 + +62 return ::boost::hash< ::boost::json::value >()( jv );
+ 981 + + }
+ 982 + +
+ 983 + + //----------------------------------------------------------
+ 984 + +
+ 985 + + #endif
+ 986 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value_from.hpp.1cdcc419fa9e4a63453aa84ed54ca11f.html b/json/gcovr/index.value_from.hpp.1cdcc419fa9e4a63453aa84ed54ca11f.html new file mode 100644 index 00000000..4bb9ef16 --- /dev/null +++ b/json/gcovr/index.value_from.hpp.1cdcc419fa9e4a63453aa84ed54ca11f.html @@ -0,0 +1,4430 @@ + + + + + + detail/value_from.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/value_from.hpp

+
+ + 100.0% Lines (46/46) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/value_from.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com)
+ 5 + + //
+ 6 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 7 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 8 + + //
+ 9 + + // Official repository: https://github.com/boostorg/json
+ 10 + + //
+ 11 + +
+ 12 + + #ifndef BOOST_JSON_DETAIL_VALUE_FROM_HPP
+ 13 + + #define BOOST_JSON_DETAIL_VALUE_FROM_HPP
+ 14 + +
+ 15 + + #include <boost/json/conversion.hpp>
+ 16 + + #include <boost/describe/enum_to_string.hpp>
+ 17 + + #include <boost/mp11/algorithm.hpp>
+ 18 + +
+ 19 + + #ifndef BOOST_NO_CXX17_HDR_OPTIONAL
+ 20 + + # include <optional>
+ 21 + + #endif
+ 22 + +
+ 23 + + namespace boost {
+ 24 + + namespace json {
+ 25 + +
+ 26 + + namespace detail {
+ 27 + +
+ 28 + + template< class Ctx, class T >
+ 29 + + struct append_tuple_element {
+ 30 + + array& arr;
+ 31 + + Ctx const& ctx;
+ 32 + + T&& t;
+ 33 + +
+ 34 + + template<std::size_t I>
+ 35 + + void
+ 36 + +295 operator()(mp11::mp_size_t<I>) const
+ 37 + + {
+ 38 + + using std::get;
+ 39 + +590 arr.emplace_back(value_from(
+ 40 + +600 get<I>(std::forward<T>(t)), ctx, arr.storage() ));
+ 41 + +295 }
+ 42 + + };
+ 43 + +
+ 44 + + //----------------------------------------------------------
+ 45 + + // User-provided conversion
+ 46 + +
+ 47 + + template< class T, class Ctx >
+ 48 + + void
+ 49 + +35 value_from_impl( user_conversion_tag, value& jv, T&& from, Ctx const& )
+ 50 + + {
+ 51 + +35 tag_invoke( value_from_tag(), jv, static_cast<T&&>(from) );
+ 52 + +35 }
+ 53 + +
+ 54 + + template< class T, class Ctx >
+ 55 + + void
+ 56 + +26 value_from_impl( context_conversion_tag, value& jv, T&& from, Ctx const& ctx)
+ 57 + + {
+ 58 + + using Sup = supported_context<Ctx, T, value_from_conversion>;
+ 59 + +26 tag_invoke( value_from_tag(), jv, static_cast<T&&>(from), Sup::get(ctx) );
+ 60 + +26 }
+ 61 + +
+ 62 + + template< class T, class Ctx >
+ 63 + + void
+ 64 + +2 value_from_impl(
+ 65 + + full_context_conversion_tag, value& jv, T&& from, Ctx const& ctx)
+ 66 + + {
+ 67 + + using Sup = supported_context<Ctx, T, value_from_conversion>;
+ 68 + +2 tag_invoke(
+ 69 + +2 value_from_tag(), jv, static_cast<T&&>(from), Sup::get(ctx), ctx );
+ 70 + +2 }
+ 71 + +
+ 72 + + //----------------------------------------------------------
+ 73 + + // Native conversion
+ 74 + +
+ 75 + + template< class T, class Ctx >
+ 76 + + void
+ 77 + +6539 value_from_impl( native_conversion_tag, value& jv, T&& from, Ctx const& )
+ 78 + + {
+ 79 + +6539 jv = std::forward<T>(from);
+ 80 + +6539 }
+ 81 + +
+ 82 + + // null-like types
+ 83 + + template< class T, class Ctx >
+ 84 + + void
+ 85 + +11 value_from_impl( null_like_conversion_tag, value& jv, T&&, Ctx const& )
+ 86 + + {
+ 87 + + // do nothing
+ 88 + +11 BOOST_ASSERT(jv.is_null());
+ 89 + + (void)jv;
+ 90 + +11 }
+ 91 + +
+ 92 + + // string-like types
+ 93 + + template< class T, class Ctx >
+ 94 + + void
+ 95 + +75 value_from_impl( string_like_conversion_tag, value& jv, T&& from, Ctx const& )
+ 96 + + {
+ 97 + +75 auto sv = static_cast<string_view>(from);
+ 98 + +75 jv.emplace_string().assign(sv);
+ 99 + +75 }
+ 100 + +
+ 101 + + // map-like types
+ 102 + + template< class T, class Ctx >
+ 103 + + void
+ 104 + +46 value_from_impl( map_like_conversion_tag, value& jv, T&& from, Ctx const& ctx )
+ 105 + + {
+ 106 + + using std::get;
+ 107 + +46 object& obj = jv.emplace_object();
+ 108 + +46 obj.reserve(detail::try_size(from, size_implementation<T>()));
+ 109 + +145 for (auto&& elem : from)
+ 110 + +297 obj.emplace(
+ 111 + +99 get<0>(elem),
+ 112 + +99 value_from( get<1>(elem), ctx, obj.storage() ));
+ 113 + +46 }
+ 114 + +
+ 115 + + // ranges
+ 116 + + template< class T, class Ctx >
+ 117 + + void
+ 118 + +97 value_from_impl( sequence_conversion_tag, value& jv, T&& from, Ctx const& ctx )
+ 119 + + {
+ 120 + +97 array& result = jv.emplace_array();
+ 121 + +97 result.reserve(detail::try_size(from, size_implementation<T>()));
+ 122 + + using ForwardedValue = forwarded_value<T&&>;
+ 123 + +6341 for (auto&& elem : from)
+ 124 + +6412 result.emplace_back(
+ 125 + + value_from(
+ 126 + + // not a static_cast in order to appease clang < 4.0
+ 127 + +168 ForwardedValue(elem),
+ 128 + + ctx,
+ 129 + + result.storage() ));
+ 130 + +97 }
+ 131 + +
+ 132 + + // tuple-like types
+ 133 + + template< class T, class Ctx >
+ 134 + + void
+ 135 + +139 value_from_impl( tuple_conversion_tag, value& jv, T&& from, Ctx const& ctx )
+ 136 + + {
+ 137 + +139 constexpr std::size_t n =
+ 138 + + std::tuple_size<remove_cvref<T>>::value;
+ 139 + +139 array& arr = jv.emplace_array();
+ 140 + +139 arr.reserve(n);
+ 141 + +139 mp11::mp_for_each<mp11::mp_iota_c<n>>(
+ 142 + +139 append_tuple_element< Ctx, T >{ arr, ctx, std::forward<T>(from) });
+ 143 + +139 }
+ 144 + +
+ 145 + + // no suitable conversion implementation
+ 146 + + template< class T, class Ctx >
+ 147 + + void
+ 148 + + value_from_impl( no_conversion_tag, value&, T&&, Ctx const& )
+ 149 + + {
+ 150 + + static_assert(
+ 151 + + !std::is_same<T, T>::value,
+ 152 + + "No suitable tag_invoke overload found for the type");
+ 153 + + }
+ 154 + +
+ 155 + + template< class Ctx, class T >
+ 156 + + struct from_described_member
+ 157 + + {
+ 158 + + static_assert(
+ 159 + + uniquely_named_members< remove_cvref<T> >::value,
+ 160 + + "The type has several described members with the same name.");
+ 161 + +
+ 162 + + using Ds = described_members< remove_cvref<T> >;
+ 163 + +
+ 164 + + object& obj;
+ 165 + + Ctx const& ctx;
+ 166 + + T&& from;
+ 167 + +
+ 168 + + template< class I >
+ 169 + + void
+ 170 + + operator()(I) const
+ 171 + + {
+ 172 + + using D = mp11::mp_at<Ds, I>;
+ 173 + + obj.emplace(
+ 174 + + D::name,
+ 175 + + value_from(
+ 176 + + static_cast<T&&>(from).* D::pointer,
+ 177 + + ctx,
+ 178 + + obj.storage()));
+ 179 + + }
+ 180 + + };
+ 181 + +
+ 182 + + // described classes
+ 183 + + template< class T, class Ctx >
+ 184 + + void
+ 185 + + value_from_impl(
+ 186 + + described_class_conversion_tag, value& jv, T&& from, Ctx const& ctx )
+ 187 + + {
+ 188 + + object& obj = jv.emplace_object();
+ 189 + + from_described_member<Ctx, T> member_converter{
+ 190 + + obj, ctx, static_cast<T&&>(from)};
+ 191 + +
+ 192 + + using Ds = typename decltype(member_converter)::Ds;
+ 193 + + constexpr std::size_t N = mp11::mp_size<Ds>::value;
+ 194 + + obj.reserve(N);
+ 195 + + mp11::mp_for_each< mp11::mp_iota_c<N> >(member_converter);
+ 196 + + }
+ 197 + +
+ 198 + + // described enums
+ 199 + + template< class T, class Ctx >
+ 200 + + void
+ 201 + + value_from_impl(
+ 202 + + described_enum_conversion_tag, value& jv, T from, Ctx const& )
+ 203 + + {
+ 204 + + (void)jv;
+ 205 + + (void)from;
+ 206 + + #ifdef BOOST_DESCRIBE_CXX14
+ 207 + + char const* const name = describe::enum_to_string(from, nullptr);
+ 208 + + if( name )
+ 209 + + {
+ 210 + + string& str = jv.emplace_string();
+ 211 + + str.assign(name);
+ 212 + + }
+ 213 + + else
+ 214 + + {
+ 215 + + using Integer = typename std::underlying_type< remove_cvref<T> >::type;
+ 216 + + jv = static_cast<Integer>(from);
+ 217 + + }
+ 218 + + #endif
+ 219 + + }
+ 220 + +
+ 221 + + // optionals
+ 222 + + template< class T, class Ctx >
+ 223 + + void
+ 224 + + value_from_impl(
+ 225 + + optional_conversion_tag, value& jv, T&& from, Ctx const& ctx )
+ 226 + + {
+ 227 + + if( from )
+ 228 + + value_from( *from, ctx, jv );
+ 229 + + else
+ 230 + + jv = nullptr;
+ 231 + + }
+ 232 + +
+ 233 + + // variants
+ 234 + + template< class Ctx >
+ 235 + + struct value_from_visitor
+ 236 + + {
+ 237 + + value& jv;
+ 238 + + Ctx const& ctx;
+ 239 + +
+ 240 + + template<class T>
+ 241 + + void
+ 242 + + operator()(T&& t)
+ 243 + + {
+ 244 + + value_from( static_cast<T&&>(t), ctx, jv );
+ 245 + + }
+ 246 + + };
+ 247 + +
+ 248 + + template< class Ctx, class T >
+ 249 + + void
+ 250 + + value_from_impl( variant_conversion_tag, value& jv, T&& from, Ctx const& ctx )
+ 251 + + {
+ 252 + + visit( value_from_visitor<Ctx>{ jv, ctx }, static_cast<T&&>(from) );
+ 253 + + }
+ 254 + +
+ 255 + + template< class Ctx, class T >
+ 256 + + void
+ 257 + + value_from_impl( path_conversion_tag, value& jv, T&& from, Ctx const& )
+ 258 + + {
+ 259 + + std::string s = from.generic_string();
+ 260 + + string_view sv = s;
+ 261 + + jv.emplace_string().assign(sv);
+ 262 + + }
+ 263 + +
+ 264 + + //----------------------------------------------------------
+ 265 + + // Contextual conversions
+ 266 + +
+ 267 + + template< class Ctx, class T >
+ 268 + + using value_from_category = conversion_category<
+ 269 + + Ctx, T, value_from_conversion >;
+ 270 + +
+ 271 + + } // detail
+ 272 + +
+ 273 + + #ifndef BOOST_NO_CXX17_HDR_OPTIONAL
+ 274 + + inline
+ 275 + + void
+ 276 + + tag_invoke(
+ 277 + + value_from_tag,
+ 278 + + value& jv,
+ 279 + + std::nullopt_t)
+ 280 + + {
+ 281 + + // do nothing
+ 282 + + BOOST_ASSERT(jv.is_null());
+ 283 + + (void)jv;
+ 284 + + }
+ 285 + + #endif
+ 286 + +
+ 287 + + } // namespace json
+ 288 + + } // namespace boost
+ 289 + +
+ 290 + + #endif
+ 291 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value_from.hpp.a24a88c1f8fcc581db892ed3062c98a8.html b/json/gcovr/index.value_from.hpp.a24a88c1f8fcc581db892ed3062c98a8.html new file mode 100644 index 00000000..d2bded98 --- /dev/null +++ b/json/gcovr/index.value_from.hpp.a24a88c1f8fcc581db892ed3062c98a8.html @@ -0,0 +1,3478 @@ + + + + + + value_from.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

value_from.hpp

+
+ + 92.3% Lines (12/13) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
value_from.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com)
+ 5 + + //
+ 6 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 7 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 8 + + //
+ 9 + + // Official repository: https://github.com/boostorg/json
+ 10 + + //
+ 11 + +
+ 12 + + #ifndef BOOST_JSON_VALUE_FROM_HPP
+ 13 + + #define BOOST_JSON_VALUE_FROM_HPP
+ 14 + +
+ 15 + + #include <boost/core/detail/static_assert.hpp>
+ 16 + + #include <boost/json/detail/value_from.hpp>
+ 17 + +
+ 18 + + namespace boost {
+ 19 + + namespace json {
+ 20 + +
+ 21 + + /** Convert an object of type `T` to @ref value.
+ 22 + +
+ 23 + + This function attempts to convert an object
+ 24 + + of type `T` to @ref value using
+ 25 + +
+ 26 + + @li one of @ref value's constructors,
+ 27 + +
+ 28 + + @li a library-provided generic conversion, or
+ 29 + +
+ 30 + + @li a user-provided overload of `tag_invoke`.
+ 31 + +
+ 32 + + Out of the function supports default constructible types satisfying
+ 33 + + {req_SequenceContainer}, arrays, arithmetic types, `bool`, `std::tuple`,
+ 34 + + `std::pair`, `std::optional`, `std::variant`, `std::nullptr_t`, and structs
+ 35 + + and enums described using Boost.Describe.
+ 36 + +
+ 37 + + Conversion of other types is done by calling an overload of `tag_invoke`
+ 38 + + found by argument-dependent lookup. Its signature should be similar to:
+ 39 + +
+ 40 + + @code
+ 41 + + template< class FullContext >
+ 42 + + void tag_invoke( value_from_tag, value&, T, const Context&, const FullContext& );
+ 43 + + @endcode
+ 44 + +
+ 45 + + or
+ 46 + +
+ 47 + + @code
+ 48 + + void tag_invoke( value_from_tag, value&, T, const Context& );
+ 49 + + @endcode
+ 50 + +
+ 51 + + or
+ 52 + +
+ 53 + + @code
+ 54 + + void tag_invoke( value_from_tag, value&, T );
+ 55 + + @endcode
+ 56 + +
+ 57 + + The overloads are checked for existence in that order and the first that
+ 58 + + matches will be selected. <br>
+ 59 + +
+ 60 + + The `ctx` argument can be used either as a tag type to provide conversions
+ 61 + + for third-party types, or to pass extra data to the conversion function.
+ 62 + +
+ 63 + + Overloads **(2)** and **(4)** construct their return value using the
+ 64 + + @ref storage_ptr `sp`, which ensures that the memory resource is correctly
+ 65 + + propagated.
+ 66 + +
+ 67 + + @par Exception Safety
+ 68 + + Strong guarantee.
+ 69 + +
+ 70 + + @tparam T The type of the object to convert.
+ 71 + +
+ 72 + + @tparam Context The type of context passed to the conversion function.
+ 73 + +
+ 74 + + @param t The object to convert.
+ 75 + +
+ 76 + + @param ctx Context passed to the conversion function.
+ 77 + +
+ 78 + + @param jv @ref value out parameter.
+ 79 + +
+ 80 + + @see @ref value_from_tag, @ref value_to,
+ 81 + + <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
+ 82 + + tag_invoke: A general pattern for supporting customisable functions</a>
+ 83 + + */
+ 84 + + /// @{
+ 85 + + template< class T, class Context >
+ 86 + + void
+ 87 + +6970 value_from(
+ 88 + + T&& t,
+ 89 + + Context const& ctx,
+ 90 + + value& jv)
+ 91 + + {
+ 92 + + using bare_T = detail::remove_cvref<T>;
+ 93 + + BOOST_CORE_STATIC_ASSERT((
+ 94 + + detail::conversion_round_trips<
+ 95 + + Context, bare_T, detail::value_from_conversion>::value));
+ 96 + + using cat = detail::value_from_category<Context, bare_T>;
+ 97 + +6970 detail::value_from_impl( cat(), jv, std::forward<T>(t), ctx );
+ 98 + +6970 }
+ 99 + +
+ 100 + + /** Overload
+ 101 + + @param t
+ 102 + + @param ctx
+ 103 + + @param sp A storage pointer referring to the memory resource to use for the
+ 104 + + returned @ref value.
+ 105 + +
+ 106 + + @return Overloads **(2)** and **(4)** return `t` converted to @ref value.
+ 107 + + Overloads **(1)** and **3** return `void` instead and pass their result via
+ 108 + + the out parameter `jv`.
+ 109 + + */
+ 110 + + template< class T, class Context >
+ 111 + + #ifndef BOOST_JSON_DOCS
+ 112 + + typename std::enable_if<
+ 113 + + !std::is_same< detail::remove_cvref<Context>, storage_ptr >::value &&
+ 114 + + !std::is_same< detail::remove_cvref<Context>, value >::value,
+ 115 + + value >::type
+ 116 + + #else
+ 117 + + value
+ 118 + + #endif
+ 119 + +6951 value_from(
+ 120 + + T&& t,
+ 121 + + Context const& ctx,
+ 122 + + storage_ptr sp = {})
+ 123 + + {
+ 124 + +6951 value jv(std::move(sp));
+ 125 + +6951 value_from( static_cast<T&&>(t), ctx, jv );
+ 126 + +6951 return jv;
+ 127 + + }
+ 128 + +
+ 129 + + /// Overload
+ 130 + + template<class T>
+ 131 + + void
+ 132 + +19 value_from(
+ 133 + + T&& t,
+ 134 + + value& jv)
+ 135 + + {
+ 136 + +19 value_from( static_cast<T&&>(t), detail::no_context(), jv );
+ 137 + +19 }
+ 138 + +
+ 139 + + /// Overload
+ 140 + + template<class T>
+ 141 + + value
+ 142 + +222 value_from(
+ 143 + + T&& t,
+ 144 + + storage_ptr sp = {})
+ 145 + + {
+ 146 + + return value_from(
+ 147 + +222 static_cast<T&&>(t), detail::no_context(), std::move(sp) );
+ 148 + + }
+ 149 + + /// @}
+ 150 + +
+ 151 + + /** Determine if `T` can be converted to @ref value.
+ 152 + +
+ 153 + + If `T` can be converted to @ref value via a call to @ref value_from, the
+ 154 + + static data member `value` is defined as `true`. Otherwise, `value` is
+ 155 + + defined as `false`.
+ 156 + +
+ 157 + + @see @ref value_from.
+ 158 + + */
+ 159 + + #ifdef BOOST_JSON_DOCS
+ 160 + + template<class T>
+ 161 + + using has_value_from = __see_below__;
+ 162 + + #else
+ 163 + + template<class T>
+ 164 + + using has_value_from = detail::can_convert<
+ 165 + + detail::remove_cvref<T>, detail::value_from_conversion>;
+ 166 + + #endif
+ 167 + +
+ 168 + + } // namespace json
+ 169 + + } // namespace boost
+ 170 + +
+ 171 + + #endif
+ 172 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value_ref.hpp.5136da43247c9084cc2a038477b40231.html b/json/gcovr/index.value_ref.hpp.5136da43247c9084cc2a038477b40231.html new file mode 100644 index 00000000..cffdf037 --- /dev/null +++ b/json/gcovr/index.value_ref.hpp.5136da43247c9084cc2a038477b40231.html @@ -0,0 +1,6142 @@ + + + + + + value_ref.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

value_ref.hpp

+
+ + 100.0% Lines (114/114) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
value_ref.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_VALUE_REF_HPP
+ 11 + + #define BOOST_JSON_VALUE_REF_HPP
+ 12 + +
+ 13 + + #include <boost/json/detail/config.hpp>
+ 14 + + #include <boost/json/storage_ptr.hpp>
+ 15 + + #include <boost/json/string.hpp>
+ 16 + + #include <initializer_list>
+ 17 + + #include <type_traits>
+ 18 + + #include <utility>
+ 19 + +
+ 20 + + namespace boost {
+ 21 + + namespace json {
+ 22 + +
+ 23 + + #ifndef BOOST_JSON_DOCS
+ 24 + + class value;
+ 25 + + class object;
+ 26 + + class array;
+ 27 + + class string;
+ 28 + + #endif
+ 29 + +
+ 30 + + //----------------------------------------------------------
+ 31 + +
+ 32 + + /** The type used in initializer lists.
+ 33 + +
+ 34 + + This type is used in initializer lists for lazy construction of and
+ 35 + + assignment to the container types @ref value, @ref array, and @ref object.
+ 36 + + The two types of initializer lists used are:
+ 37 + +
+ 38 + + @li `std::initializer_list< value_ref >` for constructing or assigning
+ 39 + + a @ref value or @ref array, and
+ 40 + + @li `std::initializer_list< std::pair< string_view, value_ref > >` for
+ 41 + + constructing or assigning an @ref object.
+ 42 + +
+ 43 + + A `value_ref` uses reference semantics. Creation of the actual container
+ 44 + + from the initializer list is lazily deferred until the list is used. This
+ 45 + + means that the @ref boost::container::pmr::memory_resource used to
+ 46 + + construct a container can be specified after the point where the
+ 47 + + initializer list is specified. Also, the usage of this type allows to avoid
+ 48 + + constructing a @ref value until it's necessary.
+ 49 + +
+ 50 + + @par Example
+ 51 + + This example demonstrates how a user-defined type containing a JSON value
+ 52 + + can be constructed from an initializer list:
+ 53 + +
+ 54 + + @code
+ 55 + + class my_type
+ 56 + + {
+ 57 + + value jv_;
+ 58 + +
+ 59 + + public:
+ 60 + + my_type( std::initializer_list<value_ref> init )
+ 61 + + : jv_(init)
+ 62 + + {
+ 63 + + }
+ 64 + + };
+ 65 + + @endcode
+ 66 + +
+ 67 + + @warning `value_ref` does not take ownership of the objects it was
+ 68 + + constructed with. If those objects' lifetimes end before the `value_ref`
+ 69 + + object is used, you will get undefined behavior. Because of this it is
+ 70 + + advised against declaring a variable of type
+ 71 + + `std::initializer_list<value_ref>` except in function parameter lists.
+ 72 + +
+ 73 + + @see @ref value, @ref array, @ref object, @ref value::set_at_pointer.
+ 74 + + */
+ 75 + + class value_ref
+ 76 + + {
+ 77 + + friend class value;
+ 78 + + friend class object;
+ 79 + + friend class array;
+ 80 + +
+ 81 + + friend class value_ref_test;
+ 82 + +
+ 83 + + enum class what
+ 84 + + {
+ 85 + + str,
+ 86 + + ini,
+ 87 + + func,
+ 88 + + cfunc,
+ 89 + + strfunc,
+ 90 + + };
+ 91 + +
+ 92 + + using init_list =
+ 93 + + std::initializer_list<value_ref>;
+ 94 + +
+ 95 + + struct func_type
+ 96 + + {
+ 97 + + value(*f)(void*, storage_ptr);
+ 98 + + void* p;
+ 99 + + };
+ 100 + +
+ 101 + + struct cfunc_type
+ 102 + + {
+ 103 + + value(*f)(void const*, storage_ptr);
+ 104 + + void const* p;
+ 105 + + };
+ 106 + +
+ 107 + + union arg_type
+ 108 + + {
+ 109 + + string_view str_;
+ 110 + + init_list init_list_;
+ 111 + +
+ 112 + + signed char schar_;
+ 113 + + short short_;
+ 114 + + int int_;
+ 115 + + long long_;
+ 116 + + long long long_long_;
+ 117 + + unsigned char uchar_;
+ 118 + + unsigned short ushort_;
+ 119 + + unsigned int uint_;
+ 120 + + unsigned long ulong_;
+ 121 + + unsigned long long ulong_long_;
+ 122 + + float float_;
+ 123 + + double double_;
+ 124 + + bool bool_;
+ 125 + + std::nullptr_t nullptr_;
+ 126 + +
+ 127 + +98 arg_type() {}
+ 128 + +912 explicit arg_type(string_view t) noexcept : str_(t) {}
+ 129 + +656 explicit arg_type(init_list t) noexcept : init_list_(t) {}
+ 130 + +1 explicit arg_type(signed char t) noexcept : schar_(t) {}
+ 131 + +3 explicit arg_type(short t) noexcept : short_(t) {}
+ 132 + +2692 explicit arg_type(int t) noexcept : int_(t) {}
+ 133 + +3 explicit arg_type(long t) noexcept : long_(t) {}
+ 134 + +3 explicit arg_type(long long t) noexcept : long_long_(t) {}
+ 135 + +21 explicit arg_type(unsigned char t) noexcept : uchar_(t) {}
+ 136 + +3 explicit arg_type(unsigned short t) noexcept : ushort_(t) {}
+ 137 + +45 explicit arg_type(unsigned int t) noexcept : uint_(t) {}
+ 138 + +3 explicit arg_type(unsigned long t) noexcept : ulong_(t) {}
+ 139 + +3 explicit arg_type(unsigned long long t) noexcept : ulong_long_(t) {}
+ 140 + +18 explicit arg_type(float t) noexcept : float_(t) {}
+ 141 + +34 explicit arg_type(double t) noexcept : double_(t) {}
+ 142 + +287 explicit arg_type(bool t) noexcept : bool_(t) {}
+ 143 + +88 explicit arg_type(std::nullptr_t) noexcept : nullptr_() {}
+ 144 + + };
+ 145 + +
+ 146 + + arg_type arg_;
+ 147 + + #ifndef BOOST_JSON_DOCS
+ 148 + + // VFALCO doc toolchain erroneously
+ 149 + + // displays private, anonymous unions as public
+ 150 + + union
+ 151 + + {
+ 152 + + func_type f_;
+ 153 + + cfunc_type cf_;
+ 154 + + };
+ 155 + + #endif
+ 156 + + what what_;
+ 157 + +
+ 158 + + public:
+ 159 + + /** Constructors.
+ 160 + +
+ 161 + + @li **(1)** copy constructor.
+ 162 + + @li **(2)** move constructor.
+ 163 + + @li **(3)** the constructed value stores a reference to `t`'s character
+ 164 + + array.
+ 165 + + @li **(4)** the constructed value stores a `const` reference to `t`.
+ 166 + + @li **(5)** the constructed value stores an rvalue reference to `t`.
+ 167 + + @li **(6)** the constructed value stores a copy of `b`.
+ 168 + + @li **(7)**--**(18)** the constructed value stores a copy of `t`.
+ 169 + + @li **(19)** the constrcuted value stores `nullptr`.
+ 170 + + @li **(20)** the constrcuted value stores a copy of `init`.
+ 171 + +
+ 172 + + In addition the constructed object stores a pointer to a function that
+ 173 + + captures the type information necessary to construct a @ref value from
+ 174 + + the stored data.
+ 175 + +
+ 176 + + @warning The overloads that accept references do not take ownership of
+ 177 + + referenced objects. The caller is responsible for making sure those
+ 178 + + objects do not go out of scope before the `value_ref` object is used.
+ 179 + + It is advised you only use `value_ref` (or any type that contains a
+ 180 + + `value_ref` subobject) as function parameters or take special care to
+ 181 + + not invoke undefeined behavior.
+ 182 + +
+ 183 + + @par Complexity
+ 184 + + @li **(1)**--**(19)** constant.
+ 185 + + @li **(20)** linear in `init.size()`.
+ 186 + +
+ 187 + + @par Exception Safety
+ 188 + + No-throw guarantee.
+ 189 + +
+ 190 + + @{
+ 191 + + */
+ 192 + + value_ref(
+ 193 + + value_ref const&) = default;
+ 194 + +
+ 195 + + /// Overload
+ 196 + + value_ref(
+ 197 + + value_ref&&) = default;
+ 198 + +
+ 199 + + /// Overload
+ 200 + + #ifdef BOOST_JSON_DOCS
+ 201 + + value_ref(string_view s) noexcept;
+ 202 + + #else
+ 203 + + template<
+ 204 + + class T
+ 205 + + ,class = typename
+ 206 + + std::enable_if<
+ 207 + + std::is_constructible<
+ 208 + + string_view, T>::value>::type
+ 209 + + >
+ 210 + +912 value_ref(
+ 211 + + T const& t) noexcept
+ 212 + +912 : arg_(string_view(t))
+ 213 + +912 , what_(what::str)
+ 214 + + {
+ 215 + +912 }
+ 216 + + #endif
+ 217 + +
+ 218 + + /// Overload
+ 219 + + template<class T>
+ 220 + +22 value_ref(
+ 221 + + T const& t
+ 222 + + #ifndef BOOST_JSON_DOCS
+ 223 + + ,typename std::enable_if<
+ 224 + + ! std::is_constructible<
+ 225 + + string_view, T>::value &&
+ 226 + + ! std::is_same<bool, T>::value
+ 227 + + >::type* = 0
+ 228 + + #endif
+ 229 + + ) noexcept
+ 230 + +22 : cf_{&from_const<T>, &t}
+ 231 + +22 , what_(what::cfunc)
+ 232 + + {
+ 233 + +22 }
+ 234 + +
+ 235 + + /// Overload
+ 236 + + template<class T>
+ 237 + +76 value_ref(
+ 238 + + T&& t
+ 239 + + #ifndef BOOST_JSON_DOCS
+ 240 + + ,typename std::enable_if<
+ 241 + + (! std::is_constructible<
+ 242 + + string_view, T>::value ||
+ 243 + + std::is_same<string, T>::value) &&
+ 244 + + ! std::is_same<bool,
+ 245 + + detail::remove_cvref<T>>::value &&
+ 246 + + std::is_same<T, detail::remove_cvref<T>>
+ 247 + + ::value>::type* = 0
+ 248 + + #endif
+ 249 + + ) noexcept
+ 250 + +76 : f_{&from_rvalue<
+ 251 + + detail::remove_cvref<T>>, &t}
+ 252 + +76 , what_(std::is_same<string, T>::value ?
+ 253 + +76 what::strfunc : what::func)
+ 254 + + {
+ 255 + +76 }
+ 256 + +
+ 257 + + /// Overload
+ 258 + + #ifdef BOOST_JSON_DOCS
+ 259 + + value_ref(bool b) noexcept;
+ 260 + + #else
+ 261 + + template<
+ 262 + + class T
+ 263 + + ,class = typename std::enable_if<
+ 264 + + std::is_same<T, bool>::value>::type
+ 265 + + >
+ 266 + +287 value_ref(
+ 267 + + T b) noexcept
+ 268 + +287 : arg_(b)
+ 269 + +287 , cf_{&from_builtin<bool>, &arg_.bool_}
+ 270 + +287 , what_(what::cfunc)
+ 271 + + {
+ 272 + +287 }
+ 273 + + #endif
+ 274 + +
+ 275 + + /// Overload
+ 276 + +1 value_ref(signed char t) noexcept
+ 277 + +1 : arg_(t)
+ 278 + +1 , cf_{&from_builtin<signed char>, &arg_.schar_}
+ 279 + +1 , what_(what::cfunc)
+ 280 + + {
+ 281 + +1 }
+ 282 + +
+ 283 + + /// Overload
+ 284 + +3 value_ref(short t) noexcept
+ 285 + +3 : arg_(t)
+ 286 + +3 , cf_{&from_builtin<short>, &arg_.short_}
+ 287 + +3 , what_(what::cfunc)
+ 288 + + {
+ 289 + +3 }
+ 290 + +
+ 291 + + /// Overload
+ 292 + +2692 value_ref(int t) noexcept
+ 293 + +2692 : arg_(t)
+ 294 + +2692 , cf_{&from_builtin<int>, &arg_.int_}
+ 295 + +2692 , what_(what::cfunc)
+ 296 + + {
+ 297 + +2692 }
+ 298 + +
+ 299 + + /// Overload
+ 300 + +3 value_ref(long t) noexcept
+ 301 + +3 : arg_(t)
+ 302 + +3 , cf_{&from_builtin<
+ 303 + +3 long>, &arg_.long_}
+ 304 + +3 , what_(what::cfunc)
+ 305 + + {
+ 306 + +3 }
+ 307 + +
+ 308 + + /// Overload
+ 309 + +3 value_ref(long long t) noexcept
+ 310 + +3 : arg_(t)
+ 311 + +3 , cf_{&from_builtin<
+ 312 + +3 long long>, &arg_.long_long_}
+ 313 + +3 , what_(what::cfunc)
+ 314 + + {
+ 315 + +3 }
+ 316 + +
+ 317 + + /// Overload
+ 318 + +21 value_ref(unsigned char t) noexcept
+ 319 + +21 : arg_(t)
+ 320 + +21 , cf_{&from_builtin<
+ 321 + +21 unsigned char>, &arg_.uchar_}
+ 322 + +21 , what_(what::cfunc)
+ 323 + + {
+ 324 + +21 }
+ 325 + +
+ 326 + + /// Overload
+ 327 + +3 value_ref(unsigned short t) noexcept
+ 328 + +3 : arg_(t)
+ 329 + +3 , cf_{&from_builtin<
+ 330 + +3 unsigned short>, &arg_.ushort_}
+ 331 + +3 , what_(what::cfunc)
+ 332 + + {
+ 333 + +3 }
+ 334 + +
+ 335 + + /// Overload
+ 336 + +45 value_ref(unsigned int t) noexcept
+ 337 + +45 : arg_(t)
+ 338 + +45 , cf_{&from_builtin<
+ 339 + +45 unsigned int>, &arg_.uint_}
+ 340 + +45 , what_(what::cfunc)
+ 341 + + {
+ 342 + +45 }
+ 343 + +
+ 344 + + /// Overload
+ 345 + +3 value_ref(unsigned long t) noexcept
+ 346 + +3 : arg_(t)
+ 347 + +3 , cf_{&from_builtin<
+ 348 + +3 unsigned long>, &arg_.ulong_}
+ 349 + +3 , what_(what::cfunc)
+ 350 + + {
+ 351 + +3 }
+ 352 + +
+ 353 + + /// Overload
+ 354 + +3 value_ref(unsigned long long t) noexcept
+ 355 + +3 : arg_(t)
+ 356 + +3 , cf_{&from_builtin<
+ 357 + +3 unsigned long long>, &arg_.ulong_long_}
+ 358 + +3 , what_(what::cfunc)
+ 359 + + {
+ 360 + +3 }
+ 361 + +
+ 362 + + /// Overload
+ 363 + +18 value_ref(float t) noexcept
+ 364 + +18 : arg_(t)
+ 365 + +18 , cf_{&from_builtin<
+ 366 + +18 float>, &arg_.float_}
+ 367 + +18 , what_(what::cfunc)
+ 368 + + {
+ 369 + +18 }
+ 370 + +
+ 371 + + /// Overload
+ 372 + +34 value_ref(double t) noexcept
+ 373 + +34 : arg_(t)
+ 374 + +34 , cf_{&from_builtin<
+ 375 + +34 double>, &arg_.double_}
+ 376 + +34 , what_(what::cfunc)
+ 377 + + {
+ 378 + +34 }
+ 379 + +
+ 380 + + /// Overload
+ 381 + +88 value_ref(std::nullptr_t) noexcept
+ 382 + +88 : arg_(nullptr)
+ 383 + +88 , cf_{&from_builtin<
+ 384 + +88 std::nullptr_t>, &arg_.nullptr_}
+ 385 + +88 , what_(what::cfunc)
+ 386 + + {
+ 387 + +88 }
+ 388 + +
+ 389 + + /// Overload
+ 390 + +656 value_ref(
+ 391 + + std::initializer_list<value_ref> init) noexcept
+ 392 + +656 : arg_(init)
+ 393 + +656 , what_(what::ini)
+ 394 + + {
+ 395 + +656 }
+ 396 + +
+ 397 + + /// @}
+ 398 + +
+ 399 + + #ifndef BOOST_JSON_DOCS
+ 400 + + // Not public
+ 401 + + //private:
+ 402 + + // VFALCO Why is this needed?
+ 403 + + /** Operator conversion to @ref value
+ 404 + +
+ 405 + + This allows creation of a @ref value from
+ 406 + + an initializer list element.
+ 407 + + */
+ 408 + + BOOST_JSON_DECL
+ 409 + + operator value() const;
+ 410 + + #endif
+ 411 + +
+ 412 + + private:
+ 413 + + template<class T>
+ 414 + + static
+ 415 + + value
+ 416 + + from_builtin(
+ 417 + + void const* p,
+ 418 + + storage_ptr sp) noexcept;
+ 419 + +
+ 420 + + template<class T>
+ 421 + + static
+ 422 + + value
+ 423 + + from_const(
+ 424 + + void const* p,
+ 425 + + storage_ptr sp);
+ 426 + +
+ 427 + + template<class T>
+ 428 + + static
+ 429 + + value
+ 430 + + from_rvalue(
+ 431 + + void* p,
+ 432 + + storage_ptr sp);
+ 433 + +
+ 434 + + static
+ 435 + + BOOST_JSON_DECL
+ 436 + + value
+ 437 + + from_init_list(
+ 438 + + void const* p,
+ 439 + + storage_ptr sp);
+ 440 + +
+ 441 + + inline
+ 442 + + bool
+ 443 + + is_key_value_pair() const noexcept;
+ 444 + +
+ 445 + + static
+ 446 + + inline
+ 447 + + bool
+ 448 + + maybe_object(
+ 449 + + std::initializer_list<
+ 450 + + value_ref> init) noexcept;
+ 451 + +
+ 452 + + inline
+ 453 + + string_view
+ 454 + + get_string() const noexcept;
+ 455 + +
+ 456 + + BOOST_JSON_DECL
+ 457 + + value
+ 458 + + make_value(
+ 459 + + storage_ptr sp) const;
+ 460 + +
+ 461 + + BOOST_JSON_DECL
+ 462 + + static
+ 463 + + value
+ 464 + + make_value(
+ 465 + + std::initializer_list<
+ 466 + + value_ref> init,
+ 467 + + storage_ptr sp);
+ 468 + +
+ 469 + + BOOST_JSON_DECL
+ 470 + + static
+ 471 + + object
+ 472 + + make_object(
+ 473 + + std::initializer_list<value_ref> init,
+ 474 + + storage_ptr sp);
+ 475 + +
+ 476 + + BOOST_JSON_DECL
+ 477 + + static
+ 478 + + array
+ 479 + + make_array(
+ 480 + + std::initializer_list<
+ 481 + + value_ref> init,
+ 482 + + storage_ptr sp);
+ 483 + +
+ 484 + + BOOST_JSON_DECL
+ 485 + + static
+ 486 + + void
+ 487 + + write_array(
+ 488 + + value* dest,
+ 489 + + std::initializer_list<
+ 490 + + value_ref> init,
+ 491 + + storage_ptr const& sp);
+ 492 + + };
+ 493 + +
+ 494 + + } // namespace json
+ 495 + + } // namespace boost
+ 496 + +
+ 497 + + // Must be included here for this file to stand alone
+ 498 + + #include <boost/json/value.hpp>
+ 499 + +
+ 500 + + // includes are at the bottom of <boost/json/value.hpp>
+ 501 + + //#include <boost/json/impl/value.hpp>
+ 502 + + //#include <boost/json/impl/value.ipp>
+ 503 + +
+ 504 + + #endif
+ 505 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value_ref.hpp.9e9582fd1af4a003bf535e71a0b7904d.html b/json/gcovr/index.value_ref.hpp.9e9582fd1af4a003bf535e71a0b7904d.html new file mode 100644 index 00000000..8c196463 --- /dev/null +++ b/json/gcovr/index.value_ref.hpp.9e9582fd1af4a003bf535e71a0b7904d.html @@ -0,0 +1,2574 @@ + + + + + + impl/value_ref.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/value_ref.hpp

+
+ + 100.0% Lines (7/7) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/value_ref.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_VALUE_REF_HPP
+ 11 + + #define BOOST_JSON_IMPL_VALUE_REF_HPP
+ 12 + +
+ 13 + + namespace boost {
+ 14 + + namespace json {
+ 15 + +
+ 16 + + template<class T>
+ 17 + + value
+ 18 + +8409 value_ref::
+ 19 + + from_builtin(
+ 20 + + void const* p,
+ 21 + + storage_ptr sp) noexcept
+ 22 + + {
+ 23 + + return value(
+ 24 + + *reinterpret_cast<
+ 25 + + T const*>(p),
+ 26 + +8409 std::move(sp));
+ 27 + + }
+ 28 + +
+ 29 + + template<class T>
+ 30 + + value
+ 31 + +9 value_ref::
+ 32 + + from_const(
+ 33 + + void const* p,
+ 34 + + storage_ptr sp)
+ 35 + + {
+ 36 + + return value(
+ 37 + + *reinterpret_cast<
+ 38 + + T const*>(p),
+ 39 + +9 std::move(sp));
+ 40 + + }
+ 41 + +
+ 42 + + template<class T>
+ 43 + + value
+ 44 + +63 value_ref::
+ 45 + + from_rvalue(
+ 46 + + void* p,
+ 47 + + storage_ptr sp)
+ 48 + + {
+ 49 + + return value(
+ 50 + +63 std::move(
+ 51 + + *reinterpret_cast<T*>(p)),
+ 52 + +126 std::move(sp));
+ 53 + + }
+ 54 + +
+ 55 + + } // namespace json
+ 56 + + } // namespace boost
+ 57 + +
+ 58 + + #endif
+ 59 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value_ref.ipp.e9a0bd8aab92a2b5ab364bf6b69e3959.html b/json/gcovr/index.value_ref.ipp.e9a0bd8aab92a2b5ab364bf6b69e3959.html new file mode 100644 index 00000000..40154cb7 --- /dev/null +++ b/json/gcovr/index.value_ref.ipp.e9a0bd8aab92a2b5ab364bf6b69e3959.html @@ -0,0 +1,3622 @@ + + + + + + impl/value_ref.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/value_ref.ipp

+
+ + 96.0% Lines (72/75) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/value_ref.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_VALUE_REF_IPP
+ 11 + + #define BOOST_JSON_IMPL_VALUE_REF_IPP
+ 12 + +
+ 13 + + #include <boost/json/value_ref.hpp>
+ 14 + + #include <boost/json/array.hpp>
+ 15 + + #include <boost/json/value.hpp>
+ 16 + +
+ 17 + + namespace boost {
+ 18 + + namespace json {
+ 19 + +
+ 20 + +3236 value_ref::
+ 21 + + operator
+ 22 + + value() const
+ 23 + + {
+ 24 + +3236 return make_value({});
+ 25 + + }
+ 26 + +
+ 27 + + value
+ 28 + + value_ref::
+ 29 + + from_init_list(
+ 30 + + void const* p,
+ 31 + + storage_ptr sp)
+ 32 + + {
+ 33 + + return make_value(
+ 34 + + *reinterpret_cast<
+ 35 + + init_list const*>(p),
+ 36 + + std::move(sp));
+ 37 + + }
+ 38 + +
+ 39 + + bool
+ 40 + +844 value_ref::
+ 41 + + is_key_value_pair() const noexcept
+ 42 + + {
+ 43 + +844 if(what_ != what::ini)
+ 44 + +339 return false;
+ 45 + +505 if(arg_.init_list_.size() != 2)
+ 46 + +5 return false;
+ 47 + + auto const& e =
+ 48 + +500 *arg_.init_list_.begin();
+ 49 + +500 if( e.what_ != what::str &&
+ 50 + +25 e.what_ != what::strfunc)
+ 51 + +23 return false;
+ 52 + +477 return true;
+ 53 + + }
+ 54 + +
+ 55 + + bool
+ 56 + +498 value_ref::
+ 57 + + maybe_object(
+ 58 + + std::initializer_list<
+ 59 + + value_ref> init) noexcept
+ 60 + + {
+ 61 + +975 for(auto const& e : init)
+ 62 + +844 if(! e.is_key_value_pair())
+ 63 + +367 return false;
+ 64 + +131 return true;
+ 65 + + }
+ 66 + +
+ 67 + + string_view
+ 68 + +472 value_ref::
+ 69 + + get_string() const noexcept
+ 70 + + {
+ 71 + +472 BOOST_ASSERT(
+ 72 + + what_ == what::str ||
+ 73 + + what_ == what::strfunc);
+ 74 + +472 if (what_ == what::strfunc)
+ 75 + +2 return *static_cast<const string*>(f_.p);
+ 76 + +470 return arg_.str_;
+ 77 + + }
+ 78 + +
+ 79 + + value
+ 80 + +9052 value_ref::
+ 81 + + make_value(
+ 82 + + storage_ptr sp) const
+ 83 + + {
+ 84 + +9052 switch(what_)
+ 85 + + {
+ 86 + +401 default:
+ 87 + + case what::str:
+ 88 + +802 return string(
+ 89 + + arg_.str_,
+ 90 + +786 std::move(sp));
+ 91 + +
+ 92 + +170 case what::ini:
+ 93 + + return make_value(
+ 94 + + arg_.init_list_,
+ 95 + +173 std::move(sp));
+ 96 + +
+ 97 + +58 case what::func:
+ 98 + +116 return f_.f(f_.p,
+ 99 + +58 std::move(sp));
+ 100 + +
+ 101 + +5 case what::strfunc:
+ 102 + +10 return f_.f(f_.p,
+ 103 + +5 std::move(sp));
+ 104 + +
+ 105 + +8418 case what::cfunc:
+ 106 + +16836 return cf_.f(cf_.p,
+ 107 + +8418 std::move(sp));
+ 108 + + }
+ 109 + + }
+ 110 + +
+ 111 + + value
+ 112 + +172 value_ref::
+ 113 + + make_value(
+ 114 + + std::initializer_list<
+ 115 + + value_ref> init,
+ 116 + + storage_ptr sp)
+ 117 + + {
+ 118 + +172 if(maybe_object(init))
+ 119 + +60 return make_object(
+ 120 + +60 init, std::move(sp));
+ 121 + +284 return make_array(
+ 122 + +281 init, std::move(sp));
+ 123 + + }
+ 124 + +
+ 125 + + object
+ 126 + +131 value_ref::
+ 127 + + make_object(
+ 128 + + std::initializer_list<value_ref> init,
+ 129 + + storage_ptr sp)
+ 130 + + {
+ 131 + +131 object obj(std::move(sp));
+ 132 + +131 obj.reserve(init.size());
+ 133 + +603 for(auto const& e : init)
+ 134 + +472 obj.emplace(
+ 135 + + e.arg_.init_list_.begin()[0].get_string(),
+ 136 + +944 e.arg_.init_list_.begin()[1].make_value(
+ 137 + + obj.storage()));
+ 138 + +131 return obj;
+ 139 + + }
+ 140 + +
+ 141 + + array
+ 142 + +355 value_ref::
+ 143 + + make_array(
+ 144 + + std::initializer_list<
+ 145 + + value_ref> init,
+ 146 + + storage_ptr sp)
+ 147 + + {
+ 148 + +355 array arr(std::move(sp));
+ 149 + +355 arr.reserve(init.size());
+ 150 + +1338 for(auto const& e : init)
+ 151 + +986 arr.emplace_back(
+ 152 + +1972 e.make_value(
+ 153 + + arr.storage()));
+ 154 + +352 return arr;
+ 155 + +3 }
+ 156 + +
+ 157 + + void
+ 158 + +214 value_ref::
+ 159 + + write_array(
+ 160 + + value* dest,
+ 161 + + std::initializer_list<
+ 162 + + value_ref> init,
+ 163 + + storage_ptr const& sp)
+ 164 + + {
+ 165 + + struct undo
+ 166 + + {
+ 167 + + value* const base;
+ 168 + + value* pos;
+ 169 + +214 ~undo()
+ 170 + + {
+ 171 + +214 if(pos)
+ 172 + +36 while(pos > base)
+ 173 + +20 (--pos)->~value();
+ 174 + +214 }
+ 175 + + };
+ 176 + +214 undo u{dest, dest};
+ 177 + +730 for(auto const& e : init)
+ 178 + + {
+ 179 + +16 ::new(u.pos) value(
+ 180 + +564 e.make_value(sp));
+ 181 + +516 ++u.pos;
+ 182 + + }
+ 183 + +198 u.pos = nullptr;
+ 184 + +214 }
+ 185 + +
+ 186 + + } // namespace json
+ 187 + + } // namespace boost
+ 188 + +
+ 189 + + #endif
+ 190 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value_stack.ipp.898987b601e2219cdbbc0139ef61766f.html b/json/gcovr/index.value_stack.ipp.898987b601e2219cdbbc0139ef61766f.html new file mode 100644 index 00000000..ac6163e4 --- /dev/null +++ b/json/gcovr/index.value_stack.ipp.898987b601e2219cdbbc0139ef61766f.html @@ -0,0 +1,5918 @@ + + + + + + impl/value_stack.ipp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/value_stack.ipp

+
+ + 99.5% Lines (198/199) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/value_stack.ipp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_VALUE_STACK_IPP
+ 11 + + #define BOOST_JSON_IMPL_VALUE_STACK_IPP
+ 12 + +
+ 13 + + #include <boost/json/value_stack.hpp>
+ 14 + + #include <cstring>
+ 15 + + #include <stdexcept>
+ 16 + + #include <utility>
+ 17 + +
+ 18 + + namespace boost {
+ 19 + + namespace json {
+ 20 + +
+ 21 + + //--------------------------------------
+ 22 + +
+ 23 + +2076892 value_stack::
+ 24 + + stack::
+ 25 + + ~stack()
+ 26 + + {
+ 27 + +2076892 clear();
+ 28 + +2076892 if( begin_ != temp_ &&
+ 29 + +75338 begin_ != nullptr)
+ 30 + +75330 sp_->deallocate(
+ 31 + +75330 begin_,
+ 32 + +75330 (end_ - begin_) *
+ 33 + + sizeof(value));
+ 34 + +2076892 }
+ 35 + +
+ 36 + +2076892 value_stack::
+ 37 + + stack::
+ 38 + + stack(
+ 39 + + storage_ptr sp,
+ 40 + + void* temp,
+ 41 + +2076892 std::size_t size) noexcept
+ 42 + +2076892 : sp_(std::move(sp))
+ 43 + +2076892 , temp_(temp)
+ 44 + + {
+ 45 + +2076892 if(size >= min_size_ *
+ 46 + + sizeof(value))
+ 47 + + {
+ 48 + +2001516 begin_ = reinterpret_cast<
+ 49 + + value*>(temp);
+ 50 + +2001516 top_ = begin_;
+ 51 + +2001516 end_ = begin_ +
+ 52 + +2001516 size / sizeof(value);
+ 53 + + }
+ 54 + + else
+ 55 + + {
+ 56 + +75376 begin_ = nullptr;
+ 57 + +75376 top_ = nullptr;
+ 58 + +75376 end_ = nullptr;
+ 59 + + }
+ 60 + +2076892 }
+ 61 + +
+ 62 + + void
+ 63 + +4153128 value_stack::
+ 64 + + stack::
+ 65 + + run_dtors(bool b) noexcept
+ 66 + + {
+ 67 + +4153128 run_dtors_ = b;
+ 68 + +4153128 }
+ 69 + +
+ 70 + + std::size_t
+ 71 + +4213790 value_stack::
+ 72 + + stack::
+ 73 + + size() const noexcept
+ 74 + + {
+ 75 + +4213790 return top_ - begin_;
+ 76 + + }
+ 77 + +
+ 78 + + bool
+ 79 + +64464 value_stack::
+ 80 + + stack::
+ 81 + + has_chars()
+ 82 + + {
+ 83 + +64464 return chars_ != 0;
+ 84 + + }
+ 85 + +
+ 86 + + //--------------------------------------
+ 87 + +
+ 88 + + // destroy the values but
+ 89 + + // not the stack allocation.
+ 90 + + void
+ 91 + +6230020 value_stack::
+ 92 + + stack::
+ 93 + + clear() noexcept
+ 94 + + {
+ 95 + +6230020 if(top_ != begin_)
+ 96 + + {
+ 97 + +84 if(run_dtors_)
+ 98 + +84 for(auto it = top_;
+ 99 + +335 it-- != begin_;)
+ 100 + +251 it->~value();
+ 101 + +84 top_ = begin_;
+ 102 + + }
+ 103 + +6230020 chars_ = 0;
+ 104 + +6230020 }
+ 105 + +
+ 106 + + void
+ 107 + +1868 value_stack::
+ 108 + + stack::
+ 109 + + maybe_grow()
+ 110 + + {
+ 111 + +1868 if(top_ >= end_)
+ 112 + +266 grow_one();
+ 113 + +1868 }
+ 114 + +
+ 115 + + // make room for at least one more value
+ 116 + + void
+ 117 + +66499 value_stack::
+ 118 + + stack::
+ 119 + + grow_one()
+ 120 + + {
+ 121 + +66499 BOOST_ASSERT(chars_ == 0);
+ 122 + +66499 std::size_t const capacity =
+ 123 + +66499 end_ - begin_;
+ 124 + +66499 std::size_t new_cap = min_size_;
+ 125 + + // VFALCO check overflow here
+ 126 + +66541 while(new_cap < capacity + 1)
+ 127 + +42 new_cap <<= 1;
+ 128 + + auto const begin =
+ 129 + + reinterpret_cast<value*>(
+ 130 + +66499 sp_->allocate(
+ 131 + + new_cap * sizeof(value)));
+ 132 + +66499 std::size_t const cur_size = top_ - begin_;
+ 133 + +66499 if(begin_)
+ 134 + + {
+ 135 + +11 std::memcpy(
+ 136 + + reinterpret_cast<char*>(begin),
+ 137 + +11 reinterpret_cast<char*>(begin_),
+ 138 + +11 size() * sizeof(value));
+ 139 + +11 if(begin_ != temp_)
+ 140 + +9 sp_->deallocate(begin_,
+ 141 + + capacity * sizeof(value));
+ 142 + + }
+ 143 + + // book-keeping
+ 144 + +66499 top_ = begin + cur_size;
+ 145 + +66499 end_ = begin + new_cap;
+ 146 + +66499 begin_ = begin;
+ 147 + +66499 }
+ 148 + +
+ 149 + + // make room for nchars additional characters.
+ 150 + + void
+ 151 + +16168 value_stack::
+ 152 + + stack::
+ 153 + + grow(std::size_t nchars)
+ 154 + + {
+ 155 + + // needed capacity in values
+ 156 + + std::size_t const needed =
+ 157 + +16168 size() +
+ 158 + +16168 1 +
+ 159 + +16168 ((chars_ + nchars +
+ 160 + +16168 sizeof(value) - 1) /
+ 161 + +16168 sizeof(value));
+ 162 + +16168 std::size_t const capacity =
+ 163 + +16168 end_ - begin_;
+ 164 + +16168 BOOST_ASSERT(
+ 165 + + needed > capacity);
+ 166 + +16168 std::size_t new_cap = min_size_;
+ 167 + + // VFALCO check overflow here
+ 168 + +57815 while(new_cap < needed)
+ 169 + +41647 new_cap <<= 1;
+ 170 + + auto const begin =
+ 171 + + reinterpret_cast<value*>(
+ 172 + +16168 sp_->allocate(
+ 173 + + new_cap * sizeof(value)));
+ 174 + +16168 std::size_t const cur_size = top_ - begin_;
+ 175 + +16168 if(begin_)
+ 176 + + {
+ 177 + + std::size_t amount =
+ 178 + +7328 size() * sizeof(value);
+ 179 + +7328 if(chars_ > 0)
+ 180 + + amount += sizeof(value) + chars_;
+ 181 + +7328 std::memcpy(
+ 182 + + reinterpret_cast<char*>(begin),
+ 183 + +7328 reinterpret_cast<char*>(begin_),
+ 184 + + amount);
+ 185 + +7328 if(begin_ != temp_)
+ 186 + +7328 sp_->deallocate(begin_,
+ 187 + + capacity * sizeof(value));
+ 188 + + }
+ 189 + + // book-keeping
+ 190 + +16168 top_ = begin + cur_size;
+ 191 + +16168 end_ = begin + new_cap;
+ 192 + +16168 begin_ = begin;
+ 193 + +16168 }
+ 194 + +
+ 195 + + //--------------------------------------
+ 196 + +
+ 197 + + void
+ 198 + +17145 value_stack::
+ 199 + + stack::
+ 200 + + append(string_view s)
+ 201 + + {
+ 202 + +17145 std::size_t const bytes_avail =
+ 203 + + reinterpret_cast<
+ 204 + +17145 char const*>(end_) -
+ 205 + + reinterpret_cast<
+ 206 + +17145 char const*>(top_);
+ 207 + + // make sure there is room for
+ 208 + + // pushing one more value without
+ 209 + + // clobbering the string.
+ 210 + +34290 if(sizeof(value) + chars_ +
+ 211 + +17145 s.size() > bytes_avail)
+ 212 + +16168 grow(s.size());
+ 213 + +
+ 214 + + // copy the new piece
+ 215 + +17145 std::memcpy(
+ 216 + + reinterpret_cast<char*>(
+ 217 + +17145 top_ + 1) + chars_,
+ 218 + +17145 s.data(), s.size());
+ 219 + +17145 chars_ += s.size();
+ 220 + +
+ 221 + + // ensure a pushed value cannot
+ 222 + + // clobber the released string.
+ 223 + +17145 BOOST_ASSERT(
+ 224 + + reinterpret_cast<char*>(
+ 225 + + top_ + 1) + chars_ <=
+ 226 + + reinterpret_cast<char*>(
+ 227 + + end_));
+ 228 + +17145 }
+ 229 + +
+ 230 + + string_view
+ 231 + +17020 value_stack::
+ 232 + + stack::
+ 233 + + release_string() noexcept
+ 234 + + {
+ 235 + + // ensure a pushed value cannot
+ 236 + + // clobber the released string.
+ 237 + +17020 BOOST_ASSERT(
+ 238 + + reinterpret_cast<char*>(
+ 239 + + top_ + 1) + chars_ <=
+ 240 + + reinterpret_cast<char*>(
+ 241 + + end_));
+ 242 + +17020 auto const n = chars_;
+ 243 + +17020 chars_ = 0;
+ 244 + + return { reinterpret_cast<
+ 245 + +17020 char const*>(top_ + 1), n };
+ 246 + + }
+ 247 + +
+ 248 + + // transfer ownership of the top n
+ 249 + + // elements of the stack to the caller
+ 250 + + value*
+ 251 + +2113641 value_stack::
+ 252 + + stack::
+ 253 + + release(std::size_t n) noexcept
+ 254 + + {
+ 255 + +2113641 BOOST_ASSERT(n <= size());
+ 256 + +2113641 BOOST_ASSERT(chars_ == 0);
+ 257 + +2113641 top_ -= n;
+ 258 + +2113641 return top_;
+ 259 + + }
+ 260 + +
+ 261 + + template<class... Args>
+ 262 + + value&
+ 263 + +2119934 value_stack::
+ 264 + + stack::
+ 265 + + push(Args&&... args)
+ 266 + + {
+ 267 + +2119934 BOOST_ASSERT(chars_ == 0);
+ 268 + +2119934 if(top_ >= end_)
+ 269 + +66233 grow_one();
+ 270 + + value& jv = detail::access::
+ 271 + +2119934 construct_value(top_,
+ 272 + + std::forward<Args>(args)...);
+ 273 + +2119870 ++top_;
+ 274 + +2119870 return jv;
+ 275 + + }
+ 276 + +
+ 277 + + template<class Unchecked>
+ 278 + + void
+ 279 + +36999 value_stack::
+ 280 + + stack::
+ 281 + + exchange(Unchecked&& u)
+ 282 + + {
+ 283 + +36999 BOOST_ASSERT(chars_ == 0);
+ 284 + + union U
+ 285 + + {
+ 286 + + value v;
+ 287 + +36999 U() {}
+ 288 + +36999 ~U() {}
+ 289 + +36999 } jv;
+ 290 + + // construct value on the stack
+ 291 + + // to avoid clobbering top_[0],
+ 292 + + // which belongs to `u`.
+ 293 + + detail::access::
+ 294 + +36999 construct_value(
+ 295 + +36999 &jv.v, std::move(u));
+ 296 + +36922 std::memcpy(
+ 297 + + reinterpret_cast<
+ 298 + +36922 char*>(top_),
+ 299 + + &jv.v, sizeof(value));
+ 300 + +36922 ++top_;
+ 301 + +36999 }
+ 302 + +
+ 303 + + //----------------------------------------------------------
+ 304 + +
+ 305 + +2076892 value_stack::
+ 306 + + ~value_stack()
+ 307 + + {
+ 308 + + // default dtor is here so the
+ 309 + + // definition goes in the library
+ 310 + + // instead of the caller's TU.
+ 311 + +2076892 }
+ 312 + +
+ 313 + +2076892 value_stack::
+ 314 + + value_stack(
+ 315 + + storage_ptr sp,
+ 316 + + unsigned char* temp_buffer,
+ 317 + +2076892 std::size_t temp_size) noexcept
+ 318 + +2076892 : st_(
+ 319 + +2076892 std::move(sp),
+ 320 + + temp_buffer,
+ 321 + +2076892 temp_size)
+ 322 + + {
+ 323 + +2076892 }
+ 324 + +
+ 325 + + void
+ 326 + +4153128 value_stack::
+ 327 + + reset(storage_ptr sp) noexcept
+ 328 + + {
+ 329 + +4153128 st_.clear();
+ 330 + +
+ 331 + +4153128 sp_.~storage_ptr();
+ 332 + +12459376 ::new(&sp_) storage_ptr(
+ 333 + +4153128 pilfer(sp));
+ 334 + +
+ 335 + + // `stack` needs this
+ 336 + + // to clean up correctly
+ 337 + +8306256 st_.run_dtors(
+ 338 + +4153128 ! sp_.is_not_shared_and_deallocate_is_trivial());
+ 339 + +4153128 }
+ 340 + +
+ 341 + + value
+ 342 + +2076642 value_stack::
+ 343 + + release() noexcept
+ 344 + + {
+ 345 + + // This means the caller did not
+ 346 + + // cause a single top level element
+ 347 + + // to be produced.
+ 348 + +2076642 BOOST_ASSERT(st_.size() == 1);
+ 349 + +
+ 350 + + // give up shared ownership
+ 351 + +2076642 sp_ = {};
+ 352 + +
+ 353 + +2076642 return pilfer(*st_.release(1));
+ 354 + + }
+ 355 + +
+ 356 + + //----------------------------------------------------------
+ 357 + +
+ 358 + + void
+ 359 + +2120 value_stack::
+ 360 + + push_array(std::size_t n)
+ 361 + + {
+ 362 + + // we already have room if n > 0
+ 363 + +2120 if(BOOST_JSON_UNLIKELY(n == 0))
+ 364 + +819 st_.maybe_grow();
+ 365 + + detail::unchecked_array ua(
+ 366 + +2120 st_.release(n), n, sp_);
+ 367 + +2120 st_.exchange(std::move(ua));
+ 368 + +2120 }
+ 369 + +
+ 370 + + void
+ 371 + +34879 value_stack::
+ 372 + + push_object(std::size_t n)
+ 373 + + {
+ 374 + + // we already have room if n > 0
+ 375 + +34879 if(BOOST_JSON_UNLIKELY(n == 0))
+ 376 + +1049 st_.maybe_grow();
+ 377 + + detail::unchecked_object uo(
+ 378 + +34879 st_.release(n * 2), n, sp_);
+ 379 + +34879 st_.exchange(std::move(uo));
+ 380 + +34879 }
+ 381 + +
+ 382 + + void
+ 383 + +17145 value_stack::
+ 384 + + push_chars(
+ 385 + + string_view s)
+ 386 + + {
+ 387 + +17145 st_.append(s);
+ 388 + +17145 }
+ 389 + +
+ 390 + + void
+ 391 + +38356 value_stack::
+ 392 + + push_key(
+ 393 + + string_view s)
+ 394 + + {
+ 395 + +38356 if(! st_.has_chars())
+ 396 + + {
+ 397 + +30296 st_.push(detail::key_t{}, s, sp_);
+ 398 + +30236 return;
+ 399 + + }
+ 400 + +8060 auto part = st_.release_string();
+ 401 + +8060 st_.push(detail::key_t{}, part, s, sp_);
+ 402 + + }
+ 403 + +
+ 404 + + void
+ 405 + +26108 value_stack::
+ 406 + + push_string(
+ 407 + + string_view s)
+ 408 + + {
+ 409 + +26108 if(! st_.has_chars())
+ 410 + + {
+ 411 + + // fast path
+ 412 + +17148 st_.push(s, sp_);
+ 413 + +17144 return;
+ 414 + + }
+ 415 + +
+ 416 + + // VFALCO We could add a special
+ 417 + + // private ctor to string that just
+ 418 + + // creates uninitialized space,
+ 419 + + // to reduce member function calls.
+ 420 + +8960 auto part = st_.release_string();
+ 421 + +17920 auto& str = st_.push(
+ 422 + +8960 string_kind, sp_).get_string();
+ 423 + +8960 str.reserve(
+ 424 + +8960 part.size() + s.size());
+ 425 + +8960 std::memcpy(
+ 426 + +8960 str.data(),
+ 427 + +8960 part.data(), part.size());
+ 428 + +8960 std::memcpy(
+ 429 + +8960 str.data() + part.size(),
+ 430 + +8960 s.data(), s.size());
+ 431 + +8960 str.grow(part.size() + s.size());
+ 432 + + }
+ 433 + +
+ 434 + + void
+ 435 + +5815 value_stack::
+ 436 + + push_int64(
+ 437 + + int64_t i)
+ 438 + + {
+ 439 + +5815 st_.push(i, sp_);
+ 440 + +5815 }
+ 441 + +
+ 442 + + void
+ 443 + +70 value_stack::
+ 444 + + push_uint64(
+ 445 + + uint64_t u)
+ 446 + + {
+ 447 + +70 st_.push(u, sp_);
+ 448 + +70 }
+ 449 + +
+ 450 + + void
+ 451 + +2039817 value_stack::
+ 452 + + push_double(
+ 453 + + double d)
+ 454 + + {
+ 455 + +2039817 st_.push(d, sp_);
+ 456 + +2039817 }
+ 457 + +
+ 458 + + void
+ 459 + +400 value_stack::
+ 460 + + push_bool(
+ 461 + + bool b)
+ 462 + + {
+ 463 + +400 st_.push(b, sp_);
+ 464 + +400 }
+ 465 + +
+ 466 + + void
+ 467 + +9368 value_stack::
+ 468 + + push_null()
+ 469 + + {
+ 470 + +9368 st_.push(nullptr, sp_);
+ 471 + +9368 }
+ 472 + +
+ 473 + + } // namespace json
+ 474 + + } // namespace boost
+ 475 + +
+ 476 + + #endif
+ 477 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value_to.hpp.1b7ce679b2c4b444ce7bf9f62953b6be.html b/json/gcovr/index.value_to.hpp.1b7ce679b2c4b444ce7bf9f62953b6be.html new file mode 100644 index 00000000..6c01f09e --- /dev/null +++ b/json/gcovr/index.value_to.hpp.1b7ce679b2c4b444ce7bf9f62953b6be.html @@ -0,0 +1,4006 @@ + + + + + + value_to.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

value_to.hpp

+
+ + 100.0% Lines (9/9) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
value_to.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com)
+ 5 + + //
+ 6 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 7 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 8 + + //
+ 9 + + // Official repository: https://github.com/boostorg/json
+ 10 + + //
+ 11 + +
+ 12 + + #ifndef BOOST_JSON_VALUE_TO_HPP
+ 13 + + #define BOOST_JSON_VALUE_TO_HPP
+ 14 + +
+ 15 + + #include <boost/core/detail/static_assert.hpp>
+ 16 + + #include <boost/json/detail/value_to.hpp>
+ 17 + +
+ 18 + + namespace boost {
+ 19 + + namespace json {
+ 20 + +
+ 21 + + /** Convert a @ref value to an object of type `T`.
+ 22 + +
+ 23 + + This function attempts to convert a @ref value
+ 24 + + to `T` using
+ 25 + +
+ 26 + + @li one of @ref value's accessors, or
+ 27 + + @li a library-provided generic conversion, or
+ 28 + + @li a user-provided overload of `tag_invoke`.
+ 29 + +
+ 30 + + Out of the box the function supports default constructible types satisfying
+ 31 + + {req_SequenceContainer}, arrays, arithmetic types, `bool`, `std::tuple`,
+ 32 + + `std::pair`, `std::optional`, `std::variant`, `std::nullptr_t`, and structs
+ 33 + + and enums described using Boost.Describe.
+ 34 + +
+ 35 + + Conversion of other types is done by calling an overload of `tag_invoke`
+ 36 + + found by argument-dependent lookup. Its signature should be similar to:
+ 37 + +
+ 38 + + @code
+ 39 + + template< class FullContext >
+ 40 + + T tag_invoke( value_to_tag<T>, const value&, const Context& , const FullContext& );
+ 41 + + @endcode
+ 42 + +
+ 43 + + or
+ 44 + +
+ 45 + + @code
+ 46 + + T tag_invoke( value_to_tag<T>, const value&, const Context& );
+ 47 + + @endcode
+ 48 + +
+ 49 + + or
+ 50 + +
+ 51 + + @code
+ 52 + + result<T> tag_invoke( value_to_tag<T>, const value& );
+ 53 + + @endcode
+ 54 + +
+ 55 + + The overloads are checked for existence in that order and the first that
+ 56 + + matches will be selected.
+ 57 + +
+ 58 + + The object returned by the function call is returned by @ref value_to as
+ 59 + + the result of the conversion.
+ 60 + +
+ 61 + + The `ctx` argument can be used either as a tag type to provide conversions
+ 62 + + for third-party types, or to pass extra data to the conversion function.
+ 63 + +
+ 64 + + Overload **(3)** is **deleted** and participates in overload resolution
+ 65 + + only when `U` is not @ref value. The overload exists to prevent unintented
+ 66 + + creation of temporary @ref value instances, e.g.
+ 67 + +
+ 68 + + @code
+ 69 + + auto flag = value_to<bool>(true);
+ 70 + + @endcode
+ 71 + +
+ 72 + + @par Constraints
+ 73 + + @code
+ 74 + + ! std::is_reference< T >::value
+ 75 + + @endcode
+ 76 + +
+ 77 + + @par Exception Safety
+ 78 + + Strong guarantee.
+ 79 + +
+ 80 + + @tparam T The type to convert to.
+ 81 + +
+ 82 + + @tparam Context The type of context passed to the conversion function.
+ 83 + +
+ 84 + + @returns `jv` converted to `result<T>`.
+ 85 + +
+ 86 + + @param jv The @ref value to convert.
+ 87 + +
+ 88 + + @param ctx Context passed to the conversion function.
+ 89 + +
+ 90 + + @see @ref value_to_tag, @ref value_from,
+ 91 + + <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
+ 92 + + tag_invoke: A general pattern for supporting customisable functions</a>
+ 93 + +
+ 94 + + @{
+ 95 + + */
+ 96 + + template< class T, class Context >
+ 97 + + T
+ 98 + +404 value_to( value const& jv, Context const& ctx )
+ 99 + + {
+ 100 + + BOOST_CORE_STATIC_ASSERT( ! std::is_reference<T>::value );
+ 101 + + using bare_T = detail::remove_cvref<T>;
+ 102 + + BOOST_CORE_STATIC_ASSERT((
+ 103 + + detail::conversion_round_trips<
+ 104 + + Context, bare_T, detail::value_to_conversion>::value));
+ 105 + + using cat = detail::value_to_category<Context, bare_T>;
+ 106 + +404 return detail::value_to_impl( cat(), value_to_tag<bare_T>(), jv, ctx );
+ 107 + + }
+ 108 + +
+ 109 + + /// Overload
+ 110 + + template<class T>
+ 111 + + T
+ 112 + +125 value_to(const value& jv)
+ 113 + + {
+ 114 + +186 return value_to<T>( jv, detail::no_context() );
+ 115 + + }
+ 116 + +
+ 117 + + /// Overload
+ 118 + + template<class T, class U
+ 119 + + #ifndef BOOST_JSON_DOCS
+ 120 + + , class = typename std::enable_if<!std::is_same<U, value>::value>::type
+ 121 + + #endif
+ 122 + + >
+ 123 + + T
+ 124 + + value_to(U const& jv) = delete;
+ 125 + + /// @}
+ 126 + +
+ 127 + + /** Convert a @ref value to a @ref boost::system::result.
+ 128 + +
+ 129 + + This function attempts to convert a @ref value to `result<T>` using
+ 130 + +
+ 131 + + @li one of @ref value's accessors, or
+ 132 + + @li a library-provided generic conversion, or
+ 133 + + @li a user-provided overload of `tag_invoke`.
+ 134 + +
+ 135 + + Out of the box the function supports default constructible types satisfying
+ 136 + + {req_SequenceContainer}, arrays, arithmetic types, `bool`, `std::tuple`,
+ 137 + + `std::pair`, `std::optional`, `std::variant`, `std::nullptr_t`, and structs
+ 138 + + and enums described using Boost.Describe.
+ 139 + +
+ 140 + + Conversion of other types is done by calling an overload of `tag_invoke`
+ 141 + + found by argument-dependent lookup. Its signature should be similar to:
+ 142 + +
+ 143 + + @code
+ 144 + + template< class FullContext >
+ 145 + + result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context& , const FullContext& );
+ 146 + + @endcode
+ 147 + +
+ 148 + + or
+ 149 + +
+ 150 + + @code
+ 151 + + result<T> tag_invoke( try_value_to_tag<T>, const value&, const Context& );
+ 152 + + @endcode
+ 153 + +
+ 154 + + or
+ 155 + +
+ 156 + + @code
+ 157 + + result<T> tag_invoke( try_value_to_tag<T>, const value& );
+ 158 + + @endcode
+ 159 + +
+ 160 + + The overloads are checked for existence in that order and the first that
+ 161 + + matches will be selected.
+ 162 + +
+ 163 + + If an error occurs during conversion, the result will store the error code
+ 164 + + associated with the error. If an exception is thrown, the function will
+ 165 + + attempt to retrieve the associated error code and return it, otherwise it
+ 166 + + will return `error::exception`, unless the exception type is
+ 167 + + @ref std::bad_alloc, which will be allowed to propagate.
+ 168 + +
+ 169 + + The `ctx` argument can be used either as a tag type to provide conversions
+ 170 + + for third-party types, or to pass extra data to the conversion function.
+ 171 + +
+ 172 + + @par Constraints
+ 173 + + @code
+ 174 + + ! std::is_reference< T >::value
+ 175 + + @endcode
+ 176 + +
+ 177 + + @par Exception Safety
+ 178 + + Strong guarantee.
+ 179 + +
+ 180 + + @tparam T The type to convert to.
+ 181 + + @tparam Context The type of context passed to the conversion function.
+ 182 + +
+ 183 + + @param jv The @ref value to convert.
+ 184 + + @param ctx Context passed to the conversion function.
+ 185 + +
+ 186 + + @returns `jv` converted to `result<T>`.
+ 187 + +
+ 188 + + @see @ref value_to_tag, @ref value_to, @ref value_from,
+ 189 + + [tag_invoke: A general pattern for supporting customisable functions](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf).
+ 190 + +
+ 191 + + @{
+ 192 + + */
+ 193 + + template< class T, class Context >
+ 194 + + typename result_for<T, value>::type
+ 195 + +3745 try_value_to( value const& jv, Context const& ctx )
+ 196 + + {
+ 197 + + BOOST_CORE_STATIC_ASSERT( ! std::is_reference<T>::value );
+ 198 + + using bare_T = detail::remove_cvref<T>;
+ 199 + + BOOST_CORE_STATIC_ASSERT((
+ 200 + + detail::conversion_round_trips<
+ 201 + + Context, bare_T, detail::value_to_conversion>::value));
+ 202 + + using cat = detail::value_to_category<Context, bare_T>;
+ 203 + +3555 return detail::value_to_impl(
+ 204 + +3739 cat(), try_value_to_tag<bare_T>(), jv, ctx );
+ 205 + + }
+ 206 + +
+ 207 + + /// Overload
+ 208 + + template<class T>
+ 209 + + typename result_for<T, value>::type
+ 210 + +130 try_value_to(const value& jv)
+ 211 + + {
+ 212 + +163 return try_value_to<T>( jv, detail::no_context() );
+ 213 + + }
+ 214 + + /// @}
+ 215 + +
+ 216 + + /** Determine if a @ref value can be converted to `T`.
+ 217 + +
+ 218 + + If @ref value can be converted to `T` via a
+ 219 + + call to @ref value_to, the static data member `value`
+ 220 + + is defined as `true`. Otherwise, `value` is
+ 221 + + defined as `false`.
+ 222 + +
+ 223 + + @see @ref value_to
+ 224 + + */
+ 225 + + #ifdef BOOST_JSON_DOCS
+ 226 + + template<class T>
+ 227 + + using has_value_to = __see_below__;
+ 228 + + #else
+ 229 + + template<class T>
+ 230 + + using has_value_to = detail::can_convert<
+ 231 + + detail::remove_cvref<T>, detail::value_to_conversion>;
+ 232 + + #endif
+ 233 + +
+ 234 + + } // namespace json
+ 235 + + } // namespace boost
+ 236 + +
+ 237 + + #endif
+ 238 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.value_to.hpp.635e555e887031c6fc380bccf2c402de.html b/json/gcovr/index.value_to.hpp.635e555e887031c6fc380bccf2c402de.html new file mode 100644 index 00000000..3695ab16 --- /dev/null +++ b/json/gcovr/index.value_to.hpp.635e555e887031c6fc380bccf2c402de.html @@ -0,0 +1,8902 @@ + + + + + + detail/value_to.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

detail/value_to.hpp

+
+ + 100.0% Lines (157/157) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
detail/value_to.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+ 4 + + // Copyright (c) 2021 Dmitry Arkhipov (grisumbras@gmail.com)
+ 5 + + //
+ 6 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 7 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 8 + + //
+ 9 + + // Official repository: https://github.com/boostorg/json
+ 10 + + //
+ 11 + +
+ 12 + + #ifndef BOOST_JSON_DETAIL_VALUE_TO_HPP
+ 13 + + #define BOOST_JSON_DETAIL_VALUE_TO_HPP
+ 14 + +
+ 15 + + #include <boost/core/detail/static_assert.hpp>
+ 16 + + #include <boost/json/value.hpp>
+ 17 + + #include <boost/json/conversion.hpp>
+ 18 + + #include <boost/json/result_for.hpp>
+ 19 + + #include <boost/describe/enum_from_string.hpp>
+ 20 + +
+ 21 + + #ifndef BOOST_NO_CXX17_HDR_OPTIONAL
+ 22 + + # include <optional>
+ 23 + + #endif
+ 24 + +
+ 25 + + namespace boost {
+ 26 + + namespace json {
+ 27 + +
+ 28 + + namespace detail {
+ 29 + +
+ 30 + + template<class T>
+ 31 + + using has_reserve_member_helper = decltype(std::declval<T&>().reserve(0));
+ 32 + + template<class T>
+ 33 + + using has_reserve_member = mp11::mp_valid<has_reserve_member_helper, T>;
+ 34 + + template<class T>
+ 35 + + using reserve_implementation = mp11::mp_cond<
+ 36 + + is_tuple_like<T>, mp11::mp_int<2>,
+ 37 + + has_reserve_member<T>, mp11::mp_int<1>,
+ 38 + + mp11::mp_true, mp11::mp_int<0>>;
+ 39 + +
+ 40 + + template<class T>
+ 41 + + error
+ 42 + +41 try_reserve(
+ 43 + + T&,
+ 44 + + std::size_t size,
+ 45 + + mp11::mp_int<2>)
+ 46 + + {
+ 47 + +41 constexpr std::size_t N = std::tuple_size<remove_cvref<T>>::value;
+ 48 + +41 if ( N != size )
+ 49 + +30 return error::size_mismatch;
+ 50 + +11 return error();
+ 51 + + }
+ 52 + +
+ 53 + + template<typename T>
+ 54 + + error
+ 55 + +74 try_reserve(
+ 56 + + T& cont,
+ 57 + + std::size_t size,
+ 58 + + mp11::mp_int<1>)
+ 59 + + {
+ 60 + +74 cont.reserve(size);
+ 61 + +74 return error();
+ 62 + + }
+ 63 + +
+ 64 + + template<typename T>
+ 65 + + error
+ 66 + +57 try_reserve(
+ 67 + + T&,
+ 68 + + std::size_t,
+ 69 + + mp11::mp_int<0>)
+ 70 + + {
+ 71 + +57 return error();
+ 72 + + }
+ 73 + +
+ 74 + +
+ 75 + + // identity conversion
+ 76 + + template< class Ctx >
+ 77 + + system::result<value>
+ 78 + + value_to_impl(
+ 79 + + value_conversion_tag,
+ 80 + + try_value_to_tag<value>,
+ 81 + + value const& jv,
+ 82 + + Ctx const& )
+ 83 + + {
+ 84 + + return jv;
+ 85 + + }
+ 86 + +
+ 87 + + template< class Ctx >
+ 88 + + value
+ 89 + + value_to_impl(
+ 90 + + value_conversion_tag, value_to_tag<value>, value const& jv, Ctx const& )
+ 91 + + {
+ 92 + + return jv;
+ 93 + + }
+ 94 + +
+ 95 + + // object
+ 96 + + template< class Ctx >
+ 97 + + system::result<object>
+ 98 + +12 value_to_impl(
+ 99 + + object_conversion_tag,
+ 100 + + try_value_to_tag<object>,
+ 101 + + value const& jv,
+ 102 + + Ctx const& )
+ 103 + + {
+ 104 + +12 object const* obj = jv.if_object();
+ 105 + +12 if( obj )
+ 106 + +6 return *obj;
+ 107 + +6 system::error_code ec;
+ 108 + +6 BOOST_JSON_FAIL(ec, error::not_object);
+ 109 + +6 return ec;
+ 110 + + }
+ 111 + +
+ 112 + + // array
+ 113 + + template< class Ctx >
+ 114 + + system::result<array>
+ 115 + +12 value_to_impl(
+ 116 + + array_conversion_tag,
+ 117 + + try_value_to_tag<array>,
+ 118 + + value const& jv,
+ 119 + + Ctx const& )
+ 120 + + {
+ 121 + +12 array const* arr = jv.if_array();
+ 122 + +12 if( arr )
+ 123 + +6 return *arr;
+ 124 + +6 system::error_code ec;
+ 125 + +6 BOOST_JSON_FAIL(ec, error::not_array);
+ 126 + +6 return ec;
+ 127 + + }
+ 128 + +
+ 129 + + // string
+ 130 + + template< class Ctx >
+ 131 + + system::result<string>
+ 132 + +12 value_to_impl(
+ 133 + + string_conversion_tag,
+ 134 + + try_value_to_tag<string>,
+ 135 + + value const& jv,
+ 136 + + Ctx const& )
+ 137 + + {
+ 138 + +12 string const* str = jv.if_string();
+ 139 + +12 if( str )
+ 140 + +6 return *str;
+ 141 + +6 system::error_code ec;
+ 142 + +6 BOOST_JSON_FAIL(ec, error::not_string);
+ 143 + +6 return ec;
+ 144 + + }
+ 145 + +
+ 146 + + // bool
+ 147 + + template< class Ctx >
+ 148 + + system::result<bool>
+ 149 + +49 value_to_impl(
+ 150 + + bool_conversion_tag, try_value_to_tag<bool>, value const& jv, Ctx const& )
+ 151 + + {
+ 152 + +49 auto b = jv.if_bool();
+ 153 + +49 if( b )
+ 154 + +42 return *b;
+ 155 + +7 system::error_code ec;
+ 156 + +7 BOOST_JSON_FAIL(ec, error::not_bool);
+ 157 + +7 return {boost::system::in_place_error, ec};
+ 158 + + }
+ 159 + +
+ 160 + + // integral and floating point
+ 161 + + template< class T, class Ctx >
+ 162 + + system::result<T>
+ 163 + +3396 value_to_impl(
+ 164 + + number_conversion_tag, try_value_to_tag<T>, value const& jv, Ctx const& )
+ 165 + + {
+ 166 + +3396 system::error_code ec;
+ 167 + +3396 auto const n = jv.to_number<T>(ec);
+ 168 + +3396 if( ec.failed() )
+ 169 + +55 return {boost::system::in_place_error, ec};
+ 170 + +3341 return {boost::system::in_place_value, n};
+ 171 + + }
+ 172 + +
+ 173 + + // null-like conversion
+ 174 + + template< class T, class Ctx >
+ 175 + + system::result<T>
+ 176 + +56 value_to_impl(
+ 177 + + null_like_conversion_tag,
+ 178 + + try_value_to_tag<T>,
+ 179 + + value const& jv,
+ 180 + + Ctx const& )
+ 181 + + {
+ 182 + +56 if( jv.is_null() )
+ 183 + +35 return {boost::system::in_place_value, T{}};
+ 184 + +21 system::error_code ec;
+ 185 + +21 BOOST_JSON_FAIL(ec, error::not_null);
+ 186 + +21 return {boost::system::in_place_error, ec};
+ 187 + + }
+ 188 + +
+ 189 + + // string-like types
+ 190 + + template< class T, class Ctx >
+ 191 + + system::result<T>
+ 192 + +79 value_to_impl(
+ 193 + + string_like_conversion_tag,
+ 194 + + try_value_to_tag<T>,
+ 195 + + value const& jv,
+ 196 + + Ctx const& )
+ 197 + + {
+ 198 + +79 auto str = jv.if_string();
+ 199 + +79 if( str )
+ 200 + +67 return {boost::system::in_place_value, T(str->subview())};
+ 201 + +12 system::error_code ec;
+ 202 + +12 BOOST_JSON_FAIL(ec, error::not_string);
+ 203 + +12 return {boost::system::in_place_error, ec};
+ 204 + + }
+ 205 + +
+ 206 + + // map-like containers
+ 207 + + template< class T, class Ctx >
+ 208 + + system::result<T>
+ 209 + +74 value_to_impl(
+ 210 + + map_like_conversion_tag,
+ 211 + + try_value_to_tag<T>,
+ 212 + + value const& jv,
+ 213 + + Ctx const& ctx )
+ 214 + + {
+ 215 + +74 object const* obj = jv.if_object();
+ 216 + +74 if( !obj )
+ 217 + + {
+ 218 + +12 system::error_code ec;
+ 219 + +12 BOOST_JSON_FAIL(ec, error::not_object);
+ 220 + +12 return {boost::system::in_place_error, ec};
+ 221 + + }
+ 222 + +
+ 223 + +62 T res;
+ 224 + +62 error const e = detail::try_reserve(
+ 225 + + res, obj->size(), reserve_implementation<T>());
+ 226 + +62 if( e != error() )
+ 227 + + {
+ 228 + +12 system::error_code ec;
+ 229 + +12 BOOST_JSON_FAIL( ec, e );
+ 230 + +12 return {boost::system::in_place_error, ec};
+ 231 + + }
+ 232 + +
+ 233 + +50 auto ins = detail::inserter(res, inserter_implementation<T>());
+ 234 + +147 for( key_value_pair const& kv: *obj )
+ 235 + + {
+ 236 + +104 auto elem_res = try_value_to<mapped_type<T>>( kv.value(), ctx );
+ 237 + +104 if( elem_res.has_error() )
+ 238 + +13 return {boost::system::in_place_error, elem_res.error()};
+ 239 + +91 *ins++ = value_type<T>{
+ 240 + +182 key_type<T>(kv.key()),
+ 241 + +91 std::move(*elem_res)};
+ 242 + + }
+ 243 + +37 return res;
+ 244 + +62 }
+ 245 + +
+ 246 + + // all other containers
+ 247 + + template< class T, class Ctx >
+ 248 + + system::result<T>
+ 249 + +119 value_to_impl(
+ 250 + + sequence_conversion_tag,
+ 251 + + try_value_to_tag<T>,
+ 252 + + value const& jv,
+ 253 + + Ctx const& ctx )
+ 254 + + {
+ 255 + +119 array const* arr = jv.if_array();
+ 256 + +119 if( !arr )
+ 257 + + {
+ 258 + +12 system::error_code ec;
+ 259 + +12 BOOST_JSON_FAIL(ec, error::not_array);
+ 260 + +12 return {boost::system::in_place_error, ec};
+ 261 + + }
+ 262 + +
+ 263 + +79 T result;
+ 264 + +107 error const e = detail::try_reserve(
+ 265 + + result, arr->size(), reserve_implementation<T>());
+ 266 + +107 if( e != error() )
+ 267 + + {
+ 268 + +18 system::error_code ec;
+ 269 + +18 BOOST_JSON_FAIL( ec, e );
+ 270 + +18 return {boost::system::in_place_error, ec};
+ 271 + + }
+ 272 + +
+ 273 + +89 auto ins = detail::inserter(result, inserter_implementation<T>());
+ 274 + +3344 for( value const& val: *arr )
+ 275 + + {
+ 276 + +3229 auto elem_res = try_value_to<value_type<T>>( val, ctx );
+ 277 + +3229 if( elem_res.has_error() )
+ 278 + +13 return {boost::system::in_place_error, elem_res.error()};
+ 279 + +3216 *ins++ = std::move(*elem_res);
+ 280 + + }
+ 281 + +76 return result;
+ 282 + +79 }
+ 283 + +
+ 284 + + // tuple-like types
+ 285 + + template< class T, class Ctx >
+ 286 + + system::result<T>
+ 287 + +230 try_make_tuple_elem(value const& jv, Ctx const& ctx, system::error_code& ec)
+ 288 + + {
+ 289 + +230 if( ec.failed() )
+ 290 + +38 return {boost::system::in_place_error, ec};
+ 291 + +
+ 292 + +192 auto result = try_value_to<T>( jv, ctx );
+ 293 + +192 ec = result.error();
+ 294 + +192 return result;
+ 295 + +57 }
+ 296 + +
+ 297 + + template <class T, class Ctx, std::size_t... Is>
+ 298 + + system::result<T>
+ 299 + +91 try_make_tuple_like(
+ 300 + + array const& arr, Ctx const& ctx, boost::mp11::index_sequence<Is...>)
+ 301 + + {
+ 302 + +91 system::error_code ec;
+ 303 + +109 auto items = std::make_tuple(
+ 304 + + try_make_tuple_elem<
+ 305 + +111 typename std::decay<tuple_element_t<Is, T>>::type >(
+ 306 + + arr[Is], ctx, ec)
+ 307 + + ...);
+ 308 + + #if defined(BOOST_GCC)
+ 309 + + # pragma GCC diagnostic push
+ 310 + + # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+ 311 + + #endif
+ 312 + +91 if( ec.failed() )
+ 313 + +13 return {boost::system::in_place_error, ec};
+ 314 + + #if defined(BOOST_GCC)
+ 315 + + # pragma GCC diagnostic pop
+ 316 + + #endif
+ 317 + +
+ 318 + + return {
+ 319 + +78 boost::system::in_place_value, T(std::move(*std::get<Is>(items))...)};
+ 320 + +54 }
+ 321 + +
+ 322 + + template< class T, class Ctx >
+ 323 + + system::result<T>
+ 324 + +115 value_to_impl(
+ 325 + + tuple_conversion_tag,
+ 326 + + try_value_to_tag<T>,
+ 327 + + value const& jv,
+ 328 + + Ctx const& ctx )
+ 329 + + {
+ 330 + +115 system::error_code ec;
+ 331 + +
+ 332 + +115 array const* arr = jv.if_array();
+ 333 + +115 if( !arr )
+ 334 + + {
+ 335 + +12 BOOST_JSON_FAIL(ec, error::not_array);
+ 336 + +12 return {boost::system::in_place_error, ec};
+ 337 + + }
+ 338 + +
+ 339 + +103 constexpr std::size_t N = std::tuple_size<remove_cvref<T>>::value;
+ 340 + +103 if( N != arr->size() )
+ 341 + + {
+ 342 + +12 BOOST_JSON_FAIL(ec, error::size_mismatch);
+ 343 + +12 return {boost::system::in_place_error, ec};
+ 344 + + }
+ 345 + +
+ 346 + +31 return try_make_tuple_like<T>(
+ 347 + +91 *arr, ctx, boost::mp11::make_index_sequence<N>());
+ 348 + + }
+ 349 + +
+ 350 + + template< class Ctx, class T >
+ 351 + + struct to_described_member
+ 352 + + {
+ 353 + + static_assert(
+ 354 + + uniquely_named_members<T>::value,
+ 355 + + "The type has several described members with the same name.");
+ 356 + +
+ 357 + + using Ds = described_members<T>;
+ 358 + +
+ 359 + + system::result<T>& res;
+ 360 + + object const& obj;
+ 361 + + Ctx const& ctx;
+ 362 + +
+ 363 + + template< class I >
+ 364 + + void
+ 365 + + operator()(I)
+ 366 + + {
+ 367 + + if( !res )
+ 368 + + return;
+ 369 + +
+ 370 + + using D = mp11::mp_at<Ds, I>;
+ 371 + + using M = described_member_t<T, D>;
+ 372 + +
+ 373 + + auto const found = obj.find(D::name);
+ 374 + + if( found == obj.end() )
+ 375 + + {
+ 376 + + BOOST_IF_CONSTEXPR( !is_optional_like<M>::value )
+ 377 + + {
+ 378 + + system::error_code ec;
+ 379 + + BOOST_JSON_FAIL(ec, error::size_mismatch);
+ 380 + + res = {boost::system::in_place_error, ec};
+ 381 + + }
+ 382 + + return;
+ 383 + + }
+ 384 + +
+ 385 + + #if defined(__GNUC__) && BOOST_GCC_VERSION >= 80000 && BOOST_GCC_VERSION < 11000
+ 386 + + # pragma GCC diagnostic push
+ 387 + + # pragma GCC diagnostic ignored "-Wunused"
+ 388 + + # pragma GCC diagnostic ignored "-Wunused-variable"
+ 389 + + #endif
+ 390 + + auto member_res = try_value_to<M>( found->value(), ctx );
+ 391 + + #if defined(__GNUC__) && BOOST_GCC_VERSION >= 80000 && BOOST_GCC_VERSION < 11000
+ 392 + + # pragma GCC diagnostic pop
+ 393 + + #endif
+ 394 + + if( member_res )
+ 395 + + (*res).* D::pointer = std::move(*member_res);
+ 396 + + else
+ 397 + + res = {boost::system::in_place_error, member_res.error()};
+ 398 + + }
+ 399 + + };
+ 400 + +
+ 401 + + // described classes
+ 402 + + template< class T, class Ctx >
+ 403 + + system::result<T>
+ 404 + + value_to_impl(
+ 405 + + described_class_conversion_tag,
+ 406 + + try_value_to_tag<T>,
+ 407 + + value const& jv,
+ 408 + + Ctx const& ctx )
+ 409 + + {
+ 410 + + BOOST_CORE_STATIC_ASSERT( std::is_default_constructible<T>::value );
+ 411 + + system::result<T> res;
+ 412 + +
+ 413 + + auto* obj = jv.if_object();
+ 414 + + if( !obj )
+ 415 + + {
+ 416 + + system::error_code ec;
+ 417 + + BOOST_JSON_FAIL(ec, error::not_object);
+ 418 + + res = {boost::system::in_place_error, ec};
+ 419 + + return res;
+ 420 + + }
+ 421 + +
+ 422 + + to_described_member<Ctx, T> member_converter{res, *obj, ctx};
+ 423 + +
+ 424 + + using Ds = typename decltype(member_converter)::Ds;
+ 425 + + constexpr std::size_t N = mp11::mp_size<Ds>::value;
+ 426 + + mp11::mp_for_each< mp11::mp_iota_c<N> >(member_converter);
+ 427 + +
+ 428 + + if( !res )
+ 429 + + return res;
+ 430 + +
+ 431 + + return res;
+ 432 + + }
+ 433 + +
+ 434 + + // described enums
+ 435 + + template< class T, class Ctx >
+ 436 + + system::result<T>
+ 437 + + value_to_impl(
+ 438 + + described_enum_conversion_tag,
+ 439 + + try_value_to_tag<T>,
+ 440 + + value const& jv,
+ 441 + + Ctx const& )
+ 442 + + {
+ 443 + + T val = {};
+ 444 + + (void)jv;
+ 445 + + #ifdef BOOST_DESCRIBE_CXX14
+ 446 + + system::error_code ec;
+ 447 + +
+ 448 + + auto str = jv.if_string();
+ 449 + + if( !str )
+ 450 + + {
+ 451 + + BOOST_JSON_FAIL(ec, error::not_string);
+ 452 + + return {system::in_place_error, ec};
+ 453 + + }
+ 454 + +
+ 455 + + if( !describe::enum_from_string(str->data(), val) )
+ 456 + + {
+ 457 + + BOOST_JSON_FAIL(ec, error::unknown_name);
+ 458 + + return {system::in_place_error, ec};
+ 459 + + }
+ 460 + + #endif
+ 461 + +
+ 462 + + return {system::in_place_value, val};
+ 463 + + }
+ 464 + +
+ 465 + + // optionals
+ 466 + + template< class T, class Ctx >
+ 467 + + system::result<T>
+ 468 + + value_to_impl(
+ 469 + + optional_conversion_tag,
+ 470 + + try_value_to_tag<T>,
+ 471 + + value const& jv,
+ 472 + + Ctx const& ctx)
+ 473 + + {
+ 474 + + using Inner = value_result_type<T>;
+ 475 + + if( jv.is_null() )
+ 476 + + return {};
+ 477 + + else
+ 478 + + return try_value_to<Inner>(jv, ctx);
+ 479 + + }
+ 480 + +
+ 481 + + // variants
+ 482 + + template< class T, class V, class I >
+ 483 + + using variant_construction_category = mp11::mp_cond<
+ 484 + + std::is_constructible< T, variant2::in_place_index_t<I::value>, V >,
+ 485 + + mp11::mp_int<2>,
+ 486 + + #ifndef BOOST_NO_CXX17_HDR_VARIANT
+ 487 + + std::is_constructible< T, std::in_place_index_t<I::value>, V >,
+ 488 + + mp11::mp_int<1>,
+ 489 + + #endif // BOOST_NO_CXX17_HDR_VARIANT
+ 490 + + mp11::mp_true,
+ 491 + + mp11::mp_int<0> >;
+ 492 + +
+ 493 + + template< class T, class I, class V >
+ 494 + + T
+ 495 + + initialize_variant( V&& v, mp11::mp_int<0> )
+ 496 + + {
+ 497 + + T t;
+ 498 + + t.template emplace<I::value>( std::move(v) );
+ 499 + + return t;
+ 500 + + }
+ 501 + +
+ 502 + + template< class T, class I, class V >
+ 503 + + T
+ 504 + + initialize_variant( V&& v, mp11::mp_int<2> )
+ 505 + + {
+ 506 + + return T( variant2::in_place_index_t<I::value>(), std::move(v) );
+ 507 + + }
+ 508 + +
+ 509 + + #ifndef BOOST_NO_CXX17_HDR_VARIANT
+ 510 + + template< class T, class I, class V >
+ 511 + + T
+ 512 + + initialize_variant( V&& v, mp11::mp_int<1> )
+ 513 + + {
+ 514 + + return T( std::in_place_index_t<I::value>(), std::move(v) );
+ 515 + + }
+ 516 + + #endif // BOOST_NO_CXX17_HDR_VARIANT
+ 517 + +
+ 518 + +
+ 519 + + template< class T, class Ctx >
+ 520 + + struct alternative_converter
+ 521 + + {
+ 522 + + system::result<T>& res;
+ 523 + + value const& jv;
+ 524 + + Ctx const& ctx;
+ 525 + +
+ 526 + + template< class I >
+ 527 + + void operator()( I ) const
+ 528 + + {
+ 529 + + if( res )
+ 530 + + return;
+ 531 + +
+ 532 + + using V = mp11::mp_at<T, I>;
+ 533 + + auto attempt = try_value_to<V>(jv, ctx);
+ 534 + + if( attempt )
+ 535 + + {
+ 536 + + using cat = variant_construction_category<T, V, I>;
+ 537 + + res = initialize_variant<T, I>( std::move(*attempt), cat() );
+ 538 + + }
+ 539 + + }
+ 540 + + };
+ 541 + +
+ 542 + + template< class T, class Ctx >
+ 543 + + system::result<T>
+ 544 + + value_to_impl(
+ 545 + + variant_conversion_tag,
+ 546 + + try_value_to_tag<T>,
+ 547 + + value const& jv,
+ 548 + + Ctx const& ctx)
+ 549 + + {
+ 550 + + system::error_code ec;
+ 551 + + BOOST_JSON_FAIL(ec, error::exhausted_variants);
+ 552 + +
+ 553 + + using Is = mp11::mp_iota< mp11::mp_size<T> >;
+ 554 + +
+ 555 + + system::result<T> res = {system::in_place_error, ec};
+ 556 + + mp11::mp_for_each<Is>( alternative_converter<T, Ctx>{res, jv, ctx} );
+ 557 + + return res;
+ 558 + + }
+ 559 + +
+ 560 + + template< class T, class Ctx >
+ 561 + + system::result<T>
+ 562 + + value_to_impl(
+ 563 + + path_conversion_tag, try_value_to_tag<T>, value const& jv, Ctx const& )
+ 564 + + {
+ 565 + + auto str = jv.if_string();
+ 566 + + if( !str )
+ 567 + + {
+ 568 + + system::error_code ec;
+ 569 + + BOOST_JSON_FAIL(ec, error::not_string);
+ 570 + + return {boost::system::in_place_error, ec};
+ 571 + + }
+ 572 + +
+ 573 + + string_view sv = str->subview();
+ 574 + + return {boost::system::in_place_value, T( sv.begin(), sv.end() )};
+ 575 + + }
+ 576 + +
+ 577 + + //----------------------------------------------------------
+ 578 + + // User-provided conversions; throwing -> throwing
+ 579 + + template< class T, class Ctx >
+ 580 + + mp11::mp_if< mp11::mp_valid<has_user_conversion_to_impl, T>, T >
+ 581 + +1 value_to_impl(
+ 582 + + user_conversion_tag, value_to_tag<T> tag, value const& jv, Ctx const&)
+ 583 + + {
+ 584 + +1 return tag_invoke(tag, jv);
+ 585 + + }
+ 586 + +
+ 587 + + template<
+ 588 + + class T,
+ 589 + + class Ctx,
+ 590 + + class Sup = supported_context<Ctx, T, value_to_conversion>
+ 591 + + >
+ 592 + + mp11::mp_if<
+ 593 + + mp11::mp_valid< has_context_conversion_to_impl, typename Sup::type, T>, T >
+ 594 + +1 value_to_impl(
+ 595 + + context_conversion_tag,
+ 596 + + value_to_tag<T> tag,
+ 597 + + value const& jv,
+ 598 + + Ctx const& ctx )
+ 599 + + {
+ 600 + +1 return tag_invoke( tag, jv, Sup::get(ctx) );
+ 601 + + }
+ 602 + +
+ 603 + + template<
+ 604 + + class T,
+ 605 + + class Ctx,
+ 606 + + class Sup = supported_context<Ctx, T, value_to_conversion>
+ 607 + + >
+ 608 + + mp11::mp_if<
+ 609 + + mp11::mp_valid<
+ 610 + + has_full_context_conversion_to_impl, typename Sup::type, T>,
+ 611 + + T>
+ 612 + + value_to_impl(
+ 613 + + full_context_conversion_tag,
+ 614 + + value_to_tag<T> tag,
+ 615 + + value const& jv,
+ 616 + + Ctx const& ctx )
+ 617 + + {
+ 618 + + return tag_invoke( tag, jv, Sup::get(ctx), ctx );
+ 619 + + }
+ 620 + +
+ 621 + + //----------------------------------------------------------
+ 622 + + // User-provided conversions; throwing -> nonthrowing
+ 623 + + template< class T, class Ctx >
+ 624 + + mp11::mp_if_c< !mp11::mp_valid<has_user_conversion_to_impl, T>::value, T>
+ 625 + +60 value_to_impl(
+ 626 + + user_conversion_tag, value_to_tag<T>, value const& jv, Ctx const& )
+ 627 + + {
+ 628 + +60 auto res = tag_invoke(try_value_to_tag<T>(), jv);
+ 629 + +60 if( res.has_error() )
+ 630 + +12 throw_system_error( res.error() );
+ 631 + +96 return std::move(*res);
+ 632 + +32 }
+ 633 + +
+ 634 + + template<
+ 635 + + class T,
+ 636 + + class Ctx,
+ 637 + + class Sup = supported_context<Ctx, T, value_to_conversion>
+ 638 + + >
+ 639 + + mp11::mp_if_c<
+ 640 + + !mp11::mp_valid<
+ 641 + + has_context_conversion_to_impl, typename Sup::type, T>::value,
+ 642 + + T>
+ 643 + +3 value_to_impl(
+ 644 + + context_conversion_tag, value_to_tag<T>, value const& jv, Ctx const& ctx )
+ 645 + + {
+ 646 + +3 auto res = tag_invoke( try_value_to_tag<T>(), jv, Sup::get(ctx) );
+ 647 + +3 if( res.has_error() )
+ 648 + +1 throw_system_error( res.error() );
+ 649 + +4 return std::move(*res);
+ 650 + + }
+ 651 + +
+ 652 + + template<
+ 653 + + class T,
+ 654 + + class Ctx,
+ 655 + + class Sup = supported_context<Ctx, T, value_to_conversion>
+ 656 + + >
+ 657 + + mp11::mp_if_c<
+ 658 + + !mp11::mp_valid<
+ 659 + + has_full_context_conversion_to_impl, typename Sup::type, T>::value,
+ 660 + + T>
+ 661 + + value_to_impl(
+ 662 + + full_context_conversion_tag,
+ 663 + + value_to_tag<T>,
+ 664 + + value const& jv,
+ 665 + + Ctx const& ctx )
+ 666 + + {
+ 667 + + auto res = tag_invoke(try_value_to_tag<T>(), jv, Sup::get(ctx), ctx);
+ 668 + + if( res.has_error() )
+ 669 + + throw_system_error( res.error() );
+ 670 + + return std::move(*res);
+ 671 + + }
+ 672 + +
+ 673 + + //----------------------------------------------------------
+ 674 + + // User-provided conversions; nonthrowing -> nonthrowing
+ 675 + + template< class T, class Ctx >
+ 676 + + mp11::mp_if<
+ 677 + + mp11::mp_valid<
+ 678 + + has_nonthrowing_user_conversion_to_impl, T>, system::result<T> >
+ 679 + +124 value_to_impl(
+ 680 + + user_conversion_tag, try_value_to_tag<T>, value const& jv, Ctx const& )
+ 681 + + {
+ 682 + +132 return tag_invoke(try_value_to_tag<T>(), jv);
+ 683 + + }
+ 684 + +
+ 685 + + template<
+ 686 + + class T,
+ 687 + + class Ctx,
+ 688 + + class Sup = supported_context<Ctx, T, value_to_conversion>
+ 689 + + >
+ 690 + + mp11::mp_if<
+ 691 + + mp11::mp_valid<
+ 692 + + has_nonthrowing_context_conversion_to_impl, typename Sup::type, T>,
+ 693 + + system::result<T> >
+ 694 + + value_to_impl(
+ 695 + + context_conversion_tag,
+ 696 + + try_value_to_tag<T> tag,
+ 697 + + value const& jv,
+ 698 + + Ctx const& ctx )
+ 699 + + {
+ 700 + + return tag_invoke( tag, jv, Sup::get(ctx) );
+ 701 + + }
+ 702 + +
+ 703 + + template<
+ 704 + + class T,
+ 705 + + class Ctx,
+ 706 + + class Sup = supported_context<Ctx, T, value_to_conversion>
+ 707 + + >
+ 708 + + mp11::mp_if<
+ 709 + + mp11::mp_valid<
+ 710 + + has_nonthrowing_full_context_conversion_to_impl,
+ 711 + + typename Sup::type,
+ 712 + + T>,
+ 713 + + system::result<T> >
+ 714 + + value_to_impl(
+ 715 + + full_context_conversion_tag,
+ 716 + + try_value_to_tag<T> tag,
+ 717 + + value const& jv,
+ 718 + + Ctx const& ctx )
+ 719 + + {
+ 720 + + return tag_invoke( tag, jv, Sup::get(ctx), ctx );
+ 721 + + }
+ 722 + +
+ 723 + + //----------------------------------------------------------
+ 724 + + // User-provided conversions; nonthrowing -> throwing
+ 725 + +
+ 726 + + template< class T, class... Args >
+ 727 + + system::result<T>
+ 728 + +36 wrap_conversion_exceptions( value_to_tag<T>, Args&& ... args )
+ 729 + + {
+ 730 + + #ifndef BOOST_NO_EXCEPTIONS
+ 731 + + try
+ 732 + + {
+ 733 + + #endif
+ 734 + + return {
+ 735 + + boost::system::in_place_value,
+ 736 + +36 tag_invoke( value_to_tag<T>(), static_cast<Args&&>(args)... )};
+ 737 + + #ifndef BOOST_NO_EXCEPTIONS
+ 738 + + }
+ 739 + +30 catch( std::bad_alloc const&)
+ 740 + + {
+ 741 + +6 throw;
+ 742 + + }
+ 743 + +12 catch( system::system_error const& e)
+ 744 + + {
+ 745 + +12 return {boost::system::in_place_error, e.code()};
+ 746 + + }
+ 747 + +12 catch( ... )
+ 748 + + {
+ 749 + +6 system::error_code ec;
+ 750 + +6 BOOST_JSON_FAIL(ec, error::exception);
+ 751 + +6 return {boost::system::in_place_error, ec};
+ 752 + + }
+ 753 + + #endif
+ 754 + + }
+ 755 + +
+ 756 + + template< class T, class Ctx >
+ 757 + + mp11::mp_if_c<
+ 758 + + !mp11::mp_valid<has_nonthrowing_user_conversion_to_impl, T>::value,
+ 759 + + system::result<T> >
+ 760 + +36 value_to_impl(
+ 761 + + user_conversion_tag, try_value_to_tag<T>, value const& jv, Ctx const& )
+ 762 + + {
+ 763 + +36 return wrap_conversion_exceptions(value_to_tag<T>(), jv);
+ 764 + + }
+ 765 + +
+ 766 + + template<
+ 767 + + class T,
+ 768 + + class Ctx,
+ 769 + + class Sup = supported_context<Ctx, T, value_to_conversion>
+ 770 + + >
+ 771 + + mp11::mp_if_c<
+ 772 + + !mp11::mp_valid<
+ 773 + + has_nonthrowing_context_conversion_to_impl,
+ 774 + + typename Sup::type,
+ 775 + + T>::value,
+ 776 + + system::result<T> >
+ 777 + + value_to_impl(
+ 778 + + context_conversion_tag,
+ 779 + + try_value_to_tag<T>,
+ 780 + + value const& jv,
+ 781 + + Ctx const& ctx )
+ 782 + + {
+ 783 + + return wrap_conversion_exceptions( value_to_tag<T>(), jv, Sup::get(ctx) );
+ 784 + + }
+ 785 + +
+ 786 + + template<
+ 787 + + class T,
+ 788 + + class Ctx,
+ 789 + + class Sup = supported_context<Ctx, T, value_to_conversion>
+ 790 + + >
+ 791 + + mp11::mp_if_c<
+ 792 + + !mp11::mp_valid<
+ 793 + + has_nonthrowing_full_context_conversion_to_impl,
+ 794 + + typename Sup::type,
+ 795 + + T>::value,
+ 796 + + system::result<T> >
+ 797 + + value_to_impl(
+ 798 + + full_context_conversion_tag,
+ 799 + + try_value_to_tag<T>,
+ 800 + + value const& jv,
+ 801 + + Ctx const& ctx )
+ 802 + + {
+ 803 + + return wrap_conversion_exceptions(
+ 804 + + value_to_tag<T>(), jv, Sup::get(ctx), ctx);
+ 805 + + }
+ 806 + +
+ 807 + + // no suitable conversion implementation
+ 808 + + template< class T, class Ctx >
+ 809 + + T
+ 810 + + value_to_impl( no_conversion_tag, value_to_tag<T>, value const&, Ctx const& )
+ 811 + + {
+ 812 + + static_assert(
+ 813 + + !std::is_same<T, T>::value,
+ 814 + + "No suitable tag_invoke overload found for the type");
+ 815 + + }
+ 816 + +
+ 817 + + // generic wrapper over non-throwing implementations
+ 818 + + template< class Impl, class T, class Ctx >
+ 819 + + T
+ 820 + +339 value_to_impl( Impl impl, value_to_tag<T>, value const& jv, Ctx const& ctx )
+ 821 + + {
+ 822 + +339 return value_to_impl(impl, try_value_to_tag<T>(), jv, ctx).value();
+ 823 + + }
+ 824 + +
+ 825 + + template< class Ctx, class T >
+ 826 + + using value_to_category = conversion_category<
+ 827 + + Ctx, T, value_to_conversion >;
+ 828 + +
+ 829 + + } // detail
+ 830 + +
+ 831 + + #ifndef BOOST_NO_CXX17_HDR_OPTIONAL
+ 832 + + inline
+ 833 + + system::result<std::nullopt_t>
+ 834 + + tag_invoke(
+ 835 + + try_value_to_tag<std::nullopt_t>,
+ 836 + + value const& jv)
+ 837 + + {
+ 838 + + if( jv.is_null() )
+ 839 + + return std::nullopt;
+ 840 + + system::error_code ec;
+ 841 + + BOOST_JSON_FAIL(ec, error::not_null);
+ 842 + + return ec;
+ 843 + + }
+ 844 + + #endif
+ 845 + +
+ 846 + + } // namespace json
+ 847 + + } // namespace boost
+ 848 + +
+ 849 + + #endif
+ 850 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/index.visit.hpp.d5ce1db1e3454de3538149bf6f28b617.html b/json/gcovr/index.visit.hpp.d5ce1db1e3454de3538149bf6f28b617.html new file mode 100644 index 00000000..3b5135c3 --- /dev/null +++ b/json/gcovr/index.visit.hpp.d5ce1db1e3454de3538149bf6f28b617.html @@ -0,0 +1,2830 @@ + + + + + + impl/visit.hpp - GCC Code Coverage Report + + + + + + +
+ + + + +
+
+ + + +
+ +
+
+
+
+

impl/visit.hpp

+
+ + 100.0% Lines (37/37) + + + -% Functions (0/0) + + + -% Branches (0/0) + +
+
+ +
+ + +
+
+ +
+
+
+
impl/visit.hpp
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineHitsSource Code
+ 1 + + //
+ 2 + + // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+ 3 + + //
+ 4 + + // Distributed under the Boost Software License, Version 1.0. (See accompanying
+ 5 + + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ 6 + + //
+ 7 + + // Official repository: https://github.com/boostorg/json
+ 8 + + //
+ 9 + +
+ 10 + + #ifndef BOOST_JSON_IMPL_VISIT_HPP
+ 11 + + #define BOOST_JSON_IMPL_VISIT_HPP
+ 12 + +
+ 13 + + namespace boost {
+ 14 + + namespace json {
+ 15 + +
+ 16 + +
+ 17 + + template<class Visitor>
+ 18 + + auto
+ 19 + +8 visit(
+ 20 + + Visitor&& v,
+ 21 + + value& jv) -> decltype(
+ 22 + + static_cast<Visitor&&>(v)( std::declval<std::nullptr_t&>() ) )
+ 23 + + {
+ 24 + +8 switch(jv.kind())
+ 25 + + {
+ 26 + +1 default: // unreachable()?
+ 27 + +1 case kind::string: return static_cast<Visitor&&>(v)( jv.get_string() );
+ 28 + +1 case kind::array: return static_cast<Visitor&&>(v)( jv.get_array() );
+ 29 + +1 case kind::object: return static_cast<Visitor&&>(v)( jv.get_object() );
+ 30 + +1 case kind::bool_: return static_cast<Visitor&&>(v)( jv.get_bool() );
+ 31 + +1 case kind::int64: return static_cast<Visitor&&>(v)( jv.get_int64() );
+ 32 + +1 case kind::uint64: return static_cast<Visitor&&>(v)( jv.get_uint64() );
+ 33 + +1 case kind::double_: return static_cast<Visitor&&>(v)( jv.get_double() );
+ 34 + +1 case kind::null: {
+ 35 + +1 auto np = nullptr;
+ 36 + +1 return static_cast<Visitor&&>(v)(np) ;
+ 37 + + }
+ 38 + + }
+ 39 + + }
+ 40 + +
+ 41 + + template<class Visitor>
+ 42 + + auto
+ 43 + +256 visit(
+ 44 + + Visitor&& v,
+ 45 + + value const& jv) -> decltype(
+ 46 + + static_cast<Visitor&&>(v)( std::declval<std::nullptr_t const&>() ) )
+ 47 + + {
+ 48 + +256 switch(jv.kind())
+ 49 + + {
+ 50 + +45 default: // unreachable()?
+ 51 + +45 case kind::string: return static_cast<Visitor&&>(v)( jv.get_string() );
+ 52 + +11 case kind::array: return static_cast<Visitor&&>(v)( jv.get_array() );
+ 53 + +21 case kind::object: return static_cast<Visitor&&>(v)( jv.get_object() );
+ 54 + +29 case kind::bool_: return static_cast<Visitor&&>(v)( jv.get_bool() );
+ 55 + +91 case kind::int64: return static_cast<Visitor&&>(v)( jv.get_int64() );
+ 56 + +17 case kind::uint64: return static_cast<Visitor&&>(v)( jv.get_uint64() );
+ 57 + +9 case kind::double_: return static_cast<Visitor&&>(v)( jv.get_double() );
+ 58 + +33 case kind::null: {
+ 59 + +33 auto const np = nullptr;
+ 60 + +33 return static_cast<Visitor&&>(v)(np) ;
+ 61 + + }
+ 62 + + }
+ 63 + + }
+ 64 + +
+ 65 + +
+ 66 + + template<class Visitor>
+ 67 + + auto
+ 68 + +16 visit(
+ 69 + + Visitor&& v,
+ 70 + + value&& jv) -> decltype(
+ 71 + + static_cast<Visitor&&>(v)( std::declval<std::nullptr_t&&>() ) )
+ 72 + + {
+ 73 + +16 switch(jv.kind())
+ 74 + + {
+ 75 + +2 default: // unreachable()?
+ 76 + +2 case kind::string: return static_cast<Visitor&&>(v)( std::move( jv.get_string() ) );
+ 77 + +2 case kind::array: return static_cast<Visitor&&>(v)( std::move( jv.get_array() ) );
+ 78 + +2 case kind::object: return static_cast<Visitor&&>(v)( std::move( jv.get_object() ) );
+ 79 + +2 case kind::bool_: return static_cast<Visitor&&>(v)( std::move( jv.get_bool() ) );
+ 80 + +2 case kind::int64: return static_cast<Visitor&&>(v)( std::move( jv.get_int64() ) );
+ 81 + +2 case kind::uint64: return static_cast<Visitor&&>(v)( std::move( jv.get_uint64() ) );
+ 82 + +2 case kind::double_: return static_cast<Visitor&&>(v)( std::move( jv.get_double() ) );
+ 83 + +2 case kind::null: return static_cast<Visitor&&>(v)( std::nullptr_t() ) ;
+ 84 + + }
+ 85 + + }
+ 86 + +
+ 87 + + } // namespace json
+ 88 + + } // namespace boost
+ 89 + +
+ 90 + + #endif
+ 91 + +
+
+
+
+ + +
+
+ + + + diff --git a/json/gcovr/keep.txt b/json/gcovr/keep.txt deleted file mode 100644 index 2fa992c0..00000000 --- a/json/gcovr/keep.txt +++ /dev/null @@ -1 +0,0 @@ -keep diff --git a/json/gcovr/tree.json b/json/gcovr/tree.json new file mode 100644 index 00000000..c6abe458 --- /dev/null +++ b/json/gcovr/tree.json @@ -0,0 +1,802 @@ +[ + { + "name": "detail", + "coverage": "83.0", + "coverageClass": "coverage-medium", + "isDirectory": true, + "link": "index.detail.0ab43ac414239956f09d5b0181f77c50.html", + "children": [ + { + "name": "charconv", + "coverage": "52.9", + "coverageClass": "coverage-low", + "isDirectory": true, + "link": "index.charconv.510f5dd29cc43eca58c0d2b93adff045.html", + "children": [ + { + "name": "detail", + "coverage": "53.2", + "coverageClass": "coverage-low", + "isDirectory": true, + "link": "index.detail.287b6ad9e303318f27f0e943b3878477.html", + "children": [ + { + "name": "fast_float", + "coverage": "79.6", + "coverageClass": "coverage-medium", + "isDirectory": true, + "link": "index.fast_float.eccdc16b8d3a6677c41246e350f1ee5c.html", + "children": [ + { + "name": "ascii_number.hpp", + "coverage": "88.0", + "coverageClass": "coverage-medium", + "isDirectory": false, + "link": "index.ascii_number.hpp.06e327eb6aa84eac97ab3143afde5536.html", + "children": [] + }, + { + "name": "bigint.hpp", + "coverage": "89.9", + "coverageClass": "coverage-medium", + "isDirectory": false, + "link": "index.bigint.hpp.7ed59f082bdc8865c839e37a907818ae.html", + "children": [] + }, + { + "name": "decimal_to_binary.hpp", + "coverage": "94.7", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.decimal_to_binary.hpp.aa9ca29d0a37b3474618fa96dc2b5923.html", + "children": [] + }, + { + "name": "digit_comparison.hpp", + "coverage": "76.9", + "coverageClass": "coverage-medium", + "isDirectory": false, + "link": "index.digit_comparison.hpp.d6697c5bee8735e93381acb1ede736e7.html", + "children": [] + }, + { + "name": "float_common.hpp", + "coverage": "62.7", + "coverageClass": "coverage-low", + "isDirectory": false, + "link": "index.float_common.hpp.60c7bd470abb6c3589089cc294f360d4.html", + "children": [] + }, + { + "name": "parse_number.hpp", + "coverage": "42.9", + "coverageClass": "coverage-low", + "isDirectory": false, + "link": "index.parse_number.hpp.7949b767450af0a0c4e38d459ab8efa6.html", + "children": [] + } + ] + }, + { + "name": "compute_float64.hpp", + "coverage": "0.0", + "coverageClass": "coverage-low", + "isDirectory": false, + "link": "index.compute_float64.hpp.14da4b5c079d398c9d8067d0d7a811dc.html", + "children": [] + }, + { + "name": "emulated128.hpp", + "coverage": "0.0", + "coverageClass": "coverage-low", + "isDirectory": false, + "link": "index.emulated128.hpp.0ceaaed8d203e80b297f0b1456573326.html", + "children": [] + }, + { + "name": "from_chars_float_impl.hpp", + "coverage": "0.0", + "coverageClass": "coverage-low", + "isDirectory": false, + "link": "index.from_chars_float_impl.hpp.a4a922435f511d73baf7f630422a09ef.html", + "children": [] + }, + { + "name": "from_chars_integer_impl.hpp", + "coverage": "0.0", + "coverageClass": "coverage-low", + "isDirectory": false, + "link": "index.from_chars_integer_impl.hpp.62421e671be5feb9c0f1e3df5a09b86e.html", + "children": [] + }, + { + "name": "integer_search_trees.hpp", + "coverage": "0.0", + "coverageClass": "coverage-low", + "isDirectory": false, + "link": "index.integer_search_trees.hpp.4c04f6dbbc7f34b14ccd1b3f4b32318c.html", + "children": [] + }, + { + "name": "parser.hpp", + "coverage": "0.0", + "coverageClass": "coverage-low", + "isDirectory": false, + "link": "index.parser.hpp.45a498812670ba69036304cd17e3052d.html", + "children": [] + } + ] + }, + { + "name": "impl/from_chars.ipp", + "coverage": "25.0", + "coverageClass": "coverage-low", + "isDirectory": true, + "link": "index.from_chars.ipp.1f79c0e3711fd7d708dc790de46627b3.html", + "children": [] + } + ] + }, + { + "name": "impl", + "coverage": "99.3", + "coverageClass": "coverage-high", + "isDirectory": true, + "link": "index.impl.cde90127c1b0418ad9f796d3477a9914.html", + "children": [ + { + "name": "array.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.array.hpp.ffb272ea2be09d8caf7e569420bf69e3.html", + "children": [] + }, + { + "name": "default_resource.ipp", + "coverage": "87.5", + "coverageClass": "coverage-medium", + "isDirectory": false, + "link": "index.default_resource.ipp.29b0230184410f16ceaecef9a447dcef.html", + "children": [] + }, + { + "name": "except.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.except.ipp.12c9aef5d4d66299103ac6024ed0063f.html", + "children": [] + }, + { + "name": "format.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.format.ipp.9ec47a71b786a54db9e57825e82a5eb7.html", + "children": [] + }, + { + "name": "handler.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.handler.ipp.25997a61b96794a78e1e3ddeede59723.html", + "children": [] + }, + { + "name": "shared_resource.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.shared_resource.ipp.f07eb9144ccb01dab822bc01a22dda0d.html", + "children": [] + }, + { + "name": "stack.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.stack.hpp.c6cfbf398aba6b34d13f47ba0d19bf6a.html", + "children": [] + }, + { + "name": "stack.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.stack.ipp.3a9e0e01201646e2f48328d15e4e2602.html", + "children": [] + }, + { + "name": "string_impl.ipp", + "coverage": "99.1", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.string_impl.ipp.e66f2c45d36b3fec9c3bfbb095fa9edb.html", + "children": [] + } + ] + }, + { + "name": "ryu", + "coverage": "99.7", + "coverageClass": "coverage-high", + "isDirectory": true, + "link": "index.ryu.9a047557b83bbcb666051bf9b69b073a.html", + "children": [ + { + "name": "detail", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": true, + "link": "index.detail.e4ef6da21b1421bbb8fd14958bc3b5ac.html", + "children": [ + { + "name": "common.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.common.hpp.98695bbba488db8061085c97a91bfff6.html", + "children": [] + }, + { + "name": "d2s.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.d2s.hpp.cde3922f605044959e8be4ef6db1abab.html", + "children": [] + }, + { + "name": "d2s_full_table.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.d2s_full_table.hpp.08b587354545c40cd025a0cdb25e60c9.html", + "children": [] + }, + { + "name": "d2s_intrinsics.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.d2s_intrinsics.hpp.83ef835088fb80240623093e946e5ee8.html", + "children": [] + }, + { + "name": "digit_table.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.digit_table.hpp.54cb42fce758b96305314c836f5822d5.html", + "children": [] + } + ] + }, + { + "name": "impl/d2s.ipp", + "coverage": "99.6", + "coverageClass": "coverage-high", + "isDirectory": true, + "link": "index.d2s.ipp.5c6823db6d8cdf35aa2e1efe1dbd8e24.html", + "children": [] + } + ] + }, + { + "name": "array.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.array.hpp.161c04ed0fb44652959476d632ffe1a5.html", + "children": [] + }, + { + "name": "buffer.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.buffer.hpp.55b2280adf5814131719bffc56d99e63.html", + "children": [] + }, + { + "name": "config.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.config.hpp.0a32ee1b4391ae1eeb404af25739161a.html", + "children": [] + }, + { + "name": "default_resource.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.default_resource.hpp.cf498b84410e67aa58bd4c613cab1f84.html", + "children": [] + }, + { + "name": "digest.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.digest.hpp.905cd2165a4f34376c449f885fe1adf1.html", + "children": [] + }, + { + "name": "literals.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.literals.hpp.2e722ac7a80e95232217c08e5473907a.html", + "children": [] + }, + { + "name": "object.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.object.hpp.f7e5cc97accf7f1302ce80ea402b6373.html", + "children": [] + }, + { + "name": "parse_into.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.parse_into.hpp.f1e9fbffabe35587d223b9d98d9e761c.html", + "children": [] + }, + { + "name": "sbo_buffer.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.sbo_buffer.hpp.9e08251ec0ed54496b3a8a6fb89a63c3.html", + "children": [] + }, + { + "name": "shared_resource.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.shared_resource.hpp.1927ca08c89a37cdfbf293076af47ff7.html", + "children": [] + }, + { + "name": "sse2.hpp", + "coverage": "97.8", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.sse2.hpp.6a507d81ac7c10f52d533f58d85ac238.html", + "children": [] + }, + { + "name": "stack.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.stack.hpp.2c1d90a4d04ade6bea988474789a22e6.html", + "children": [] + }, + { + "name": "stream.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.stream.hpp.07654afdcb5f383c2335d7fecd03055c.html", + "children": [] + }, + { + "name": "string_impl.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.string_impl.hpp.3bd773ee5e5571ae1ed6db73d00280e3.html", + "children": [] + }, + { + "name": "utf8.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.utf8.hpp.d18a20eb6345bd7b0b78784fd246f3ed.html", + "children": [] + }, + { + "name": "value.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value.hpp.08b63e532c8156eaeb5cccaa7944e074.html", + "children": [] + }, + { + "name": "value_from.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value_from.hpp.1cdcc419fa9e4a63453aa84ed54ca11f.html", + "children": [] + }, + { + "name": "value_to.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value_to.hpp.635e555e887031c6fc380bccf2c402de.html", + "children": [] + } + ] + }, + { + "name": "impl", + "coverage": "99.2", + "coverageClass": "coverage-high", + "isDirectory": true, + "link": "index.impl.c82c9a65c0038782a53ba4c76e95a641.html", + "children": [ + { + "name": "array.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.array.hpp.43ca8a64d5cb1e0e18bac819d8dd589d.html", + "children": [] + }, + { + "name": "array.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.array.ipp.12b73a50f89b12e61f6c515c936b6c51.html", + "children": [] + }, + { + "name": "conversion.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.conversion.hpp.c385894883668d872f8d1b74220b0f7e.html", + "children": [] + }, + { + "name": "error.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.error.hpp.561447e3b80e5107d88e9cf24f3b9513.html", + "children": [] + }, + { + "name": "error.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.error.ipp.5ffd5dbb81ff10cef7db2ed5dff0c794.html", + "children": [] + }, + { + "name": "kind.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.kind.ipp.944bac86090b83665f00c8cee1a3defe.html", + "children": [] + }, + { + "name": "monotonic_resource.ipp", + "coverage": "97.1", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.monotonic_resource.ipp.05f2ed6d69820a792f84fc5a30acb7c6.html", + "children": [] + }, + { + "name": "null_resource.ipp", + "coverage": "77.8", + "coverageClass": "coverage-medium", + "isDirectory": false, + "link": "index.null_resource.ipp.a960c79e90c931af68e459ac2d12d5fe.html", + "children": [] + }, + { + "name": "object.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.object.hpp.f9faeb03c62042d95f8ee35052afa9e9.html", + "children": [] + }, + { + "name": "object.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.object.ipp.84c492a53a4bbdeb0fd1338b41d399a5.html", + "children": [] + }, + { + "name": "parse.ipp", + "coverage": "96.1", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.parse.ipp.bda6280a016bf6834766bc3a0bff32bc.html", + "children": [] + }, + { + "name": "parse_into.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.parse_into.hpp.9fe27b0246ac36c90c713d2ffcd261fd.html", + "children": [] + }, + { + "name": "parser.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.parser.ipp.266f2bed4bd28788f0addeb11aa58a0d.html", + "children": [] + }, + { + "name": "pointer.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.pointer.ipp.29ac44758c62ce39e625bbc7f1409991.html", + "children": [] + }, + { + "name": "serialize.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.serialize.hpp.d3414f2b51c87c80044a72e36bd57115.html", + "children": [] + }, + { + "name": "serialize.ipp", + "coverage": "96.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.serialize.ipp.01c963125bda877c839757dd2c6962c0.html", + "children": [] + }, + { + "name": "serializer.hpp", + "coverage": "97.8", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.serializer.hpp.ad86b38709508f8d05ea641d2e98c1da.html", + "children": [] + }, + { + "name": "serializer.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.serializer.ipp.a6e01f5c62a1e98844cee0136d1d1512.html", + "children": [] + }, + { + "name": "static_resource.ipp", + "coverage": "81.8", + "coverageClass": "coverage-medium", + "isDirectory": false, + "link": "index.static_resource.ipp.da4918eee73bb2b38d71ee2c22c5a4b6.html", + "children": [] + }, + { + "name": "stream_parser.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.stream_parser.ipp.9e84d7cb15fc2f2f5eb0a5dbb07fed15.html", + "children": [] + }, + { + "name": "string.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.string.hpp.753c5fbae83abdbca988b8d9bf6c7e2c.html", + "children": [] + }, + { + "name": "string.ipp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.string.ipp.608f1816a0e4c09495ec66dab6eb9085.html", + "children": [] + }, + { + "name": "value.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value.hpp.927a100eb53bf40397be1d8b22da1871.html", + "children": [] + }, + { + "name": "value.ipp", + "coverage": "98.7", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value.ipp.210aedf137631846f16fbe0ee4f0812c.html", + "children": [] + }, + { + "name": "value_ref.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value_ref.hpp.9e9582fd1af4a003bf535e71a0b7904d.html", + "children": [] + }, + { + "name": "value_ref.ipp", + "coverage": "96.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value_ref.ipp.e9a0bd8aab92a2b5ab364bf6b69e3959.html", + "children": [] + }, + { + "name": "value_stack.ipp", + "coverage": "99.5", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value_stack.ipp.898987b601e2219cdbbc0139ef61766f.html", + "children": [] + }, + { + "name": "visit.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.visit.hpp.d5ce1db1e3454de3538149bf6f28b617.html", + "children": [] + } + ] + }, + { + "name": "array.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.array.hpp.6e0bda7bf6757e548b5faad83e899291.html", + "children": [] + }, + { + "name": "basic_parser.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.basic_parser.hpp.c9c83104d1acc54b93b6e51f63102df2.html", + "children": [] + }, + { + "name": "basic_parser_impl.hpp", + "coverage": "98.3", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.basic_parser_impl.hpp.5c3e10cbda02afe7ee8dcae02239f852.html", + "children": [] + }, + { + "name": "monotonic_resource.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.monotonic_resource.hpp.c7901c306f139d49bdd39970ea9decfb.html", + "children": [] + }, + { + "name": "object.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.object.hpp.4af583e26a117226f5f096905dacf35c.html", + "children": [] + }, + { + "name": "parser.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.parser.hpp.d91835266758ed9bedb91a3636a5e82c.html", + "children": [] + }, + { + "name": "pilfer.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.pilfer.hpp.4dd6b487af20fd66fc07f525c990eb8b.html", + "children": [] + }, + { + "name": "result_for.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.result_for.hpp.e956a435ea4d78939339c698f7ed6545.html", + "children": [] + }, + { + "name": "serializer.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.serializer.hpp.79c79ec35822453ea6370e04c673a001.html", + "children": [] + }, + { + "name": "static_resource.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.static_resource.hpp.7bee809dfe2a5a1cb7dd0c3dd2654987.html", + "children": [] + }, + { + "name": "storage_ptr.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.storage_ptr.hpp.ac80baa46fb5bebc8f455223b00c44c4.html", + "children": [] + }, + { + "name": "stream_parser.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.stream_parser.hpp.756a2056175378bf4974ad36f699d9ba.html", + "children": [] + }, + { + "name": "string.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.string.hpp.a0ee7b78a1e1a48649112e27bc32c7ed.html", + "children": [] + }, + { + "name": "value.hpp", + "coverage": "98.9", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value.hpp.4e464561aa627034092b7a363639d5b7.html", + "children": [] + }, + { + "name": "value_from.hpp", + "coverage": "92.3", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value_from.hpp.a24a88c1f8fcc581db892ed3062c98a8.html", + "children": [] + }, + { + "name": "value_ref.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value_ref.hpp.5136da43247c9084cc2a038477b40231.html", + "children": [] + }, + { + "name": "value_to.hpp", + "coverage": "100.0", + "coverageClass": "coverage-high", + "isDirectory": false, + "link": "index.value_to.hpp.1b7ce679b2c4b444ce7bf9f62953b6be.html", + "children": [] + } +] \ No newline at end of file diff --git a/scripts/build_tree.py b/scripts/build_tree.py new file mode 100755 index 00000000..17eeea8f --- /dev/null +++ b/scripts/build_tree.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +""" +Build a JSON tree structure from gcovr HTML output. +This enables true inline expand/collapse in the sidebar. +""" + +import json +import os +import re +import sys +from html.parser import HTMLParser +from pathlib import Path + + +class FileListParser(HTMLParser): + """Parse gcovr HTML to extract file list entries and current path.""" + + def __init__(self): + super().__init__() + self.entries = [] + self.current_path = '' + self.in_file_row = False + self.current_entry = {} + self.capture_text = None + self.in_breadcrumb = False + + def handle_starttag(self, tag, attrs): + attrs_dict = dict(attrs) + + # Detect breadcrumb to extract current path + if tag == 'div' and attrs_dict.get('class') == 'breadcrumb': + self.in_breadcrumb = True + + # Detect file-row divs + if tag == 'div' and 'class' in attrs_dict: + classes = attrs_dict['class'].split() + if 'file-row' in classes: + self.in_file_row = True + self.current_entry = { + 'name': attrs_dict.get('data-filename', ''), + 'coverage': attrs_dict.get('data-coverage', '0'), + 'is_dir': 'directory' in classes, + 'link': None + } + + # Capture links in file rows + if self.in_file_row and tag == 'a': + href = attrs_dict.get('href', '') + if href and not self.current_entry.get('link'): + self.current_entry['link'] = href + + # Capture coverage percent + if self.in_file_row and tag == 'span' and 'class' in attrs_dict: + if 'coverage-percent' in attrs_dict['class']: + self.capture_text = 'coverage' + + def handle_data(self, data): + if self.capture_text == 'coverage' and self.in_file_row: + match = re.search(r'([\d.]+)%?', data.strip()) + if match: + self.current_entry['coverage'] = match.group(1) + self.capture_text = None + + def handle_endtag(self, tag): + if tag == 'div' and self.in_file_row and self.current_entry.get('name'): + self.entries.append(self.current_entry) + self.current_entry = {} + self.in_file_row = False + if tag == 'div' and self.in_breadcrumb: + self.in_breadcrumb = False + + +def parse_html_file(filepath): + """Parse a single HTML file and extract entries.""" + try: + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + + parser = FileListParser() + parser.feed(content) + return parser.entries + except Exception as e: + print(f"Error parsing {filepath}: {e}", file=sys.stderr) + return [] + + +def get_coverage_class(coverage): + """Determine coverage class based on percentage.""" + try: + pct = float(coverage) + if pct >= 90: + return 'coverage-high' + elif pct >= 75: + return 'coverage-medium' + else: + return 'coverage-low' + except: + return 'coverage-unknown' + + +def build_tree(output_dir): + """Build complete tree structure by following links recursively.""" + output_path = Path(output_dir) + + # Map from HTML filename to entries + file_entries = {} + + # Parse all HTML files + for html_file in output_path.glob('index*.html'): + entries = parse_html_file(html_file) + file_entries[html_file.name] = entries + + def build_node_from_file(html_filename, visited=None): + """Recursively build tree from HTML file.""" + if visited is None: + visited = set() + + if html_filename in visited: + return [] + visited.add(html_filename) + + entries = file_entries.get(html_filename, []) + nodes = [] + + for entry in entries: + name = entry['name'] + is_dir = entry['is_dir'] or '.' not in name + coverage = entry['coverage'] + link = entry['link'] + + node = { + 'name': name, + 'coverage': coverage, + 'coverageClass': get_coverage_class(coverage), + 'isDirectory': is_dir, + 'link': link, + 'children': [] + } + + # If directory with a link, recursively get its children + if is_dir and link and link in file_entries: + node['children'] = build_node_from_file(link, visited.copy()) + + nodes.append(node) + + # Sort: directories first, then files, alphabetically + nodes.sort(key=lambda x: (not x['isDirectory'], x['name'].lower())) + return nodes + + # Start from index.html + tree = build_node_from_file('index.html') + return tree + + +def inject_tree_data(output_dir, tree): + """Inject tree data as JavaScript variable into all HTML files.""" + output_path = Path(output_dir) + tree_script = f'' + + count = 0 + for html_file in output_path.glob('*.html'): + try: + with open(html_file, 'r', encoding='utf-8') as f: + content = f.read() + + # Check if already injected (look for the actual data, not just the var name) + if 'window.GCOVR_TREE_DATA=[' in content or 'window.GCOVR_TREE_DATA={' in content: + continue + + # Inject before + if '' in content: + content = content.replace('', f'{tree_script}\n') + with open(html_file, 'w', encoding='utf-8') as f: + f.write(content) + count += 1 + except Exception as e: + print(f"Warning: Could not inject into {html_file}: {e}", file=sys.stderr) + + return count + + +def main(): + if len(sys.argv) < 2: + print("Usage: build_tree.py ", file=sys.stderr) + sys.exit(1) + + output_dir = sys.argv[1] + + if not os.path.isdir(output_dir): + print(f"Error: {output_dir} is not a directory", file=sys.stderr) + sys.exit(1) + + tree = build_tree(output_dir) + + # Write tree.json + tree_file = os.path.join(output_dir, 'tree.json') + with open(tree_file, 'w', encoding='utf-8') as f: + json.dump(tree, f, indent=2) + + print(f"Generated {tree_file} with {len(tree)} root entries") + + # Inject tree data into HTML files for local file:// access + injected = inject_tree_data(output_dir, tree) + print(f"Injected tree data into {injected} HTML files") + + +if __name__ == '__main__': + main() diff --git a/scripts/gcovr_wrapper.py b/scripts/gcovr_wrapper.py new file mode 100755 index 00000000..79c08d80 --- /dev/null +++ b/scripts/gcovr_wrapper.py @@ -0,0 +1,22 @@ +#!/opt/homebrew/Cellar/gcovr/8.6/libexec/bin/python +""" +Wrapper for gcovr that registers .ipp files as C++ for syntax highlighting. +""" + +import sys + +# Register .ipp extension with Pygments before importing gcovr +from pygments.lexers import get_lexer_by_name, _mapping + +# Add .ipp to C++ lexer's filenames +cpp_lexer_info = _mapping.LEXERS.get('CppLexer') +if cpp_lexer_info: + # Format: (module, classname, names, filenames, mimetypes) + module, classname, names, filenames, mimetypes = cpp_lexer_info + if '*.ipp' not in filenames: + filenames = filenames + ('*.ipp',) + _mapping.LEXERS['CppLexer'] = (module, classname, names, filenames, mimetypes) + +# Now run gcovr +from gcovr.__main__ import main +sys.exit(main()) diff --git a/templates/html/base.html b/templates/html/base.html new file mode 100644 index 00000000..633b1d0e --- /dev/null +++ b/templates/html/base.html @@ -0,0 +1,99 @@ +{# -*- engine: jinja -*- #} + + + + + + {% block html_title %}{{info.head}}{% endblock %} + + + + + + +
+ + + + +
+
+ + +
+ {% block navigation %} + {% endblock %} +
+
+ +
+
+ {% block summary %} + {% endblock %} +
+ +
+ {% block content %} + {% endblock %} +
+
+ + +
+
+ + + diff --git a/templates/html/directory_page.content.html b/templates/html/directory_page.content.html new file mode 100644 index 00000000..2abc6d14 --- /dev/null +++ b/templates/html/directory_page.content.html @@ -0,0 +1,81 @@ +{# -*- engine: jinja -*- #} +{# Check if we have any function or branch data #} +{% set has_functions = entries | selectattr('functions.coverage', 'ne', '-') | list | length > 0 %} +{% set has_branches = entries | selectattr('branches.coverage', 'ne', '-') | list | length > 0 %} +
+
+
+ Name +
+
+ Coverage +
+
+ Lines +
+ {% if has_functions %} +
+ Functions +
+ {% endif %} + {% if has_branches %} +
+ Branches +
+ {% endif %} +
+ +
+ {% for row in entries %} + + {% endfor %} +
+
diff --git a/templates/html/directory_page.html b/templates/html/directory_page.html new file mode 100644 index 00000000..d51ca6e8 --- /dev/null +++ b/templates/html/directory_page.html @@ -0,0 +1,42 @@ +{# -*- engine: jinja -*- #} +{% extends "base.html" %} + +{% block html_title %}{%if relative_path %}{{relative_path}} - {% endif %}{{info.head}}{% endblock %} + +{% block sidebar_tree %} +{# Render sidebar tree from entries - check for file extension to determine type #} +{% for row in entries %} +{% set is_file = '.' in row.filename %} +
+
+ {% if not is_file and row.link %} + + + {% else %} + + {% endif %} + {% if is_file %} + + {% else %} + + {% endif %} + {% if row.link %} + {{row.filename}} + {% else %} + {{row.filename}} + {% endif %} +
+
+{% endfor %} +{% endblock %} + +{% block summary %} +{% include "directory_page.summary.html" %} +{% endblock %} + +{% block navigation %} +{% include "directory_page.navigation.html" %} +{% endblock %} + +{% block content %} +{% include "directory_page.content.html" %} +{% endblock %} diff --git a/templates/html/directory_page.navigation.html b/templates/html/directory_page.navigation.html new file mode 100644 index 00000000..fc7f9c42 --- /dev/null +++ b/templates/html/directory_page.navigation.html @@ -0,0 +1,9 @@ +{# -*- engine: jinja -*- #} + diff --git a/templates/html/directory_page.summary.html b/templates/html/directory_page.summary.html new file mode 100644 index 00000000..986039e2 --- /dev/null +++ b/templates/html/directory_page.summary.html @@ -0,0 +1,85 @@ +{# -*- engine: jinja -*- #} +
+
+
+

Lines

+
+
+
+ + + + + {{info.lines.coverage}}% +
+
+
+ Hit + {{info.lines.exec}} +
+
+ Total + {{info.lines.total}} +
+
+
+
+ +
+
+

Functions

+
+
+
+ + + + + {{info.functions.coverage}}% +
+
+
+ Hit + {{info.functions.exec}} +
+
+ Total + {{info.functions.total}} +
+
+
+
+ +
+
+

Branches

+
+
+
+ + + + + {{info.branches.coverage}}% +
+
+
+ Hit + {{info.branches.exec}} +
+
+ Total + {{info.branches.total}} +
+
+
+
+
+ +
+ High: ≥ {{COVERAGE_HIGH}}% + {% if COVERAGE_MED != COVERAGE_HIGH %} + Medium: ≥ {{COVERAGE_MED}}% + {% endif %} + Low: < {{COVERAGE_MED}}% +
diff --git a/templates/html/functions_page.content.html b/templates/html/functions_page.content.html new file mode 100644 index 00000000..b64509a2 --- /dev/null +++ b/templates/html/functions_page.content.html @@ -0,0 +1,36 @@ +{# -*- engine: jinja -*- #} +
+
+ {% set class_sortable = " sortable" if not info.static_report and function_list | length > 1 else "" %} +
Function
+
Calls
+
Lines
+
Branches
+
+ +
+ {% for entry in function_list %} +
+ +
+ {%- if entry["excluded"] %}excluded + {%- else %} + {%- if entry["count"] == 0 %}not called + {%- else %}{{ entry["count"] }}x + {%- endif -%} + {%- endif -%} +
+
{{ entry["line_coverage"] }}%
+
{{ entry["branch_coverage"] }}%
+
+ {% endfor %} +
+
diff --git a/templates/html/functions_page.html b/templates/html/functions_page.html new file mode 100644 index 00000000..d133f4c7 --- /dev/null +++ b/templates/html/functions_page.html @@ -0,0 +1,37 @@ +{# -*- engine: jinja -*- #} +{% extends "base.html" %} + +{% block html_title %}Functions - {{info.head}}{% endblock %} + +{% block breadcrumb %}Root / Functions{% endblock %} + +{% block sidebar_tree %} +
+ +
+
+
+ + + + + Functions +
+
+{% endblock %} + +{% block summary %} +{% include "functions_page.summary.html" %} +{% endblock %} + +{% block content %} +{% include "functions_page.content.html" %} +{% endblock %} diff --git a/templates/html/functions_page.summary.html b/templates/html/functions_page.summary.html new file mode 100644 index 00000000..8efba1be --- /dev/null +++ b/templates/html/functions_page.summary.html @@ -0,0 +1,16 @@ +{# -*- engine: jinja -*- #} +
+
+ Functions: + {{info.functions.coverage}}% + ({{info.functions.exec}} / {{info.functions.total}}) +
+
+ Lines: + {{info.lines.coverage}}% +
+
+ Branches: + {{info.branches.coverage}}% +
+
diff --git a/templates/html/gcovr.js b/templates/html/gcovr.js new file mode 100644 index 00000000..9844c376 --- /dev/null +++ b/templates/html/gcovr.js @@ -0,0 +1,453 @@ +/* GCOVR Custom JavaScript - Tree View & Interactivity */ + +(function() { + 'use strict'; + + // Wait for DOM ready + document.addEventListener('DOMContentLoaded', function() { + initTheme(); + initSidebar(); + initFileTree(); + initBreadcrumbs(); + initSearch(); + initSorting(); + initToggleButtons(); + initTreeControls(); + }); + + // =========================================== + // Breadcrumb Links + // =========================================== + + function initBreadcrumbs() { + var currentSpan = document.querySelector('.breadcrumb .current'); + if (!currentSpan || !window.GCOVR_TREE_DATA) return; + + var pathText = currentSpan.textContent.trim(); + var segments = pathText.split(' / '); + if (segments.length <= 1) return; + + // Create linked breadcrumb by traversing tree + var fragment = document.createDocumentFragment(); + var currentNodes = window.GCOVR_TREE_DATA; + + for (var i = 0; i < segments.length; i++) { + var segment = segments[i]; + + if (i > 0) { + var sep = document.createElement('span'); + sep.className = 'separator'; + sep.textContent = '/'; + fragment.appendChild(sep); + } + + // Find this segment in current level of tree + var foundNode = null; + for (var j = 0; j < currentNodes.length; j++) { + if (currentNodes[j].name === segment) { + foundNode = currentNodes[j]; + break; + } + } + + if (foundNode && foundNode.link && i < segments.length - 1) { + // Directory segment with link - make it clickable + var a = document.createElement('a'); + a.href = foundNode.link; + a.textContent = segment; + fragment.appendChild(a); + // Move to children for next iteration + currentNodes = foundNode.children || []; + } else { + // Last segment (current file) or no link found + var span = document.createElement('span'); + span.className = 'current-file'; + span.textContent = segment; + fragment.appendChild(span); + if (foundNode && foundNode.children) { + currentNodes = foundNode.children; + } + } + } + + currentSpan.innerHTML = ''; + currentSpan.appendChild(fragment); + } + + // =========================================== + // Theme Toggle + // =========================================== + + function initTheme() { + const toggle = document.getElementById('theme-toggle'); + const savedTheme = localStorage.getItem('gcovr-theme'); + + // Apply saved theme or default to dark + if (savedTheme) { + document.documentElement.setAttribute('data-theme', savedTheme); + } + + if (toggle) { + toggle.addEventListener('click', function() { + const current = document.documentElement.getAttribute('data-theme'); + const next = current === 'light' ? 'dark' : 'light'; + document.documentElement.setAttribute('data-theme', next); + localStorage.setItem('gcovr-theme', next); + }); + } + } + + // =========================================== + // Tree Controls (Expand/Collapse All) + // =========================================== + + function initTreeControls() { + var expandBtn = document.getElementById('expand-all'); + var collapseBtn = document.getElementById('collapse-all'); + + if (expandBtn) { + expandBtn.addEventListener('click', function() { + document.querySelectorAll('.tree-item').forEach(function(item) { + if (!item.classList.contains('no-children')) { + item.classList.add('expanded'); + var toggle = item.querySelector(':scope > .tree-item-header > .tree-folder-toggle'); + if (toggle) toggle.textContent = '−'; + } + }); + }); + } + + if (collapseBtn) { + collapseBtn.addEventListener('click', function() { + document.querySelectorAll('.tree-item').forEach(function(item) { + item.classList.remove('expanded'); + var toggle = item.querySelector(':scope > .tree-item-header > .tree-folder-toggle'); + if (toggle) toggle.textContent = '+'; + }); + }); + } + } + + // =========================================== + // Sidebar Toggle + // =========================================== + + function initSidebar() { + const sidebar = document.getElementById('sidebar'); + const toggle = document.getElementById('sidebar-toggle'); + + if (!sidebar || !toggle) return; + + // Load saved state + const isCollapsed = localStorage.getItem('sidebar-collapsed') === 'true'; + if (isCollapsed) { + sidebar.classList.add('collapsed'); + } + + toggle.addEventListener('click', function() { + sidebar.classList.toggle('collapsed'); + localStorage.setItem('sidebar-collapsed', sidebar.classList.contains('collapsed')); + }); + + // Mobile: open sidebar when clicked outside should close it + document.addEventListener('click', function(e) { + if (window.innerWidth <= 1024) { + if (sidebar.classList.contains('open') && + !sidebar.contains(e.target) && + e.target !== toggle && + !toggle.contains(e.target)) { + sidebar.classList.remove('open'); + } + } + }); + + // Mobile toggle + toggle.addEventListener('click', function() { + if (window.innerWidth <= 1024) { + sidebar.classList.toggle('open'); + } + }); + } + + // =========================================== + // File Tree - Load from tree.json + // =========================================== + + function initFileTree() { + var treeContainer = document.getElementById('file-tree'); + if (!treeContainer) return; + + // Check for embedded tree data first (works for local file:// access) + if (window.GCOVR_TREE_DATA) { + renderTree(treeContainer, window.GCOVR_TREE_DATA); + return; + } + + // Fallback: try to load tree.json for full hierarchy + fetch('tree.json') + .then(function(response) { + if (!response.ok) throw new Error('No tree.json'); + return response.json(); + }) + .then(function(tree) { + renderTree(treeContainer, tree); + }) + .catch(function(err) { + console.log('tree.json not found, using static sidebar'); + // Keep existing static content from Jinja template + }); + } + + function renderTree(container, tree) { + container.innerHTML = ''; + + if (!tree || tree.length === 0) { + container.innerHTML = '
No files found
'; + return; + } + + tree.forEach(function(item) { + container.appendChild(createTreeItem(item)); + }); + + // Auto-expand to current file and highlight it + expandToCurrentFile(container); + } + + function expandToCurrentFile(container) { + // Get current page filename + var currentPage = window.location.pathname.split('/').pop() || 'index.html'; + + // Find the link matching current page + var currentLink = container.querySelector('a[href="' + currentPage + '"]'); + if (!currentLink) return; + + // Mark as active + var treeItem = currentLink.closest('.tree-item'); + if (treeItem) { + treeItem.classList.add('active'); + } + + // Expand all parent folders + var parent = currentLink.closest('.tree-children'); + while (parent) { + var parentItem = parent.closest('.tree-item'); + if (parentItem) { + parentItem.classList.add('expanded'); + var toggle = parentItem.querySelector(':scope > .tree-item-header > .tree-folder-toggle'); + if (toggle) toggle.textContent = '−'; + } + parent = parentItem ? parentItem.parentElement.closest('.tree-children') : null; + } + + // Scroll into view + if (currentLink) { + currentLink.scrollIntoView({ block: 'center', behavior: 'smooth' }); + } + } + + function createTreeItem(item) { + var hasChildren = item.children && item.children.length > 0; + var isDirectory = item.isDirectory || hasChildren; + + var div = document.createElement('div'); + div.className = 'tree-item' + (isDirectory ? ' is-folder' : '') + (hasChildren ? '' : ' no-children'); + + var header = document.createElement('div'); + header.className = 'tree-item-header'; + var toggle = null; + + // Toggle button (+/-) for folders with children + if (hasChildren) { + toggle = document.createElement('button'); + toggle.className = 'tree-folder-toggle'; + toggle.textContent = '+'; + toggle.setAttribute('aria-label', 'Toggle folder'); + toggle.addEventListener('click', function(e) { + e.stopPropagation(); + e.preventDefault(); + var isExpanded = div.classList.toggle('expanded'); + toggle.textContent = isExpanded ? '−' : '+'; + }); + header.appendChild(toggle); + + // Make entire header clickable to expand/collapse + header.style.cursor = 'pointer'; + header.addEventListener('click', function(e) { + // Don't toggle if clicking a link + if (e.target.tagName === 'A') return; + e.preventDefault(); + var isExpanded = div.classList.toggle('expanded'); + toggle.textContent = isExpanded ? '−' : '+'; + }); + } else { + var spacer = document.createElement('span'); + spacer.className = 'tree-spacer'; + header.appendChild(spacer); + } + + // Icon - different for folders vs files + var icon = document.createElement('span'); + if (isDirectory) { + icon.className = 'tree-icon tree-icon-folder'; + icon.innerHTML = ''; + } else { + icon.className = 'tree-icon tree-icon-file'; + icon.innerHTML = ''; + } + header.appendChild(icon); + + // Label (with link if available) + var label = document.createElement('span'); + label.className = 'tree-label'; + label.title = item.name; + if (item.link) { + var link = document.createElement('a'); + link.href = item.link; + link.textContent = item.name; + link.title = item.name; + label.appendChild(link); + } else { + label.textContent = item.name; + } + header.appendChild(label); + + div.appendChild(header); + + // Children container (for expand/collapse) + if (hasChildren) { + var childrenWrapper = document.createElement('div'); + childrenWrapper.className = 'tree-children'; + + var childrenInner = document.createElement('div'); + childrenInner.className = 'tree-children-inner'; + item.children.forEach(function(child) { + childrenInner.appendChild(createTreeItem(child)); + }); + + childrenWrapper.appendChild(childrenInner); + div.appendChild(childrenWrapper); + } + + return div; + } + + // =========================================== + // Search + // =========================================== + + function initSearch() { + const searchInput = document.getElementById('file-search'); + if (!searchInput) return; + + searchInput.addEventListener('input', function() { + const query = this.value.toLowerCase().trim(); + const treeItems = document.querySelectorAll('.tree-item'); + + treeItems.forEach(function(item) { + const label = item.querySelector('.tree-label'); + if (label) { + const text = label.textContent.toLowerCase(); + const matches = query === '' || text.includes(query); + item.style.display = matches ? '' : 'none'; + } + }); + }); + } + + // =========================================== + // Sorting + // =========================================== + + function initSorting() { + const headers = document.querySelectorAll('.file-list-header .sortable, .functions-header .sortable'); + + headers.forEach(function(header) { + header.addEventListener('click', function() { + const sortKey = this.dataset.sort; + const isAscending = this.classList.contains('sorted-ascending'); + + // Remove sorted class from all headers + headers.forEach(function(h) { + h.classList.remove('sorted-ascending', 'sorted-descending'); + }); + + // Toggle sort direction + this.classList.add(isAscending ? 'sorted-descending' : 'sorted-ascending'); + + // Sort the list + sortList(sortKey, !isAscending); + }); + }); + } + + function sortList(key, ascending) { + const container = document.getElementById('file-list') || document.querySelector('.functions-body'); + if (!container) return; + + const rows = Array.from(container.children); + + rows.sort(function(a, b) { + let aVal = a.dataset[key] || a.querySelector('[data-sort]')?.dataset.sort || ''; + let bVal = b.dataset[key] || b.querySelector('[data-sort]')?.dataset.sort || ''; + + // Try to parse as numbers + const aNum = parseFloat(aVal); + const bNum = parseFloat(bVal); + + if (!isNaN(aNum) && !isNaN(bNum)) { + return ascending ? aNum - bNum : bNum - aNum; + } + + // String comparison + return ascending ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal); + }); + + rows.forEach(function(row) { + container.appendChild(row); + }); + } + + // =========================================== + // Toggle Buttons (Coverage Lines) + // =========================================== + + function initToggleButtons() { + const buttons = document.querySelectorAll('.button_toggle_coveredLine, .button_toggle_uncoveredLine, .button_toggle_partialCoveredLine, .button_toggle_excludedLine'); + + buttons.forEach(function(button) { + button.addEventListener('click', function() { + const lineClass = this.value; + const showClass = 'show_' + lineClass; + + // Toggle the button state + this.classList.toggle(showClass); + + // Toggle visibility of lines + const lines = document.querySelectorAll('.' + lineClass); + lines.forEach(function(line) { + line.classList.toggle(showClass); + }); + }); + }); + + // Also handle simpler toggle buttons + const simpleToggles = document.querySelectorAll('.btn-toggle'); + simpleToggles.forEach(function(button) { + button.addEventListener('click', function() { + const classes = Array.from(this.classList); + const showClass = classes.find(function(c) { return c.startsWith('show_'); }); + + if (showClass) { + this.classList.toggle(showClass); + const lineClass = showClass.replace('show_', ''); + const lines = document.querySelectorAll('.' + lineClass); + lines.forEach(function(line) { + line.classList.toggle(showClass); + }); + } + }); + }); + } + +})(); diff --git a/templates/html/source_page.content.html b/templates/html/source_page.content.html new file mode 100644 index 00000000..208237be --- /dev/null +++ b/templates/html/source_page.content.html @@ -0,0 +1,177 @@ +{# -*- engine: jinja -*- #} +{# Check if we have any branch data #} +{% set has_branches = source_lines | selectattr('line_branches', 'defined') | selectattr('line_branches') | list | length > 0 %} +
+
+
{{filename}}
+
+ + + {% if lines.partial > 0 %} + + {% endif %} + {% if lines.excluded > 0 %} + + {% endif %} +
+
+ +
+ + + + + {% if has_branches %} + + {% endif %} + {% if SHOW_CONDITION_COVERAGE %} + + {% endif %} + {% if SHOW_DECISION %} + + {% endif %} + {% if SHOW_CALLS %} + + {% endif %} + + + + + + {% if info.single_page %} + {% set anchor_prefix = html_filename + "|" %} + {% else %} + {% set anchor_prefix = '' %} + {% endif %} + {% for row in source_lines %} + + + {% if has_branches %} + + {% endif %} + {% if SHOW_CONDITION_COVERAGE %} + + {% endif %} + {% if SHOW_DECISION %} + + {% endif %} + {% if SHOW_CALLS %} + + {% endif %} + + + + {% endfor %} + +
LineBranchConditionDecisionCallHitsSource Code
+ {{row.lineno}} + + {% if row.line_branches %} +
+ {{row.line_branches | sum(attribute='taken')}}/{{row.line_branches | sum(attribute='total')}} +
+ {% for linebranch in row.line_branches %} + {% if loop.length > 1 %} +
{{linebranch.function_name}}:
+ {% endif %} + {% for branch in linebranch.branches %} + {% if branch.branchno is defined %} + {% set branch_info = branch.branchno %} + {% else %} + {% set branch_info = "%d → %d" | format(branch.source_block_id, branch.destination_block_id) | safe %} + {% endif %} + {% if branch.excluded %} +
– Branch {{branch_info}} excluded.
+ {% elif branch.taken %} +
✓ Branch {{branch_info}} taken {{branch.count}} time{% if branch.count > 1 %}s{% endif %}.
+ {% else %} +
✗ Branch {{branch_info}} not taken.
+ {% endif %} + {% endfor %} + {% endfor %} +
+
+ {% endif %} +
+ {% if row.line_conditions %} +
+ {{row.line_conditions | sum(attribute='covered') }}/{{row.line_conditions | sum(attribute='count')}} +
+ {% for linecondition in row.line_conditions %} + {% if loop.length > 1 %} +
{{linecondition.function_name}}:
+ {% endif %} + {% for condition in linecondition.condition %} + {% if condition.excluded %} +
– {{condition.prefix}}excluded.
+ {% elif condition.not_covered_true and condition.not_covered_false %} +
✗ {{condition.prefix}}Not covered.
+ {% elif condition.not_covered_true %} +
✗ {{condition.prefix}}True not covered.
+ {% elif condition.not_covered_false %} +
✗ {{condition.prefix}}False not covered.
+ {% else %} +
✓ {{condition.prefix}}Fully covered.
+ {% endif%} + {% endfor %} + {% endfor %} +
+
+ {% endif %} +
+ {% if row.line_decisions %} +
+ {{row.line_decisions | sum(attribute='taken')}}/{{row.line_decisions | sum(attribute='total')}} +
+ {% for linedecision in row.line_decisions %} + {% if loop.length > 1 %} +
{{linedecision.function_name}}:
+ {% endif %} + {% for decision in linedecision.decisions %} + {% if decision.uncheckable %} +
? Decision couldn't be analyzed.
+ {% elif decision.taken %} +
✓ Decision '{{decision.name}}' taken {{decision.count}} time{% if decision.count > 1 %}s{% endif %}.
+ {% else %} +
✗ Decision '{{decision.name}}' not taken.
+ {% endif %} + {% endfor %} + {% endfor %} +
+
+ {% endif %} +
+ {% if row.line_calls %} +
+ {{row.line_calls | sum(attribute='invoked')}}/{{row.line_calls | sum(attribute='total')}} +
+ {% for linecall in row.line_calls %} + {% if loop.length > 1 %} +
{{linecall.function_name}}:
+ {% endif %} + {% for call in linecall.calls %} + {% if call.excluded %} +
– Call {{call.name}} excluded.
+ {% elif call.invoked %} +
✓ Call {{call.name}} invoked.
+ {% else %} +
✗ Call {{call.name}} not invoked.
+ {% endif%} + {% endfor %} + {% endfor %} +
+
+ {% endif %} +
+ {% if row.covclass == 'uncoveredLine' %}{% elif row.covclass == 'excludedLine' %}{% else %}{{row.linecount}}{% endif %} + {{row.source}}
+
+
diff --git a/templates/html/source_page.html b/templates/html/source_page.html new file mode 100644 index 00000000..f0e25f75 --- /dev/null +++ b/templates/html/source_page.html @@ -0,0 +1,42 @@ +{# -*- engine: jinja -*- #} +{% extends "base.html" %} + +{% block html_title %}{{filename}} - {{info.head}}{% endblock %} + +{% block breadcrumb %}Root/{{filename | replace("/", " / ")}}{% endblock %} + +{% block sidebar_tree %} +{# Show current file in sidebar #} +
+ +
+
+
+ + + + + {{filename}} +
+
+{% endblock %} + +{% block summary %} +{% include "source_page.summary.html" %} +{% endblock %} + +{% block navigation %} +{% include "source_page.navigation.html" %} +{% endblock %} + +{% block content %} +{% include "source_page.content.html" %} +{% endblock %} diff --git a/templates/html/source_page.navigation.html b/templates/html/source_page.navigation.html new file mode 100644 index 00000000..21c5ae3a --- /dev/null +++ b/templates/html/source_page.navigation.html @@ -0,0 +1,15 @@ +{# -*- engine: jinja -*- #} + diff --git a/templates/html/source_page.summary.html b/templates/html/source_page.summary.html new file mode 100644 index 00000000..40dbf569 --- /dev/null +++ b/templates/html/source_page.summary.html @@ -0,0 +1,26 @@ +{# -*- engine: jinja -*- #} +
+
+

{{filename}}

+
+ + {{lines.coverage}}% Lines ({{lines.exec}}/{{lines.total}}) + + + {{functions.coverage}}% Functions ({{functions.exec}}/{{functions.total}}) + + + {{branches.coverage}}% Branches ({{branches.exec}}/{{branches.total}}) + +
+
+ +
+ + +
+
diff --git a/templates/html/style.css b/templates/html/style.css new file mode 100644 index 00000000..1eee6cb6 --- /dev/null +++ b/templates/html/style.css @@ -0,0 +1,1481 @@ +/* =========================================== + GCOVR Custom Dark Theme with Sidebar + =========================================== */ + +@charset "utf-8"; + +:root { + /* Dark theme colors */ + --bg-primary: #0d1117; + --bg-secondary: #161b22; + --bg-tertiary: #21262d; + --bg-hover: #30363d; + --bg-active: #388bfd26; + + --text-primary: #e6edf3; + --text-secondary: #8b949e; + --text-muted: #6e7681; + + --border-color: #30363d; + --border-muted: #21262d; + + /* Accent colors */ + --accent-blue: #58a6ff; + --accent-green: #3fb950; + --accent-yellow: #d29922; + --accent-red: #f85149; + --accent-purple: #a371f7; + + /* Coverage colors */ + --coverage-high: #3fb950; + --coverage-high-bg: rgba(63, 185, 80, 0.15); + --coverage-medium: #d29922; + --coverage-medium-bg: rgba(210, 153, 34, 0.15); + --coverage-low: #f85149; + --coverage-low-bg: rgba(248, 81, 73, 0.15); + --coverage-unknown: #6e7681; + + /* Spacing */ + --sidebar-width: 280px; + --header-height: 56px; + + /* Fonts */ + --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; + --font-mono: 'SF Mono', 'Fira Code', Consolas, 'Liberation Mono', Menlo, monospace; + + /* Radius */ + --radius-sm: 4px; + --radius-md: 6px; + --radius-lg: 8px; + + /* Transitions */ + --transition-fast: 0.15s ease; + --transition-normal: 0.25s ease; +} + +/* Light Mode */ +[data-theme="light"] { + --bg-primary: #ffffff; + --bg-secondary: #f6f8fa; + --bg-tertiary: #eaeef2; + --bg-hover: #d0d7de; + --bg-active: rgba(84, 174, 255, 0.15); + + --text-primary: #1f2328; + --text-secondary: #656d76; + --text-muted: #8c959f; + + --border-color: #d0d7de; + --border-muted: #eaeef2; + + --accent-blue: #0969da; + --accent-green: #1a7f37; + --accent-yellow: #9a6700; + --accent-red: #cf222e; + --accent-purple: #8250df; + + --coverage-high: #1a7f37; + --coverage-high-bg: rgba(26, 127, 55, 0.15); + --coverage-medium: #9a6700; + --coverage-medium-bg: rgba(154, 103, 0, 0.15); + --coverage-low: #cf222e; + --coverage-low-bg: rgba(207, 34, 46, 0.15); +} + +/* Smooth theme transitions */ +body, .sidebar, .main-content, .main-header, .main-footer, +.sidebar-header, .sidebar-nav, .sidebar-footer, +.summary-card, .file-list-container, .source-container, +.tree-item-header, .coverage-badge, .tree-coverage, +.btn, .nav-link, input { + transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease; +} + +/* Coverage class colors */ +.coverage-high { color: var(--coverage-high) !important; } +.coverage-medium { color: var(--coverage-medium) !important; } +.coverage-low, .coverage-none { color: var(--coverage-low) !important; } +.coverage-unknown { color: var(--coverage-unknown) !important; } + +/* Reset */ +*, *::before, *::after { + box-sizing: border-box; +} + +body { + margin: 0; + padding: 0; + font-family: var(--font-sans); + font-size: 14px; + line-height: 1.5; + color: var(--text-primary); + background: var(--bg-primary); + overflow-x: hidden; +} + +a { + color: var(--accent-blue); + text-decoration: none; + transition: color var(--transition-fast); +} + +a:hover { + color: #79c0ff; + text-decoration: underline; +} + +/* =========================================== + App Layout + =========================================== */ + +.app-container { + display: flex; + min-height: 100vh; +} + +/* =========================================== + Sidebar + =========================================== */ + +.sidebar { + position: fixed; + left: 0; + top: 0; + bottom: 0; + width: var(--sidebar-width); + background: var(--bg-secondary); + border-right: 1px solid var(--border-color); + display: flex; + flex-direction: column; + z-index: 100; + transition: transform var(--transition-normal); +} + +.sidebar.collapsed { + transform: translateX(-100%); +} + +.sidebar-header { + padding: 16px; + border-bottom: 1px solid var(--border-color); +} + +.sidebar-title-row { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; +} + +.sidebar-title-link { + color: inherit; + text-decoration: none; +} + +.sidebar-title-link:hover { + color: var(--accent-blue); +} + +.sidebar-header h2 { + margin: 0; + font-size: 14px; + font-weight: 600; + color: var(--text-primary); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +/* Theme Toggle */ +.theme-toggle { + width: 32px; + height: 32px; + border-radius: var(--radius-md); + border: 1px solid var(--border-color); + background: var(--bg-tertiary); + color: var(--text-secondary); + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all var(--transition-fast); + padding: 0; +} + +.theme-toggle:hover { + background: var(--bg-hover); + color: var(--text-primary); + border-color: var(--text-muted); +} + +.theme-toggle svg { + width: 16px; + height: 16px; +} + +.theme-toggle .icon-sun { display: none; } +.theme-toggle .icon-moon { display: block; } + +[data-theme="light"] .theme-toggle .icon-sun { display: block; } +[data-theme="light"] .theme-toggle .icon-moon { display: none; } + +.sidebar-search { + position: relative; +} + +.sidebar-search input { + width: 100%; + padding: 8px 12px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + color: var(--text-primary); + font-size: 13px; + outline: none; + transition: border-color var(--transition-fast), box-shadow var(--transition-fast); +} + +.sidebar-search input:focus { + border-color: var(--accent-blue); + box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.15); +} + +.sidebar-search input::placeholder { + color: var(--text-muted); +} + +/* Tree Controls */ +.tree-controls { + display: flex; + gap: 8px; + padding: 8px 16px; + border-bottom: 1px solid var(--border-color); +} + +.tree-control-btn { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 4px 8px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + color: var(--text-secondary); + font-size: 11px; + cursor: pointer; + transition: all var(--transition-fast); +} + +.tree-control-btn:hover { + background: var(--bg-hover); + color: var(--text-primary); +} + +.tree-control-btn svg { + width: 12px; + height: 12px; +} + +.sidebar-nav { + flex: 1; + overflow-y: auto; + overflow-x: hidden; + padding: 8px 0; +} + +.sidebar-footer { + padding: 12px 16px; + border-top: 1px solid var(--border-color); + background: var(--bg-tertiary); +} + +.coverage-summary-mini { + display: flex; + align-items: center; + gap: 8px; +} + +.coverage-badge { + padding: 4px 10px; + border-radius: var(--radius-sm); + font-weight: 600; + font-size: 13px; +} + +.coverage-badge.coverage-high { + background: var(--coverage-high-bg); +} + +.coverage-badge.coverage-medium { + background: var(--coverage-medium-bg); +} + +.coverage-badge.coverage-low { + background: var(--coverage-low-bg); +} + +.coverage-label { + color: var(--text-secondary); + font-size: 12px; +} + +/* Tree View */ +.tree-loading { + padding: 16px; + color: var(--text-muted); + font-size: 13px; +} + +.tree-item { + user-select: none; +} + +.tree-item-header { + display: flex; + align-items: center; + padding: 2px 12px 2px 8px; + cursor: pointer; + transition: background var(--transition-fast); + gap: 4px; + /* Extend background full width */ + margin-left: -200px; + padding-left: 208px; + margin-right: -12px; + padding-right: 24px; +} + +.tree-item-header:hover { + background: var(--bg-hover); +} + +.tree-item-header.active, +.tree-item.active > .tree-item-header { + background: var(--bg-active); +} + +.tree-item.active > .tree-item-header .tree-label { + color: var(--accent-blue); + font-weight: 500; +} + +/* Folder toggle button (+/-) - minimal style */ +.tree-folder-toggle { + width: 16px; + height: 16px; + display: inline-flex; + align-items: center; + justify-content: center; + background: transparent; + border: none; + color: var(--text-muted); + font-size: 11px; + font-weight: 400; + font-family: var(--font-mono); + flex-shrink: 0; + cursor: pointer; + transition: color var(--transition-fast); + text-decoration: none; + line-height: 1; + margin-right: 2px; + padding: 0; +} + +.tree-folder-toggle:hover { + color: var(--text-primary); + text-decoration: none; +} + +/* Spacer for files (no toggle) */ +.tree-spacer { + width: 20px; + flex-shrink: 0; +} + +/* Legacy toggle classes */ +.tree-toggle { + width: 18px; + height: 18px; + display: flex; + align-items: center; + justify-content: center; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + color: var(--text-secondary); + font-size: 12px; + font-weight: 600; + font-family: var(--font-mono); + flex-shrink: 0; + cursor: pointer; + transition: all var(--transition-fast); + padding: 0; + line-height: 1; + text-decoration: none; +} + +.tree-toggle:hover { + background: var(--bg-hover); + color: var(--text-primary); + border-color: var(--accent-blue); + text-decoration: none; +} + +.tree-toggle .toggle-icon { + display: block; + color: var(--text-primary); + font-size: 14px; + line-height: 1; +} + +.tree-toggle-spacer { + width: 18px; + flex-shrink: 0; +} + +.tree-item.no-children .tree-toggle { + visibility: hidden; +} + +.tree-icon { + width: 16px; + height: 16px; + flex-shrink: 0; +} + +.tree-icon-folder { + color: var(--accent-blue); +} + +.tree-icon-file { + color: var(--text-muted); +} + +/* Legacy classes */ +.tree-icon.folder { + color: var(--accent-blue); +} + +.tree-icon.file { + color: var(--text-secondary); +} + +.tree-label { + flex: 1; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 13px; + color: var(--text-primary); +} + +.tree-coverage { + font-size: 11px; + font-weight: 600; + padding: 2px 6px; + border-radius: var(--radius-sm); + flex-shrink: 0; +} + +.tree-coverage.coverage-high { + background: var(--coverage-high-bg); +} + +.tree-coverage.coverage-medium { + background: var(--coverage-medium-bg); +} + +.tree-coverage.coverage-low { + background: var(--coverage-low-bg); +} + +.tree-children { + display: none; + margin-left: 20px; + position: relative; +} + +.tree-item.expanded > .tree-children { + display: block; +} + +.tree-children-inner { + /* Animation support */ +} + + +/* =========================================== + Main Content + =========================================== */ + +.main-content { + flex: 1; + margin-left: var(--sidebar-width); + display: flex; + flex-direction: column; + min-height: 100vh; + transition: margin-left var(--transition-normal); +} + +.sidebar.collapsed + .main-content { + margin-left: 0; +} + +.main-header { + position: sticky; + top: 0; + z-index: 50; + display: flex; + align-items: center; + gap: 16px; + padding: 12px 24px; + background: var(--bg-secondary); + border-bottom: 1px solid var(--border-color); + height: var(--header-height); +} + +.sidebar-toggle { + display: flex; + flex-direction: column; + justify-content: center; + gap: 4px; + width: 32px; + height: 32px; + padding: 6px; + background: transparent; + border: none; + border-radius: var(--radius-sm); + cursor: pointer; + transition: background var(--transition-fast); +} + +.sidebar-toggle:hover { + background: var(--bg-hover); +} + +.sidebar-toggle span { + display: block; + height: 2px; + background: var(--text-secondary); + border-radius: 1px; + transition: background var(--transition-fast); +} + +.sidebar-toggle:hover span { + background: var(--text-primary); +} + +.breadcrumb { + display: flex; + align-items: center; + flex-wrap: nowrap; + font-size: 14px; + color: var(--text-secondary); + white-space: nowrap; +} + +.breadcrumb a, +.breadcrumb span { + display: inline; + white-space: nowrap; +} + +.breadcrumb a { + color: var(--text-secondary); +} + +.breadcrumb a:hover { + color: var(--accent-blue); +} + +.breadcrumb .separator { + color: var(--text-muted); + padding: 0 6px; +} + +.breadcrumb .current { + color: var(--text-primary); +} + +.header-actions { + margin-left: auto; +} + +.content-wrapper { + flex: 1; + padding: 24px; + max-width: 1400px; + width: 100%; + margin: 0 auto; +} + +.main-footer { + padding: 24px; + text-align: center; + color: var(--text-muted); + font-size: 12px; + border-top: 1px solid var(--border-color); +} + +.main-footer a { + color: var(--text-muted); +} + +/* =========================================== + Summary Cards + =========================================== */ + +.summary-section { + margin-bottom: 24px; +} + +.summary-cards { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 16px; + margin-bottom: 16px; +} + +.summary-card { + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.summary-card-header { + padding: 12px 16px; + border-bottom: 1px solid var(--border-color); + background: var(--bg-tertiary); +} + +.summary-card-header h3 { + margin: 0; + font-size: 12px; + font-weight: 600; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.summary-card-body { + padding: 16px; + display: flex; + align-items: center; + gap: 16px; +} + +.coverage-ring { + position: relative; + width: 72px; + height: 72px; + flex-shrink: 0; +} + +.coverage-ring svg { + width: 100%; + height: 100%; + transform: rotate(-90deg); +} + +.coverage-ring .ring-bg { + fill: none; + stroke: var(--bg-tertiary); + stroke-width: 3; +} + +.coverage-ring .ring-fill { + fill: none; + stroke: currentColor; + stroke-width: 3; + stroke-linecap: round; + transition: stroke-dasharray var(--transition-normal); +} + +.coverage-ring.coverage-high .ring-fill { stroke: var(--coverage-high); } +.coverage-ring.coverage-medium .ring-fill { stroke: var(--coverage-medium); } +.coverage-ring.coverage-low .ring-fill { stroke: var(--coverage-low); } + +.coverage-ring .ring-text { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 14px; + font-weight: 600; +} + +.summary-stats { + flex: 1; +} + +.stat-row { + display: flex; + justify-content: space-between; + padding: 4px 0; + font-size: 13px; +} + +.stat-row .stat-label { + color: var(--text-secondary); +} + +.stat-row .stat-value { + font-weight: 500; + color: var(--text-primary); +} + +.coverage-legend { + display: flex; + gap: 16px; + flex-wrap: wrap; +} + +.legend-item { + padding: 4px 12px; + border-radius: var(--radius-sm); + font-size: 12px; + font-weight: 500; +} + +.legend-item.coverage-high { + background: var(--coverage-high-bg); + color: var(--coverage-high); +} + +.legend-item.coverage-medium { + background: var(--coverage-medium-bg); + color: var(--coverage-medium); +} + +.legend-item.coverage-low { + background: var(--coverage-low-bg); + color: var(--coverage-low); +} + +/* =========================================== + File List + =========================================== */ + +.file-list-container { + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.file-list-header { + display: grid; + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px 100px 100px; + gap: 8px; + padding: 12px 16px; + background: var(--bg-tertiary); + border-bottom: 1px solid var(--border-color); + font-size: 12px; + font-weight: 600; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.file-list-header > div { + display: flex; + align-items: center; + gap: 4px; +} + +.file-list-header .sortable { + cursor: pointer; + user-select: none; +} + +.file-list-header .sortable:hover { + color: var(--text-primary); +} + +.file-list-header .sorted-ascending::after { + content: ' ↑'; +} + +.file-list-header .sorted-descending::after { + content: ' ↓'; +} + +.file-row { + display: grid; + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px 100px 100px; + gap: 8px; + padding: 4px 16px; + border-bottom: 1px solid var(--border-muted); + align-items: center; + transition: background var(--transition-fast); +} + +.file-row:last-child { + border-bottom: none; +} + +.file-row:hover { + background: var(--bg-hover); +} + +/* Adjust grid when columns are hidden */ +.no-functions.no-branches .file-list-header, +.no-functions.no-branches .file-row { + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px; +} + +.no-functions:not(.no-branches) .file-list-header, +.no-functions:not(.no-branches) .file-row { + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px 100px; +} + +.no-branches:not(.no-functions) .file-list-header, +.no-branches:not(.no-functions) .file-row { + grid-template-columns: minmax(200px, 2fr) minmax(150px, 1fr) 100px 100px; +} + +.file-row:nth-child(even) { + background: rgba(56, 139, 253, 0.03); +} + +.file-row:nth-child(even):hover { + background: var(--bg-hover); +} + +.col-name { + display: flex; + align-items: center; + gap: 8px; + min-width: 0; +} + +.file-icon { + flex-shrink: 0; + color: var(--text-muted); +} + +.file-icon svg { + display: block; +} + +.file-row.directory .file-icon { + color: var(--accent-blue); +} + +.col-name a { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.col-name .no-link { + color: var(--text-secondary); +} + +.col-coverage { + display: flex; + align-items: center; + gap: 12px; +} + +.coverage-bar-container { + flex: 1; + height: 6px; + background: var(--bg-tertiary); + border-radius: 3px; + overflow: hidden; +} + +.coverage-bar { + height: 100%; + border-radius: 3px; + transition: width var(--transition-normal); +} + +.coverage-bar.coverage-high { background: var(--coverage-high); } +.coverage-bar.coverage-medium { background: var(--coverage-medium); } +.coverage-bar.coverage-low { background: var(--coverage-low); } + +.coverage-percent { + font-weight: 600; + font-size: 13px; + min-width: 48px; + text-align: right; +} + +.col-lines, .col-functions, .col-branches { + text-align: right; + font-size: 13px; +} + +.stat-value { + font-weight: 500; +} + +.stat-separator { + color: var(--text-muted); + margin: 0 2px; +} + +.stat-total { + color: var(--text-secondary); +} + +/* =========================================== + Source Code View + =========================================== */ + +.source-summary { + display: flex; + justify-content: space-between; + align-items: flex-start; + flex-wrap: wrap; + gap: 16px; + margin-bottom: 16px; +} + +.source-info h2 { + margin: 0 0 8px 0; + font-size: 18px; + font-weight: 600; + color: var(--text-primary); + font-family: var(--font-mono); +} + +.source-stats { + display: flex; + gap: 16px; + flex-wrap: wrap; +} + +.source-stats .stat { + font-size: 13px; + color: var(--text-secondary); +} + +.source-stats .stat strong { + margin-right: 4px; +} + +.source-controls { + display: flex; + gap: 8px; +} + +.btn { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 8px 12px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + color: var(--text-secondary); + font-size: 13px; + cursor: pointer; + transition: all var(--transition-fast); +} + +.btn:hover { + background: var(--bg-hover); + color: var(--text-primary); +} + +.btn.btn-sm { + padding: 4px 10px; + font-size: 12px; +} + +.btn-count { + font-weight: 600; +} + +.btn-toggle { + text-decoration: line-through; + opacity: 0.6; +} + +.btn-toggle.show_coveredLine, +.btn-toggle.show_uncoveredLine, +.btn-toggle.show_partialCoveredLine, +.btn-toggle.show_excludedLine { + text-decoration: none; + opacity: 1; +} + +.color-dot { + width: 8px; + height: 8px; + border-radius: 50%; +} + +.color-dot.covered { background: var(--coverage-high); } +.color-dot.uncovered { background: var(--coverage-low); } + +.source-container { + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.source-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 16px; + background: var(--bg-tertiary); + border-bottom: 1px solid var(--border-color); + flex-wrap: wrap; + gap: 12px; +} + +.source-title { + font-family: var(--font-mono); + font-size: 13px; + font-weight: 500; + color: var(--text-primary); +} + +.source-actions { + display: flex; + gap: 8px; + flex-wrap: wrap; +} + +.source-table-container { + overflow-x: auto; +} + +.source-table { + width: 100%; + border-collapse: collapse; + font-family: var(--font-mono); + font-size: 12px; + line-height: 1.5; +} + +.source-table thead { + position: sticky; + top: 0; + z-index: 10; +} + +.source-table th { + padding: 8px 12px; + background: var(--bg-tertiary); + color: var(--text-secondary); + font-weight: 600; + text-align: left; + border-bottom: 1px solid var(--border-color); + white-space: nowrap; +} + +.source-table th.col-lineno, +.source-table th.col-count, +.source-table th.col-branch { + text-align: right; +} + +.source-table td { + padding: 0 12px; + vertical-align: top; + border-bottom: 1px solid var(--border-muted); +} + +.source-table .col-lineno { + background: var(--bg-tertiary); + border-right: 1px solid var(--border-color); + text-align: right; + user-select: none; + width: 60px; +} + +.source-table .col-lineno a { + color: var(--text-muted); + text-decoration: none; + display: block; + padding: 2px 0; +} + +.source-table .col-lineno a:hover { + color: var(--accent-blue); +} + +.source-table .col-branch, +.source-table .col-condition, +.source-table .col-decision, +.source-table .col-call { + background: var(--bg-tertiary); + border-right: 1px solid var(--border-color); + text-align: center; + width: 60px; +} + +.source-table .col-count { + text-align: right; + width: 60px; + color: var(--text-muted); +} + +.source-table .col-source { + white-space: pre; + padding-left: 16px; +} + +/* Line coverage highlighting */ +.source-line.coveredLine.show_coveredLine td.col-source, +.source-line.coveredLine.show_coveredLine td.col-count { + background: var(--coverage-high-bg); +} + +.source-line.uncoveredLine.show_uncoveredLine td.col-source, +.source-line.uncoveredLine.show_uncoveredLine td.col-count { + background: var(--coverage-low-bg); +} + +.source-line.partialCoveredLine.show_partialCoveredLine td.col-source, +.source-line.partialCoveredLine.show_partialCoveredLine td.col-count { + background: var(--coverage-medium-bg); +} + +.source-line.excludedLine.show_excludedLine td.col-source, +.source-line.excludedLine.show_excludedLine td.col-count { + background: rgba(110, 118, 129, 0.15); +} + +.hit-miss { + color: var(--coverage-low); + font-weight: bold; +} + +.hit-excluded { + color: var(--text-muted); +} + +/* Branch/condition popup */ +.branch-details, .condition-details, .decision-details, .call-details { + position: relative; +} + +.branch-summary, .condition-summary, .decision-summary, .call-summary { + cursor: pointer; + padding: 2px 4px; + border-radius: var(--radius-sm); +} + +.branch-summary:hover, .condition-summary:hover, .decision-summary:hover, .call-summary:hover { + background: var(--bg-hover); +} + +.branch-popup, .condition-popup, .decision-popup, .call-popup { + position: absolute; + top: 100%; + left: 0; + z-index: 100; + min-width: 250px; + padding: 12px; + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); + font-size: 12px; + line-height: 1.6; +} + +.function-name { + font-weight: 600; + color: var(--accent-blue); + margin-bottom: 4px; +} + +.branch-taken, .condition-covered, .decision-taken, .call-invoked { + color: var(--coverage-high); +} + +.branch-not-taken, .condition-not-covered, .decision-not-taken, .call-not-invoked { + color: var(--coverage-low); +} + +.branch-excluded, .condition-excluded, .decision-uncheckable, .call-excluded { + color: var(--text-muted); +} + +/* =========================================== + Navigation + =========================================== */ + +.nav-links { + display: flex; + gap: 12px; +} + +.nav-link { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 6px 12px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + color: var(--text-secondary); + font-size: 13px; + transition: all var(--transition-fast); +} + +.nav-link:hover { + background: var(--bg-hover); + color: var(--text-primary); + text-decoration: none; +} + +.nav-link svg { + flex-shrink: 0; +} + +/* =========================================== + Functions Page + =========================================== */ + +.summary-inline { + display: flex; + gap: 24px; + flex-wrap: wrap; + padding: 16px; + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + margin-bottom: 24px; +} + +.summary-inline .summary-stat { + display: flex; + align-items: center; + gap: 8px; +} + +.summary-inline .stat-label { + color: var(--text-secondary); + font-size: 13px; +} + +.summary-inline .stat-value { + font-weight: 600; + font-size: 14px; +} + +.summary-inline .stat-detail { + color: var(--text-muted); + font-size: 12px; +} + +.functions-container { + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.functions-header { + display: grid; + grid-template-columns: 2fr 120px 80px 80px; + gap: 16px; + padding: 12px 16px; + background: var(--bg-tertiary); + border-bottom: 1px solid var(--border-color); + font-size: 12px; + font-weight: 600; + color: var(--text-secondary); + text-transform: uppercase; +} + +.function-row { + display: grid; + grid-template-columns: 2fr 120px 80px 80px; + gap: 16px; + padding: 10px 16px; + border-bottom: 1px solid var(--border-muted); + align-items: center; + transition: background var(--transition-fast); +} + +.function-row:hover { + background: var(--bg-hover); +} + +.function-row .col-function a { + display: block; +} + +.function-name { + font-weight: 500; + display: block; +} + +.function-location { + font-size: 11px; + color: var(--text-muted); +} + +.function-row .excluded { + color: var(--text-muted); + font-style: italic; +} + +.function-row .not-called { + color: var(--coverage-low); +} + +.function-row .called { + color: var(--coverage-high); + font-weight: 500; +} + +/* =========================================== + Responsive + =========================================== */ + +@media (max-width: 1024px) { + .sidebar { + transform: translateX(-100%); + } + + .sidebar.open { + transform: translateX(0); + } + + .main-content { + margin-left: 0; + } + + .file-list-header, + .file-row { + grid-template-columns: 1fr 120px 80px; + } + + .col-functions, + .col-branches { + display: none; + } +} + +@media (max-width: 768px) { + .content-wrapper { + padding: 16px; + } + + .summary-cards { + grid-template-columns: 1fr; + } + + .file-list-header, + .file-row { + grid-template-columns: 1fr 100px; + } + + .col-lines { + display: none; + } + + .source-header { + flex-direction: column; + align-items: flex-start; + } +} + +/* =========================================== + Syntax Highlighting (Dark Theme) + =========================================== */ + +/* Dark theme syntax highlighting */ +.c { color: #8b949e; font-style: italic; } /* Comment */ +.k { color: #ff7b72; font-weight: bold; } /* Keyword */ +.o { color: #79c0ff; } /* Operator */ +.cm { color: #8b949e; font-style: italic; } /* Comment.Multiline */ +.cp { color: #d29922; } /* Comment.Preproc */ +.c1 { color: #8b949e; font-style: italic; } /* Comment.Single */ +.cs { color: #8b949e; font-weight: bold; } /* Comment.Special */ +.gd { color: #f85149; } /* Generic.Deleted */ +.gi { color: #3fb950; } /* Generic.Inserted */ +.kc { color: #79c0ff; } /* Keyword.Constant */ +.kd { color: #ff7b72; } /* Keyword.Declaration */ +.kn { color: #ff7b72; } /* Keyword.Namespace */ +.kt { color: #ffa657; } /* Keyword.Type */ +.m { color: #a5d6ff; } /* Literal.Number */ +.s { color: #a5d6ff; } /* Literal.String */ +.na { color: #79c0ff; } /* Name.Attribute */ +.nb { color: #ffa657; } /* Name.Builtin */ +.nc { color: #ffa657; font-weight: bold; } /* Name.Class */ +.nf { color: #d2a8ff; } /* Name.Function */ +.nn { color: #ffa657; } /* Name.Namespace */ +.nt { color: #7ee787; } /* Name.Tag */ +.nv { color: #79c0ff; } /* Name.Variable */ +.ow { color: #ff7b72; font-weight: bold; } /* Operator.Word */ +.s1 { color: #a5d6ff; } /* Literal.String.Single */ +.s2 { color: #a5d6ff; } /* Literal.String.Double */ + +/* Light theme syntax highlighting */ +[data-theme="light"] .c { color: #6e7781; } +[data-theme="light"] .k { color: #cf222e; } +[data-theme="light"] .o { color: #0550ae; } +[data-theme="light"] .cm { color: #6e7781; } +[data-theme="light"] .cp { color: #9a6700; } +[data-theme="light"] .c1 { color: #6e7781; } +[data-theme="light"] .cs { color: #6e7781; } +[data-theme="light"] .gd { color: #cf222e; } +[data-theme="light"] .gi { color: #1a7f37; } +[data-theme="light"] .kc { color: #0550ae; } +[data-theme="light"] .kd { color: #cf222e; } +[data-theme="light"] .kn { color: #cf222e; } +[data-theme="light"] .kt { color: #953800; } +[data-theme="light"] .m { color: #0550ae; } +[data-theme="light"] .s { color: #0a3069; } +[data-theme="light"] .na { color: #0550ae; } +[data-theme="light"] .nb { color: #953800; } +[data-theme="light"] .nc { color: #953800; } +[data-theme="light"] .nf { color: #8250df; } +[data-theme="light"] .nn { color: #953800; } +[data-theme="light"] .nt { color: #1a7f37; } +[data-theme="light"] .nv { color: #0550ae; } +[data-theme="light"] .ow { color: #cf222e; } +[data-theme="light"] .s1 { color: #0a3069; } +[data-theme="light"] .s2 { color: #0a3069; } + +/* =========================================== + Scrollbar + =========================================== */ + +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: var(--bg-primary); +} + +::-webkit-scrollbar-thumb { + background: var(--bg-tertiary); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--bg-hover); +} + +/* Button toggle classes for gcovr compatibility */ +.button_toggle_coveredLine, +.button_toggle_uncoveredLine, +.button_toggle_partialCoveredLine, +.button_toggle_excludedLine { + text-decoration: line-through; + opacity: 0.6; +} + +.button_toggle_coveredLine.show_coveredLine, +.button_toggle_uncoveredLine.show_uncoveredLine, +.button_toggle_partialCoveredLine.show_partialCoveredLine, +.button_toggle_excludedLine.show_excludedLine { + text-decoration: none; + opacity: 1; +}