24 #include <daw/daw_algorithm.h>
25 #include <daw/daw_move.h>
26 #include <daw/daw_utility.h>
30 #include <daw/stdinc/tuple_traits.h>
32 #include <string_view>
38 template<
json_options_t PolicyFlags = json_details::default_policy_flag,
39 typename Allocator = json_details::NoAllocator>
44 std::optional<std::string_view>
name;
48 template<std::
size_t Idx, json_options_t PolicyFlags,
typename Allocator>
49 constexpr decltype(
auto )
53 "Invalid index. Valid values are 0 for name, and 1 for value" );
54 if constexpr( Idx == 0 ) {
55 return parse_state.name;
57 return parse_state.value;
61 template<std::
size_t Idx, json_options_t PolicyFlags,
typename Allocator>
62 constexpr decltype(
auto )
66 "Invalid index. Valid values are 0 for name, and 1 for value" );
67 if constexpr( Idx == 0 ) {
68 return parse_state.name;
70 return parse_state.value;
74 template<std::
size_t Idx, json_options_t PolicyFlags,
typename Allocator>
75 constexpr decltype(
auto )
79 "Invalid index. Valid values are 0 for name, and 1 for value" );
80 if constexpr( Idx == 0 ) {
81 return std::move( parse_state.name );
83 return std::move( parse_state.value );
90 template<daw::json::json_options_t PolicyFlags,
typename Allocator>
91 class tuple_element<0,
daw::json::basic_json_pair<PolicyFlags, Allocator>> {
93 using type = std::optional<std::string_view>;
96 template<daw::json::json_options_t PolicyFlags,
typename Allocator>
97 class tuple_element<1,
daw::json::basic_json_pair<PolicyFlags, Allocator>> {
102 template<daw::json::json_options_t PolicyFlags,
typename Allocator>
103 class tuple_size<
daw::json::basic_json_pair<PolicyFlags, Allocator>>
104 :
public std::integral_constant<std::size_t, 2> {};
112 template<
json_options_t PolicyFlags = json_details::default_policy_flag,
113 typename Allocator = json_details::NoAllocator>
121 using pointer = json_details::arrow_proxy<value_type>;
136 : m_state( parse_state ) {}
139 : m_state(
std::data( json_doc ),
daw::data_end( json_doc ) ) {}
142 Allocator
const &alloc )
143 : m_state(
std::data( json_doc ),
daw::data_end( json_doc ),
144 std::data( json_doc ),
daw::data_end( json_doc ), alloc ) {}
148 : m_state( jv.get_raw_state( ) ) {}
152 [[nodiscard]] constexpr std::optional<std::string_view> name( )
const {
156 auto parse_state = m_state;
157 auto result = json_details::parse_name( parse_state );
158 return std::string_view( std::data( result ), std::size( result ) );
169 auto parse_state = m_state;
170 (void)json_details::parse_name( parse_state );
171 return ParseState( parse_state.first, parse_state.last,
172 parse_state.first, parse_state.last,
173 parse_state.get_allocator( ) );
183 m_state.first, m_state.last,
184 m_state.get_allocator( ) ) ) };
186 auto parse_state = m_state;
187 auto name = json_details::parse_name( parse_state );
188 return { std::string_view( std::data( name ), std::size( name ) ),
190 parse_state.first, parse_state.last, parse_state.first,
191 parse_state.last, parse_state.get_allocator( ) ) ) };
198 [[nodiscard]] constexpr
pointer operator->( ) {
199 return { operator*( ) };
207 (void)json_details::parse_name( m_state );
209 (void)json_details::skip_value( m_state );
210 m_state.move_next_member_or_end( );
216 inline constexpr
void operator++(
int ) & {
222 [[nodiscard]] constexpr
bool is_array( )
const {
223 return *m_state.class_first ==
'[';
228 [[nodiscard]] constexpr
bool is_class( )
const {
229 return *m_state.class_first ==
'{';
234 [[nodiscard]] constexpr
bool good( )
const {
235 if( not m_state.has_more( ) or m_state.is_null( ) ) {
238 switch( m_state.front( ) ) {
268 [[nodiscard]] constexpr
explicit operator bool( )
const {
281 template<json_options_t P,
typename A>
282 [[nodiscard]] constexpr
bool
286 return m_state.first == rhs.
m_state.first;
290 return not rhs.
good( );
296 template<json_options_t P,
typename A>
297 [[nodiscard]] constexpr
bool
299 return not operator==( rhs );
303 template<json_options_t PolicyFlags,
typename Allocator>
311 template<
typename Allocator>
316 template<json_options_t PolicyFlags,
typename Allocator>
323 template<
json_options_t PolicyFlags = json_details::default_policy_flag,
324 typename Allocator = json_details::NoAllocator>
339 template<json_options_t PolicyFlags,
typename Allocator>
348 template<json_options_t PolicyFlags,
typename Allocator>
353 using CharT =
typename ParseState::CharT;
363 template<json_options_t P,
typename A>
366 : m_parse_state(
std::move( parse_state ) ) {
368 m_parse_state.trim_left( );
373 : m_parse_state(
std::data( sv ),
daw::data_end( sv ) ) {
374 m_parse_state.trim_left( );
379 : m_parse_state( first, first + static_cast<
std::ptrdiff_t>( sz ) ) {
380 m_parse_state.trim_left( );
385 : m_parse_state( first, last ) {
386 m_parse_state.trim_left( );
391 [[nodiscard]]
inline constexpr
ParseState get_raw_state( )
const {
392 return m_parse_state;
395 [[nodiscard]]
inline constexpr std::string_view
397 return std::string_view( m_parse_state.first, m_parse_state.size( ) );
403 [[nodiscard]]
inline constexpr
iterator begin( )
const {
404 auto parse_state =
ParseState( m_parse_state.first, m_parse_state.last,
405 m_parse_state.first, m_parse_state.last,
406 m_parse_state.get_allocator( ) );
407 parse_state.remove_prefix( );
408 parse_state.trim_left( );
414 [[nodiscard]]
inline constexpr
iterator end( )
const {
424 if( type( ) != JsonBaseParseTypes::Class ) {
427 bool const has_escape = name.contains(
'\\' );
430 return daw::algorithm::find_if(
431 begin( ), end( ), [name](
auto const &jp ) {
433 auto f0 = std::data( name );
434 auto const l0 = daw::data_end( name );
435 auto f1 = std::data( *jp.name );
436 auto const l1 = daw::data_end( *jp.name );
437 while( f0 != l0 and f1 != l1 ) {
448 return f0 == l0 and f1 == l1;
451 return daw::algorithm::find_if( begin( ), end( ),
452 [name](
auto const &jp ) {
454 return jp.name == name;
459 if( pos == end( ) ) {
462 return ( *pos ).value;
470 while( not json_path.empty( ) and jv ) {
472 if( json_path.front( ) ==
'[' ) {
473 return json_path.pop_front_until(
']' );
475 return json_path.pop_front_until( escaped_any_of<
'.',
'['>{ },
478 if( not json_path.empty( ) and json_path.front( ) ==
'.' ) {
479 json_path.remove_prefix( );
481 if( member.front( ) ==
'[' ) {
482 member.remove_prefix( );
485 std::data( member ), daw::data_end( member ) )
486 .with_allocator( m_parse_state.get_allocator( ) );
487 auto const index = json_details::unsigned_parser<
488 std::size_t, options::JsonRangeCheck::Never,
true>(
492 if( not json_path.empty( ) and json_path.front( ) ==
'.' ) {
493 json_path.remove_prefix( );
504 template<
typename Result>
505 [[nodiscard]] constexpr
auto as( )
const {
506 using result_t = json_details::json_deduced_type<Result>;
507 auto state = m_parse_state;
508 return json_details::parse_value<result_t,
false,
509 result_t::expected_type>( state );
512 template<
typename Result>
513 [[nodiscard]]
explicit operator Result( )
const {
514 return as<Result>( );
523 return find_member( json_path );
531 auto first = begin( );
532 auto const last = end( );
533 while( nsc_and( index > 0, first != last ) ) {
538 return ( *first ).value;
547 assert( type( ) == JsonBaseParseTypes::Array );
548 return find_element( index );
556 return find_element( index );
563 if( not m_parse_state.has_more( ) ) {
564 return JsonBaseParseTypes::None;
566 switch( m_parse_state.front( ) ) {
568 return JsonBaseParseTypes::String;
570 return JsonBaseParseTypes::Class;
572 return JsonBaseParseTypes::Array;
584 return JsonBaseParseTypes::Number;
586 if constexpr( not ParseState::is_unchecked_input ) {
587 if( m_parse_state.starts_with(
"true" ) ) {
588 return JsonBaseParseTypes::Bool;
590 return JsonBaseParseTypes::None;
592 return JsonBaseParseTypes::Bool;
595 if constexpr( not ParseState::is_unchecked_input ) {
596 if( m_parse_state.starts_with(
"false" ) ) {
597 return JsonBaseParseTypes::Bool;
599 return JsonBaseParseTypes::None;
601 return JsonBaseParseTypes::Bool;
605 ErrorReason::InvalidNull, m_parse_state );
606 return JsonBaseParseTypes::Null;
608 return JsonBaseParseTypes::None;
614 auto parse_state = m_parse_state;
615 auto result = json_details::skip_value( parse_state );
626 [[nodiscard]] constexpr std::string_view get_string_view( )
const {
627 auto parse_state = m_parse_state;
628 auto result = json_details::skip_value( parse_state );
629 return { std::data( result ), std::size( result ) };
635 template<
typename Alloc = std::allocator<
char>,
636 typename Traits = std::
char_traits<
char>>
637 [[nodiscard]] std::basic_string<char, Traits, Alloc>
639 auto parse_state = m_parse_state;
640 auto result = json_details::skip_value( parse_state );
641 return { std::data( result ), std::size( result ), alloc };
646 [[nodiscard]] constexpr
bool is_null( )
const {
647 return type( ) == JsonBaseParseTypes::Null;
652 [[nodiscard]] constexpr
bool is_class( )
const {
653 return type( ) == JsonBaseParseTypes::Class;
658 [[nodiscard]] constexpr
bool is_array( )
const {
659 return type( ) == JsonBaseParseTypes::Array;
665 return type( ) == JsonBaseParseTypes::Number;
670 [[nodiscard]]
inline constexpr
bool is_string( )
const {
671 return type( ) == JsonBaseParseTypes::String;
676 [[nodiscard]] constexpr
bool is_bool( )
const {
677 return type( ) == JsonBaseParseTypes::Bool;
684 [[nodiscard]]
inline constexpr
bool is_unknown( )
const {
685 return type( ) == JsonBaseParseTypes::None;
689 template<json_options_t P,
typename A>
690 [[nodiscard]] constexpr
694 new_range.class_first = m_parse_state.class_first;
695 new_range.class_last = m_parse_state.class_last;
700 [[nodiscard]]
explicit constexpr
operator bool( )
const {
701 return type( ) != JsonBaseParseTypes::None;
705 template<json_options_t PolicyFlags,
typename Allocator>
716 template<
typename Result, json_options_t PolicyFlags,
typename Allocator>
717 [[nodiscard]] constexpr Result
719 return jv.template as<Result>( );
722 namespace json_details {
724 inline constexpr
bool is_json_value =
false;
726 template<json_options_t PolicyFlags,
typename Allocator>
727 inline constexpr
bool
728 is_json_value<basic_json_value<PolicyFlags, Allocator>> =
true;
730 template<json_options_t PolicyFlags,
typename Allocator>
731 inline constexpr
bool
732 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(ErrorReason reason)
JsonBaseParseTypes
The fundamental JSON types.
basic_json_pair<> json_pair
std::uint32_t json_options_t
constexpr bool is_number(char c)
daw::conditional_t< ParsePolicy::is_default_parse_policy, DefaultParsePolicy, ParsePolicy > TryDefaultParsePolicy
basic_json_value_iterator(BasicParsePolicy< PolicyFlags, Allocator > const &) -> basic_json_value_iterator< PolicyFlags, Allocator >
constexpr decltype(auto) get(basic_json_pair< PolicyFlags, Allocator > const &parse_state)
constexpr Result as(basic_json_value< PolicyFlags, Allocator > const &jv)
basic_json_value_iterator_range(basic_json_value_iterator< PolicyFlags, Allocator >, basic_json_value_iterator< PolicyFlags, Allocator >) -> basic_json_value_iterator_range< PolicyFlags, Allocator >
basic_json_value(BasicParsePolicy< PolicyFlags, Allocator >) -> basic_json_value< PolicyFlags, Allocator >
Customization point traits.
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
typename BasicParsePolicy< PolicyFlags, Allocator >::CharT CharT
Iterator for iterating over arbitrary JSON members and array elements.
constexpr basic_json_pair< PolicyFlags, Allocator > operator*()
Get the name/value pair of the currently referenced element.
TryDefaultParsePolicy< BasicParsePolicy< PolicyFlags, Allocator > > parse_policy
basic_json_value_iterator()=default
basic_json_value_iterator(daw::string_view json_doc)
std::forward_iterator_tag iterator_category
std::string_view key_type
std::ptrdiff_t difference_type
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 bool operator!=(basic_json_value_iterator< P, A > const &rhs) const
Check if rhs is not equivalent to self.
constexpr basic_json_value< PolicyFlags, Allocator > value() const
Get the value currently being referenced.
A non-owning container for arbitrary JSON values that allows movement/iteration through.
constexpr std::string_view get_raw_json_document() const
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
typename ParseState::CharT CharT
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.
constexpr basic_json_value find_array_element(std::size_t index) const
Find the nth element of the current json array.
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
basic_json_value()=default
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.