19#include <daw/daw_enable_requires.h>
20#include <daw/daw_move.h>
21#include <daw/daw_string_view.h>
22#include <daw/daw_uint_buffer.h>
31 namespace json_details {
33 typename Allocator = NoAllocator>
34 class basic_stateful_json_value_state {
39 daw::string_view name;
43 explicit constexpr basic_stateful_json_value_state(
44 daw::string_view Name,
48 daw::name_hash<ParseState::expect_long_strings>( Name ) )
49 , location( std::move( val ) ) {}
51 [[nodiscard]]
constexpr bool is_match( daw::string_view Name )
const {
55 [[nodiscard]]
constexpr bool is_match( daw::string_view Name,
57 if( hash != hash_value ) {
70 : name(
std::data( Name ),
std::size( Name ) )
71 , hash_value(
daw::name_hash<false>( name ) ) {}
79 template<
json_options_t PolicyFlags = json_details::default_policy_flag,
80 typename Allocator = json_details::NoAllocator>
87 json_details::basic_stateful_json_value_state<PolicyFlags, Allocator>>
97 std::size_t
const Sz = std::size( m_locs );
98 for( ; pos < Sz; ++pos ) {
105 if( m_locs.empty( ) ) {
106 return m_value.
begin( );
108 auto res = m_locs.back( ).location;
112 auto const last = m_value.
end( );
113 while( it != last ) {
114 auto name = it.
name( );
116 auto const &new_loc = m_locs.emplace_back(
117 daw::string_view( std::data( *name ), std::size( *name ) ), it );
118 if( new_loc.is_match( member.
name ) ) {
124 return std::size( m_locs );
132 [[nodiscard]]
constexpr std::size_t
move_to( std::size_t index ) {
133 if( index < std::size( m_locs ) ) {
137 if( m_locs.empty( ) ) {
138 return m_value.
begin( );
140 auto res = m_locs.back( ).location;
144 auto last = m_value.
end( );
145 std::size_t pos = std::size( m_locs );
146 while( it != last ) {
147 auto name = it.name( );
150 daw::string_view( std::data( *name ), std::size( *name ) ), it );
152 m_locs.emplace_back( daw::string_view( ), it );
160 return std::size( m_locs );
166 : m_value(
std::move( val ) ) {
169 auto t = m_value.
type( );
170 return ( t == JsonBaseParseTypes::Class ) |
171 ( t == JsonBaseParseTypes::Array );
173 ErrorReason::ExpectedArrayOrClassStart,
190 m_value = std::move( val );
203 ErrorReason::UnknownMember );
204 return m_locs[pos].location->value;
214 std::size_t pos = move_to( member );
216 ErrorReason::UnknownMember );
217 return m_locs[pos].location->value;
226 at( std::string_view key ) {
227 auto const k = std::string_view( std::data( key ), std::size( key ) );
228 std::size_t pos = move_to( k );
229 if( pos < std::size( m_locs ) ) {
230 return m_locs[pos].location->value;
240 [[nodiscard]] std::size_t
size( ) {
242 switch( current_type ) {
243 case JsonBaseParseTypes::Array:
244 case JsonBaseParseTypes::Class:
245 return move_to( ( daw::numeric_limits<std::size_t>::max )( ) );
246 case JsonBaseParseTypes::Number:
247 case JsonBaseParseTypes::Bool:
248 case JsonBaseParseTypes::String:
249 case JsonBaseParseTypes::Null:
250 case JsonBaseParseTypes::None:
262 [[nodiscard]] std::size_t
index_of( std::string_view key ) {
272 [[nodiscard]]
constexpr bool contains( std::string_view key ) {
273 auto const k = std::string_view( std::data( key ), std::size( key ) );
274 return move_to( k ) < std::size( m_locs );
283 [[nodiscard]]
constexpr bool contains( std::size_t index ) {
284 return move_to( index ) < size( m_locs );
294 template<
typename Integer>
295 [[nodiscard]] std::optional<std::string_view>
name_of( Integer index ) {
296 static_assert( std::is_integral_v<Integer>,
297 "Only integer indices are allowed" );
298 if constexpr( std::is_signed_v<Integer> ) {
302 if(
static_cast<std::size_t
>( index ) >= sz ) {
305 sz -=
static_cast<std::size_t
>( index );
306 return std::string_view( std::data( m_locs[sz].name( ) ),
307 std::size( m_locs[sz].name( ) ) );
310 std::size_t pos = move_to(
static_cast<std::size_t
>( index ) );
311 if( pos < std::size( m_locs ) ) {
312 return std::string_view( std::data( m_locs[pos].name( ) ),
313 std::size( m_locs[pos].name( ) ) );
326 template<
typename Integer DAW_ENABLEIF( std::is_
integral_v<Integer> )>
330 if constexpr( std::is_signed_v<Integer> ) {
335 ErrorReason::UnknownMember );
336 sz -=
static_cast<std::size_t
>( index );
337 return m_locs[sz].location->value;
340 std::size_t pos = move_to(
static_cast<std::size_t
>( index ) );
342 ErrorReason::UnknownMember );
343 return m_locs[pos].location->value;
353 template<
typename Integer DAW_ENABLEIF( std::is_
integral_v<Integer> )>
355 [[nodiscard]]
constexpr std::optional<
357 if constexpr( std::is_signed_v<Integer> ) {
361 if(
static_cast<std::size_t
>( index ) >= sz ) {
364 sz -=
static_cast<std::size_t
>( index );
365 return m_locs[sz].location->value( );
368 std::size_t pos = move_to(
static_cast<std::size_t
>( index ) );
369 if( pos < std::size( m_locs ) ) {
370 return m_locs[pos].location->value( );
386 template<json_options_t PolicyFlags,
typename Allocator>
constexpr bool contains(std::string_view key)
Is the named member present. This method is O(N) worst case and O(1) if the locations have already.
constexpr basic_json_value< PolicyFlags, Allocator > at(std::string_view key)
Create a basic_json_member for the named member.
std::size_t index_of(std::string_view key)
Return the index of named member. This method is O(N) worst case and O(1) if the locations have alrea...
constexpr std::size_t move_to(std::size_t index)
constexpr basic_json_value< PolicyFlags, Allocator > get_json_value() const
constexpr std::size_t move_to(json_member_name member)
basic_json_value< PolicyFlags, Allocator > m_value
constexpr basic_json_value< PolicyFlags, Allocator > operator[](Integer index)
std::optional< std::string_view > name_of(Integer index)
constexpr basic_stateful_json_value()
constexpr basic_stateful_json_value(daw::string_view json_data)
std::size_t size()
Count the number of elements/members in the JSON class or array This method is O(N) worst case and O(...
constexpr std::optional< basic_json_value< PolicyFlags, Allocator > > at(Integer index)
constexpr basic_json_value< PolicyFlags, Allocator > operator[](json_member_name member)
Create a basic_json_member for the named member.
TryDefaultParsePolicy< BasicParsePolicy< PolicyFlags, Allocator > > ParseState
constexpr basic_stateful_json_value(basic_json_value< PolicyFlags, Allocator > val)
constexpr bool contains(std::size_t index)
constexpr basic_json_value< PolicyFlags, Allocator > operator[](std::string_view key)
Create a basic_json_member for the named member.
constexpr void reset(basic_json_value< PolicyFlags, Allocator > val)
#define daw_json_assert_weak(Bool,...)
Assert that Bool is true when in Checked Input mode If false pass rest of args to daw_json_error.
DAW_REQUIRES(daw::json::json_details::is_container_opted_into_json_iostreams_v< Container >) std
An opt in ostream interface for containers of types that have JSON mappings.
JsonBaseParseTypes
The fundamental JSON types.
std::uint32_t json_options_t
daw::conditional_t< ParsePolicy::is_default_parse_policy, DefaultParsePolicy, ParsePolicy > TryDefaultParsePolicy
Customization point traits.
daw::UInt64 json_name_hash_t
Iterator for iterating over arbitrary JSON members and array elements.
constexpr std::optional< std::string_view > name() const
Name of member.
A non-owning container for arbitrary JSON values that allows movement/iteration through.
constexpr iterator end() const
End of range over class/arrays members/items.
constexpr iterator begin() const
Get the first member/item.
constexpr ParseState get_raw_state() const
Get a copy of the underlying parse state.
constexpr JsonBaseParseTypes type() const
Get the type of JSON value.
json_name_hash_t hash_value
constexpr json_member_name(std::string_view Name)
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.