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