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