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