25#include <daw/daw_algorithm.h>
26#include <daw/daw_attributes.h>
27#include <daw/daw_move.h>
28#include <daw/daw_utility.h>
32#include <daw/stdinc/tuple_traits.h>
40 template<
json_options_t PolicyFlags = json_details::default_policy_flag,
41 typename Allocator = json_details::NoAllocator>
46 std::optional<std::string_view>
name;
50 template<std::
size_t Idx, json_options_t PolicyFlags,
typename Allocator>
51 constexpr decltype( auto )
55 "Invalid index. Valid values are 0 for name, and 1 for value" );
56 if constexpr( Idx == 0 ) {
57 return parse_state.
name;
59 return parse_state.
value;
63 template<std::
size_t Idx, json_options_t PolicyFlags,
typename Allocator>
64 constexpr decltype( auto )
68 "Invalid index. Valid values are 0 for name, and 1 for value" );
69 if constexpr( Idx == 0 ) {
70 return parse_state.
name;
72 return parse_state.
value;
76 template<std::
size_t Idx, json_options_t PolicyFlags,
typename Allocator>
77 constexpr decltype( auto )
81 "Invalid index. Valid values are 0 for name, and 1 for value" );
82 if constexpr( Idx == 0 ) {
83 return std::move( parse_state.
name );
85 return std::move( parse_state.
value );
92 template<daw::json::json_options_t PolicyFlags,
typename Allocator>
93 class tuple_element<0,
daw::json::basic_json_pair<PolicyFlags, Allocator>> {
95 using type = std::optional<std::string_view>;
98 template<daw::json::json_options_t PolicyFlags,
typename Allocator>
99 class tuple_element<1,
daw::json::basic_json_pair<PolicyFlags, Allocator>> {
104 template<daw::json::json_options_t PolicyFlags,
typename Allocator>
105 class tuple_size<
daw::json::basic_json_pair<PolicyFlags, Allocator>> {
107 static constexpr std::size_t value = 2;
116 template<json_options_t PolicyFlags = json_details::default_policy_flag,
117 typename Allocator = json_details::NoAllocator>
125 using pointer = json_details::arrow_proxy<value_type>;
140 : m_state( parse_state ) {}
143 : m_state(
std::data( json_doc ),
daw::data_end( json_doc ) ) {}
146 Allocator
const &alloc )
147 : m_state(
std::data( json_doc ),
daw::data_end( json_doc ),
148 std::data( json_doc ),
daw::data_end( json_doc ), alloc ) {}
152 : m_state( jv.get_raw_state( ) ) {}
156 [[nodiscard]]
constexpr std::optional<std::string_view>
name( )
const {
160 auto parse_state = m_state;
161 auto result = json_details::parse_name( parse_state );
162 return std::string_view( std::data( result ), std::size( result ) );
173 auto parse_state = m_state;
174 (void)json_details::parse_name( parse_state );
179 parse_state.get_allocator( ) );
192 m_state.get_allocator( ) ) ) };
194 auto parse_state = m_state;
195 auto name = json_details::parse_name( parse_state );
197 std::string_view( std::data( name ), std::size( name ) ),
202 parse_state.get_allocator( ) ) ) };
210 return { operator*( ) };
218 (void)json_details::parse_name( m_state );
220 (void)json_details::skip_value( m_state );
221 m_state.move_next_member_or_end( );
234 return *m_state.class_first ==
'[';
240 return *m_state.class_first ==
'{';
245 [[nodiscard]]
constexpr bool good( )
const {
246 if( m_state.is_null( ) or not m_state.has_more( ) ) {
249 switch( m_state.front( ) ) {
273 daw_json_error(
true, ErrorReason::ExpectedTokenNotFound, m_state );
279 [[nodiscard]]
constexpr explicit operator bool( )
const {
292 template<json_options_t P,
typename A>
293 [[nodiscard]]
constexpr bool
297 return m_state.first == rhs.
m_state.first;
301 return not rhs.
good( );
307 template<json_options_t P,
typename A>
308 [[nodiscard]]
constexpr bool
310 return not operator==( rhs );
314 template<json_options_t PolicyFlags,
typename Allocator>
322 template<
typename Allocator>
327 template<json_options_t PolicyFlags,
typename Allocator>
334 template<
json_options_t PolicyFlags = json_details::default_policy_flag,
335 typename Allocator = json_details::NoAllocator>
349 template<json_options_t PolicyFlags,
typename Allocator>
358 template<json_options_t PolicyFlags,
typename Allocator>
372 template<json_options_t P,
typename A>
374 : m_parse_state(
std::move( parse_state ) ) {
376 if( DAW_LIKELY( not m_parse_state.empty( ) ) ) {
377 m_parse_state.trim_left( );
383 : m_parse_state(
std::data( sv ),
daw::data_end( sv ) ) {
384 if( DAW_LIKELY( not m_parse_state.empty( ) ) ) {
385 m_parse_state.trim_left( );
393 first, first ? first + static_cast<
std::ptrdiff_t>( sz ) : first ) {
394 if( DAW_LIKELY( not m_parse_state.empty( ) ) ) {
395 m_parse_state.trim_left( );
402 : m_parse_state( first, last ) {
403 if( DAW_LIKELY( not m_parse_state.empty( ) ) ) {
404 m_parse_state.trim_left( );
411 return m_parse_state;
415 return std::string_view( m_parse_state.first, m_parse_state.size( ) );
422 auto parse_state =
ParseState( m_parse_state.first,
426 m_parse_state.get_allocator( ) );
427 if( DAW_LIKELY( not m_parse_state.empty( ) ) ) {
428 parse_state.remove_prefix( );
429 parse_state.trim_left( );
446 if( type( ) != JsonBaseParseTypes::Class ) {
449 bool const has_escape = name.contains(
'\\' );
452 return daw::algorithm::find_if(
453 begin( ), end( ), [name](
auto const &jp ) {
455 auto f0 = std::data( name );
456 auto const l0 = daw::data_end( name );
457 auto f1 = std::data( *jp.name );
458 auto const l1 = daw::data_end( *jp.name );
459 while( f0 != l0 and f1 != l1 ) {
470 return f0 == l0 and f1 == l1;
473 return daw::algorithm::find_if(
474 begin( ), end( ), [name](
auto const &jp ) {
476 return jp.name == name;
481 if( pos == end( ) ) {
484 return ( *pos ).value;
492 while( not json_path.empty( ) and jv ) {
494 if( json_path.front( ) ==
'[' ) {
495 return json_path.pop_front_until(
']' );
497 return json_path.pop_front_until( escaped_any_of<
'.',
'['>{ },
500 if( not json_path.empty( ) and json_path.front( ) ==
'.' ) {
501 json_path.remove_prefix( );
503 if( member.front( ) ==
'[' ) {
504 member.remove_prefix( );
507 std::data( member ), daw::data_end( member ) )
508 .with_allocator( m_parse_state.get_allocator( ) );
510 json_details::unsigned_parser<std::size_t,
511 options::JsonRangeCheck::Never,
515 if( not json_path.empty( ) and json_path.front( ) ==
'.' ) {
516 json_path.remove_prefix( );
527 template<
typename Result>
528 [[nodiscard]]
constexpr auto as( )
const {
529 using result_t = json_details::json_deduced_type<Result>;
530 auto state = m_parse_state;
531 return json_details::
532 parse_value<result_t, false, result_t::expected_type>( state );
535 template<
typename Result>
536 [[nodiscard]]
explicit operator Result( )
const {
537 return as<Result>( );
546 return find_member( json_path );
554 auto first = begin( );
555 auto const last = end( );
556 while( nsc_and( index > 0, first != last ) ) {
561 return ( *first ).value;
570 assert( type( ) == JsonBaseParseTypes::Array );
571 return find_element( index );
579 return find_element( index );
586 if( m_parse_state.empty( ) ) {
587 return JsonBaseParseTypes::None;
589 switch( m_parse_state.front( ) ) {
591 return JsonBaseParseTypes::String;
593 return JsonBaseParseTypes::Class;
595 return JsonBaseParseTypes::Array;
607 return JsonBaseParseTypes::Number;
609 if constexpr( not ParseState::is_unchecked_input ) {
610 if( m_parse_state.starts_with(
"true" ) ) {
611 return JsonBaseParseTypes::Bool;
613 return JsonBaseParseTypes::None;
615 return JsonBaseParseTypes::Bool;
618 if constexpr( not ParseState::is_unchecked_input ) {
619 if( m_parse_state.starts_with(
"false" ) ) {
620 return JsonBaseParseTypes::Bool;
622 return JsonBaseParseTypes::None;
624 return JsonBaseParseTypes::Bool;
628 ErrorReason::InvalidNull,
630 return JsonBaseParseTypes::Null;
632 return JsonBaseParseTypes::None;
638 auto parse_state = m_parse_state;
639 auto result = json_details::skip_value( parse_state );
651 auto parse_state = m_parse_state;
652 auto result = json_details::skip_value( parse_state );
653 return { std::data( result ), std::size( result ) };
659 template<
typename Alloc = std::allocator<
char>,
660 typename Traits = std::
char_traits<
char>>
661 [[nodiscard]] std::basic_string<char, Traits, Alloc>
663 auto parse_state = m_parse_state;
664 auto result = json_details::skip_value( parse_state );
665 return { std::data( result ), std::size( result ), alloc };
670 [[nodiscard]]
constexpr bool is_null( )
const {
671 return type( ) == JsonBaseParseTypes::Null;
677 return type( ) == JsonBaseParseTypes::Class;
683 return type( ) == JsonBaseParseTypes::Array;
689 return type( ) == JsonBaseParseTypes::Number;
695 return type( ) == JsonBaseParseTypes::String;
700 [[nodiscard]]
constexpr bool is_bool( )
const {
701 return type( ) == JsonBaseParseTypes::Bool;
709 return type( ) == JsonBaseParseTypes::None;
713 template<json_options_t P,
typename A>
714 [[nodiscard]]
constexpr
718 new_range.class_first = m_parse_state.class_first;
719 new_range.class_last = m_parse_state.class_last;
724 [[nodiscard]]
explicit constexpr operator bool( )
const {
725 return type( ) != JsonBaseParseTypes::None;
729 template<json_options_t PolicyFlags,
typename Allocator>
740 template<
typename Result, json_options_t PolicyFlags,
typename Allocator>
741 [[nodiscard]]
constexpr Result
743 return jv.template as<Result>( );
746 namespace json_details {
749 inline constexpr bool is_json_value =
false;
751 template<json_options_t PolicyFlags,
typename Allocator>
752 inline constexpr bool
753 is_json_value<basic_json_value<PolicyFlags, Allocator>> =
true;
755 template<json_options_t PolicyFlags,
typename Allocator>
756 inline constexpr bool
757 is_string_view_like_v<basic_json_value<PolicyFlags, Allocator>> =
false;
std::optional< std::string_view > type
#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_ATTRIB_NOINLINE void daw_json_error(bool b, ErrorReason reason)
JsonBaseParseTypes
The fundamental JSON types.
std::uint32_t json_options_t
daw::conditional_t< ParsePolicy::is_default_parse_policy, DefaultParsePolicy, ParsePolicy > TryDefaultParsePolicy
constexpr Result as(basic_json_value< PolicyFlags, Allocator > const &jv)
constexpr decltype(auto) get(basic_json_pair< PolicyFlags, Allocator > const &parse_state)
string_writer grows its string with resize_and_overwrite, leaving the new bytes uninitialized,...
Handles the bounds and policy items for parsing execution and comments.
A name/value pair of string_view/json_value.
basic_json_value< PolicyFlags, Allocator > value
TryDefaultParsePolicy< BasicParsePolicy< PolicyFlags, Allocator > > ParseState
std::optional< std::string_view > name
a rudimentary range object for holding basic_json_value_iterator
constexpr iterator begin()
Iterator for iterating over arbitrary JSON members and array elements.
constexpr pointer operator->()
Return an arrow_proxy object containing the result of operator* Should not use this method unless you...
constexpr void operator++(int) &
Move parser to next value.
constexpr std::optional< std::string_view > name() const
Name of member.
constexpr basic_json_value_iterator(parse_policy const &parse_state)
constexpr parse_policy const & get_raw_state() const
Get access to the internal state. Should not be used as part of public API.
TryDefaultParsePolicy< BasicParsePolicy< PolicyFlags, Allocator > > parse_policy
basic_json_value_iterator()=default
basic_json_value_iterator(daw::string_view json_doc)
constexpr basic_json_value< PolicyFlags, Allocator > value() const
Get the value currently being referenced.
std::forward_iterator_tag iterator_category
constexpr basic_json_value_iterator & operator++()
Move the parser to the next value.
std::string_view key_type
std::ptrdiff_t difference_type
constexpr bool is_class() const
Is the value this iterator iterates over an class.
constexpr bool is_array() const
Is the value this iterator iterates over an array.
constexpr bool good() const
Can we increment more.
json_details::arrow_proxy< value_type > pointer
constexpr bool operator==(basic_json_value_iterator< P, A > const &rhs) const
Check for equivalence with rhs iterator.
basic_json_value_iterator(daw::string_view json_doc, Allocator const &alloc)
basic_json_value_iterator(basic_json_value< PolicyFlags, Allocator > const &jv)
constexpr basic_json_pair< PolicyFlags, Allocator > operator*()
Get the name/value pair of the currently referenced element.
constexpr bool operator!=(basic_json_value_iterator< P, A > const &rhs) const
Check if rhs is not equivalent to self.
A non-owning container for arbitrary JSON values that allows movement/iteration through.
constexpr bool is_null() const
Is the JSON value a null literal.
constexpr bool is_class() const
Is the JSON value a class.
constexpr std::string_view get_string_view() const
Construct a string range of the current value. Strings start inside the quotes.
constexpr std::string_view get_raw_json_document() const
constexpr bool is_bool() const
Is the JSON value a boolean.
constexpr iterator end() const
End of range over class/arrays members/items.
std::ptrdiff_t difference_type
constexpr basic_json_value operator[](daw::string_view json_path) const
Query the current class for a named member.
TryDefaultParsePolicy< BasicParsePolicy< PolicyFlags, Allocator > > ParseState
constexpr ParseState get_state() const
Construct a string range of the current value.
constexpr basic_json_value(daw::string_view sv)
Construct from string_view.
constexpr basic_json_value(char const *first DAW_LIFETIME_BOUND, std::size_t sz)
Construct from char const *, std::size_t.
constexpr auto as() const
Parse the current json member as a Result. The Result type must be supported or mapped via a json_dat...
constexpr basic_json_value find_array_element(std::size_t index) const
Find the nth element of the current json array.
constexpr iterator begin() const
Get the first member/item.
constexpr basic_json_value find_element(std::size_t index) const
Find the nth element/submember of the current json array or class.
constexpr basic_json_value find_member(daw::string_view json_path) const
find a class member/array element as specified by the json_path
constexpr bool is_array() const
Is the JSON value a array.
constexpr bool is_string() const
Is the JSON value a string.
constexpr bool is_number() const
Is the JSON value a number literal.
constexpr ParseState get_raw_state() const
Get a copy of the underlying parse state.
std::basic_string< char, Traits, Alloc > get_string(Alloc const &alloc=Alloc()) const
Construct a string range of the current value. Strings start inside the quotes.
basic_json_value()=default
constexpr basic_json_value(BasicParsePolicy< P, A > parse_state)
Construct from IteratorRange.
constexpr bool is_unknown() const
Is the JSON data unrecognizable. JSON members will start with one of ",[,{,0,1,2,3,...
constexpr basic_json_value(char const *first DAW_LIFETIME_BOUND, char const *last)
Construct from char const *, char const *.
constexpr JsonBaseParseTypes type() const
Get the type of JSON value.
constexpr basic_json_value operator[](std::size_t index) const
Find the nth element/submember of the current json array or class.
constexpr basic_json_value find_class_member(daw::string_view name) const
Query the current class for a named member.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.