17 #include <daw/daw_uint_buffer.h>
21 #include <string_view>
26 namespace json_details {
27 template<
typename Range>
28 struct basic_stateful_json_value_state {
29 daw::string_view name;
30 daw::UInt32 hash_value;
31 basic_json_value_iterator<Range> location;
33 explicit constexpr basic_stateful_json_value_state(
34 daw::string_view Name, basic_json_value_iterator<Range> val )
37 , location( std::move( val ) ) {}
39 [[nodiscard]] constexpr
bool is_match( daw::string_view Name )
const {
43 [[nodiscard]] constexpr
bool is_match( daw::string_view Name,
44 daw::UInt32 hash )
const {
45 if( hash != hash_value ) {
58 :
name( Name.data( ), Name.size( ) )
67 template<
typename Range>
70 std::vector<json_details::basic_stateful_json_value_state<Range>> m_locs{ };
79 for( ; pos < m_locs.size( ); ++pos ) {
86 if( m_locs.empty( ) ) {
87 return m_value.
begin( );
89 auto res = m_locs.back( ).location;
93 auto const last = m_value.
end( );
95 auto name = it.name( );
97 auto const &new_loc = m_locs.emplace_back(
98 daw::string_view( name->data( ), name->size( ) ), it );
99 if( new_loc.is_match( member.
name ) ) {
105 return m_locs.size( );
113 [[nodiscard]] constexpr std::size_t move_to( std::size_t index ) {
114 if( index < m_locs.size( ) ) {
118 if( m_locs.empty( ) ) {
119 return m_value.
begin( );
121 auto res = m_locs.back( ).location;
125 auto last = m_value.
end( );
126 std::size_t pos = m_locs.size( );
127 while( it != last ) {
128 auto name = it.name( );
130 m_locs.emplace_back( daw::string_view( name->data( ), name->size( ) ),
133 m_locs.emplace_back( daw::string_view( ), it );
141 return m_locs.size( );
146 : m_value( std::move( val ) ) {
149 auto t = m_value.
type( );
150 return ( t == JsonBaseParseTypes::Class ) |
151 ( t == JsonBaseParseTypes::Array );
153 ErrorReason::ExpectedArrayOrClassStart,
167 m_value = std::move( val );
181 return m_locs[pos].location->value;
192 std::size_t pos = move_to( member );
194 return m_locs[pos].location->value;
205 daw::string_view
const k = daw::string_view( key.data( ), key.size( ) );
206 std::size_t pos = move_to( k );
207 if( pos < m_locs.size( ) ) {
208 return m_locs[pos].location->value;
219 [[nodiscard]] std::size_t
size( ) {
221 switch( current_type ) {
222 case JsonBaseParseTypes::Array:
223 case JsonBaseParseTypes::Class:
224 return move_to( daw::numeric_limits<std::size_t>::max( ) );
236 [[nodiscard]] std::size_t
index_of( std::string_view key ) {
237 daw::string_view
const k = daw::string_view( key.data( ), key.size( ) );
247 [[nodiscard]] constexpr
bool contains( std::string_view key ) {
248 daw::string_view
const k = daw::string_view( key.data( ), key.size( ) );
249 return move_to( k ) < m_locs.size( );
258 [[nodiscard]] constexpr
bool contains( std::size_t index ) {
259 return move_to( index ) < m_locs.size( );
269 template<
typename Integer, std::enable_if_t<std::is_
integral_v<Integer>,
270 std::
nullptr_t> =
nullptr>
271 [[nodiscard]] std::optional<std::string_view>
name_of( Integer index ) {
272 if constexpr( std::is_signed_v<Integer> ) {
276 if(
static_cast<std::size_t
>( index ) >= sz ) {
279 sz -=
static_cast<std::size_t
>( index );
280 return std::string_view( m_locs[sz].name( ).data( ),
281 m_locs[sz].name( ).
size( ) );
284 std::size_t pos = move_to(
static_cast<std::size_t
>( index ) );
285 if( pos < m_locs.size( ) ) {
286 return std::string_view( m_locs[pos].name( ).data( ),
287 m_locs[pos].name( ).
size( ) );
300 template<
typename Integer, std::enable_if_t<std::is_
integral_v<Integer>,
301 std::
nullptr_t> =
nullptr>
304 if constexpr( std::is_signed_v<Integer> ) {
309 ErrorReason::UnknownMember );
310 sz -=
static_cast<std::size_t
>( index );
311 return m_locs[sz].location->value;
314 std::size_t pos = move_to(
static_cast<std::size_t
>( index ) );
316 return m_locs[pos].location->value;
326 template<
typename Integer, std::enable_if_t<std::is_
integral_v<Integer>,
327 std::
nullptr_t> =
nullptr>
328 [[nodiscard]] constexpr std::optional<basic_json_value<Range>>
329 at( Integer index ) {
330 if constexpr( std::is_signed_v<Integer> ) {
334 if(
static_cast<std::size_t
>( index ) >= sz ) {
337 sz -=
static_cast<std::size_t
>( index );
338 return m_locs[sz].location->value;
341 std::size_t pos = move_to(
static_cast<std::size_t
>( index ) );
342 if( pos < m_locs.size( ) ) {
343 return m_locs[pos].location->value;