19#include <daw/daw_arith_traits.h>
20#include <daw/daw_enable_requires.h>
21#include <daw/daw_move.h>
22#include <daw/daw_string_view.h>
23#include <daw/daw_uint_buffer.h>
32 namespace json_details {
34 typename Allocator = NoAllocator>
35 class basic_stateful_json_value_state {
40 daw::string_view name;
44 explicit constexpr basic_stateful_json_value_state(
45 daw::string_view Name,
49 daw::name_hash<ParseState::expect_long_strings>( Name ) )
50 , location( std::move( val ) ) {}
52 [[nodiscard]]
constexpr bool is_match( daw::string_view Name )
const {
56 [[nodiscard]]
constexpr bool is_match( daw::string_view Name,
58 if( hash != hash_value ) {
71 : name(
std::data( Name ),
std::size( Name ) )
72 , hash_value(
daw::name_hash<false>( name ) ) {}
80 template<
json_options_t PolicyFlags = json_details::default_policy_flag,
81 typename Allocator = json_details::NoAllocator>
88 json_details::basic_stateful_json_value_state<PolicyFlags, Allocator>>
98 std::size_t
const Sz = std::size( m_locs );
99 for( ; pos < Sz; ++pos ) {
106 if( m_locs.empty( ) ) {
107 return m_value.
begin( );
109 auto res = m_locs.back( ).location;
113 auto const last = m_value.
end( );
114 while( it != last ) {
115 auto name = it.
name( );
117 auto const &new_loc = m_locs.emplace_back(
118 daw::string_view( std::data( *name ), std::size( *name ) ), it );
119 if( new_loc.is_match( member.
name ) ) {
125 return std::size( m_locs );
133 [[nodiscard]]
constexpr std::size_t
move_to( std::size_t index ) {
134 if( index < std::size( m_locs ) ) {
138 if( m_locs.empty( ) ) {
139 return m_value.
begin( );
141 auto res = m_locs.back( ).location;
145 auto last = m_value.
end( );
146 std::size_t pos = std::size( m_locs );
147 while( it != last ) {
148 auto name = it.name( );
151 daw::string_view( std::data( *name ), std::size( *name ) ), it );
153 m_locs.emplace_back( daw::string_view( ), it );
161 return std::size( m_locs );
167 : m_value(
std::move( val ) ) {
170 auto t = m_value.
type( );
171 return ( t == JsonBaseParseTypes::Class ) |
172 ( t == JsonBaseParseTypes::Array );
174 ErrorReason::ExpectedArrayOrClassStart,
191 m_value = std::move( val );
204 ErrorReason::UnknownMember );
205 return m_locs[pos].location->value;
215 std::size_t pos = move_to( member );
217 ErrorReason::UnknownMember );
218 return m_locs[pos].location->value;
227 at( std::string_view key ) {
228 auto const k = std::string_view( std::data( key ), std::size( key ) );
229 std::size_t pos = move_to( k );
230 if( pos < std::size( m_locs ) ) {
231 return m_locs[pos].location->value;
241 [[nodiscard]] std::size_t
size( ) {
243 switch( current_type ) {
244 case JsonBaseParseTypes::Array:
245 case JsonBaseParseTypes::Class:
246 return move_to( daw::max_value<std::size_t> );
247 case JsonBaseParseTypes::Number:
248 case JsonBaseParseTypes::Bool:
249 case JsonBaseParseTypes::String:
250 case JsonBaseParseTypes::Null:
251 case JsonBaseParseTypes::None:
263 [[nodiscard]] std::size_t
index_of( std::string_view key ) {
273 [[nodiscard]]
constexpr bool contains( std::string_view key ) {
274 auto const k = std::string_view( std::data( key ), std::size( key ) );
275 return move_to( k ) < std::size( m_locs );
284 [[nodiscard]]
constexpr bool contains( std::size_t index ) {
285 return move_to( index ) < size( m_locs );
295 template<
typename Integer>
296 [[nodiscard]] std::optional<std::string_view>
name_of( Integer index ) {
297 static_assert( std::is_integral_v<Integer>,
298 "Only integer indices are allowed" );
299 if constexpr( std::is_signed_v<Integer> ) {
303 if(
static_cast<std::size_t
>( index ) >= sz ) {
306 sz -=
static_cast<std::size_t
>( index );
307 return std::string_view( std::data( m_locs[sz].name( ) ),
308 std::size( m_locs[sz].name( ) ) );
311 std::size_t pos = move_to(
static_cast<std::size_t
>( index ) );
312 if( pos < std::size( m_locs ) ) {
313 return std::string_view( std::data( m_locs[pos].name( ) ),
314 std::size( m_locs[pos].name( ) ) );
327 template<
typename Integer DAW_ENABLEIF( std::is_
integral_v<Integer> )>
331 if constexpr( std::is_signed_v<Integer> ) {
336 ErrorReason::UnknownMember );
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 ) );
343 ErrorReason::UnknownMember );
344 return m_locs[pos].location->value;
354 template<
typename Integer DAW_ENABLEIF( std::is_
integral_v<Integer> )>
356 [[nodiscard]]
constexpr std::optional<
358 if constexpr( std::is_signed_v<Integer> ) {
362 if(
static_cast<std::size_t
>( index ) >= sz ) {
365 sz -=
static_cast<std::size_t
>( index );
366 return m_locs[sz].location->value( );
369 std::size_t pos = move_to(
static_cast<std::size_t
>( index ) );
370 if( pos < std::size( m_locs ) ) {
371 return m_locs[pos].location->value( );
387 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.