24#include <daw/cpp_17.h>
25#include <daw/daw_attributes.h>
26#include <daw/daw_consteval.h>
27#include <daw/daw_likely.h>
28#include <daw/daw_not_null.h>
29#include <daw/daw_rw_ref.h>
30#include <daw/daw_traits.h>
49 template<
json_options_t PolicyFlags = json_details::default_policy_flag,
50 typename Allocator = json_details::NoAllocator>
54 static constexpr bool is_default_parse_policy =
55 PolicyFlags == json_details::default_policy_flag and
56 std::is_same_v<Allocator, json_details::NoAllocator>;
65 static constexpr bool is_unchecked_input =
66 json_details::get_bits_for<options::CheckedParseMode>( PolicyFlags ) ==
67 options::CheckedParseMode::no;
73 json_details::get_bits_for<options::ExecModeTypes, std::size_t>(
82 static constexpr bool allow_escaped_names =
83 json_details::get_bits_for<options::AllowEscapedNames>( PolicyFlags ) ==
84 options::AllowEscapedNames::yes;
89 static constexpr bool force_name_equal_check =
90 json_details::get_bits_for<options::ForceFullNameCheck>(
91 PolicyFlags ) == options::ForceFullNameCheck::yes;
97 json_details::get_bits_for<options::ZeroTerminatedString>(
98 PolicyFlags ) == options::ZeroTerminatedString::yes;
103 static constexpr bool allow_string_mutation =
104 json_details::get_bits_for<options::AllowStringMutation>(
105 PolicyFlags ) == options::AllowStringMutation::yes;
110 static constexpr bool precise_ieee754 =
111 json_details::get_bits_for<options::IEEE754Precise>( PolicyFlags ) ==
112 options::IEEE754Precise::yes;
117 static constexpr bool minified_document =
118 json_details::get_bits_for<options::MinifiedDocument>( PolicyFlags ) ==
119 options::MinifiedDocument::yes;
124 static constexpr bool exclude_special_escapes =
125 json_details::get_bits_for<options::ExcludeSpecialEscapes>(
126 PolicyFlags ) == options::ExcludeSpecialEscapes::yes;
129 static constexpr bool allow_leading_zero_plus =
true;
131 static constexpr bool use_exact_mappings_by_default =
132 json_details::get_bits_for<options::UseExactMappingsByDefault>(
133 PolicyFlags ) == options::UseExactMappingsByDefault::yes;
135 static constexpr bool must_verify_end_of_data_is_valid =
136 json_details::get_bits_for<options::MustVerifyEndOfDataIsValid>(
137 PolicyFlags ) == options::MustVerifyEndOfDataIsValid::yes;
139 static constexpr bool expect_long_strings =
140 json_details::get_bits_for<options::ExpectLongNames>( PolicyFlags ) ==
141 options::ExpectLongNames::yes;
145 static constexpr std::size_t array_reserve_amount = [] {
146 switch( json_details::get_bits_for<options::ArrayReserve>(
148 case options::ArrayReserve::none:
149 return std::size_t{ 0 };
150 case options::ArrayReserve::elements_128:
151 return std::size_t{ 128 };
152 case options::ArrayReserve::elements_512:
153 return std::size_t{ 512 };
154 case options::ArrayReserve::elements_1024:
155 return std::size_t{ 1024 };
157 return std::size_t{ 0 };
161 switch_t<json_details::get_bits_for<options::PolicyCommentTypes,
162 std::size_t>( PolicyFlags ),
166 using iterator = std::conditional_t<allow_string_mutation ,
167 char *,
char const *>;
172 std::size_t counter = 0;
174 template<
auto... PolicyOptions>
176 json_details::set_bits( PolicyFlags, PolicyOptions... ), Allocator>;
188 : json_details::AllocatorWrapper<Allocator>( alloc )
199 , class_last( cl ) {}
207 , counter( cnter ) {}
210 iterator cl, Allocator
const &alloc )
211 : json_details::AllocatorWrapper<Allocator>( alloc )
215 , class_last( cl ) {}
219 iterator cf = iterator{ }, iterator cl = iterator{ } )
const {
220 BasicParsePolicy result = *
this;
228 result.class_first = cf;
231 result.class_last = cl;
237 return json_details::AllocatorWrapper<Allocator>::get_allocator( );
240 template<
typename Alloc>
243 template<
typename Alloc>
246 Alloc
const &alloc ) {
252 json_details::NoAllocator
const & ) {
256 template<
typename Alloc>
257 [[nodiscard]]
constexpr auto
259 if constexpr( std::is_same_v<Alloc, json_details::NoAllocator> ) {
262 auto result = with_allocator(
269 template<
typename Alloc>
270 [[nodiscard]]
constexpr with_allocator_type<Alloc>
273 with_allocator( first, last, class_first, class_last, alloc );
274 result.counter = counter;
278 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr auto
286 template<
typename Alloc>
292 template<
typename Alloc>
295 json_details::NoAllocator
const & ) {
315 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr bool empty( )
const {
320 return first >= last or *first ==
'\0';
322 return first >= last;
326 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr bool has_more( )
const {
327#if not defined( NDEBUG )
329 ErrorReason::InvalidNull );
334 template<std::
size_t N>
336 static_assert( N > 0 );
337 if( size( ) < ( N - 1 ) ) {
341 for( std::size_t n = 0; n < ( N - 1 ); ++n ) {
342 result = result & ( first[n] == rhs[n] );
347 template<std::
size_t N>
349 if( not starts_with( rhs ) ) {
352 first +=
static_cast<std::ptrdiff_t
>( N - 1 );
358 auto const position =
359 json_details::memchr_unchecked<c, exec_tag_t, expect_long_strings>(
360 daw::not_null<char const *>{ daw::never_null, first },
361 daw::not_null<char const *>{ daw::never_null, last } );
362 first = json_details::input_pointer( first, position.get( ) );
367 auto const position =
368 json_details::memchr_checked<c, exec_tag_t, expect_long_strings>(
369 daw::not_null<char const *>{ first },
370 daw::not_null<char const *>{ last } );
371 first = json_details::input_pointer( first, position.get( ) );
376 if( is_unchecked_input ) {
377 move_to_next_of_unchecked<c>( );
379 move_to_next_of_checked<c>( );
383 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr char front( )
const {
389 first < last, ErrorReason::UnexpectedEndOfData, *
this );
393 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr std::size_t
size( )
const {
394 assert( last >= first );
395 return static_cast<std::size_t
>( last - first );
398 [[nodiscard]]
constexpr bool is_null( )
const {
399 return first ==
nullptr;
407 first +=
static_cast<std::ptrdiff_t
>( n );
421 class_first = new_pos.
f;
422 class_last = new_pos.
l;
426 return { class_first, class_last };
430 return CommentPolicy::trim_left_checked( *
this );
434 return CommentPolicy::trim_left_unchecked( *
this );
438 return CommentPolicy::is_literal_end( *first );
441 [[nodiscard]] DAW_ATTRIB_INLINE
constexpr bool
443 return (
static_cast<unsigned>(
static_cast<unsigned char>( *first ) ) -
448 return DAW_LIKELY( first < last ) and *first ==
'[';
452 return DAW_LIKELY( first < last ) and *first ==
'{';
456 return DAW_LIKELY( first < last ) and *first ==
'}';
460 return DAW_LIKELY( first < last ) and *first ==
'"';
464 if constexpr( is_unchecked_input ) {
465 trim_left_unchecked( );
467 trim_left_checked( );
472 trim_left_unchecked( );
473 if( *first ==
',' ) {
475 trim_left_unchecked( );
480 trim_left_checked( );
482 if( *first ==
',' ) {
487 if( DAW_LIKELY( first < last ) and *first ==
',' ) {
495 if constexpr( is_unchecked_input ) {
496 move_next_member_or_end_unchecked( );
498 move_next_member_or_end_checked( );
503 if constexpr( is_unchecked_input ) {
504 CommentPolicy::move_next_member_unchecked( *
this );
507 move_next_member_or_end_checked( );
512 CommentPolicy::template move_to_next_of<
'"',
'}'>( *this );
516 return parse_policy_details::in<
'"',
'}'>( *first );
520 return parse_policy_details::in<',', ']'>( *first );
524 return parse_policy_details::in<',', '}', ']'>( *first );
527 template<json_details::SkipBracketedType BracketedType>
530 return CommentPolicy::template skip_bracketed_item_checked<
531 BracketedType>( *this );
534 template<json_details::SkipBracketedType BracketedType>
537 return CommentPolicy::template skip_bracketed_item_unchecked<
538 BracketedType>( *this );
542#if defined( DAW_JSON_HAS_STD_SIMD )
543 if constexpr( std::is_same_v<CommentPolicy, NoCommentSkippingPolicy> ) {
544 return json_details::skip_bracketed_item_simd<
545 json_details::SkipBracketedType::Class>( *this );
547#elif defined( DAW_JSON_HAS_SIMD )
548 if constexpr( std::is_same_v<CommentPolicy, NoCommentSkippingPolicy> ) {
549 if( not DAW_IS_CONSTANT_EVALUATED_COMPAT( ) ) {
550 return json_details::skip_bracketed_item_simd<
551 json_details::SkipBracketedType::Class>( *this );
555 if constexpr( is_unchecked_input ) {
556 return skip_bracketed_item_unchecked<
557 json_details::SkipBracketedType::Class>( );
559 return skip_bracketed_item_checked<
560 json_details::SkipBracketedType::Class>( );
565#if defined( DAW_JSON_HAS_STD_SIMD )
566 if constexpr( std::is_same_v<CommentPolicy, NoCommentSkippingPolicy> ) {
567 return json_details::skip_bracketed_item_simd<
568 json_details::SkipBracketedType::Array>( *this );
570#elif defined( DAW_JSON_HAS_SIMD )
571 if constexpr( std::is_same_v<CommentPolicy, NoCommentSkippingPolicy> ) {
572 if( not DAW_IS_CONSTANT_EVALUATED_COMPAT( ) ) {
573 return json_details::skip_bracketed_item_simd<
574 json_details::SkipBracketedType::Array>( *this );
578 if constexpr( is_unchecked_input ) {
579 return skip_bracketed_item_unchecked<
580 json_details::SkipBracketedType::Array>( );
582 return skip_bracketed_item_checked<
583 json_details::SkipBracketedType::Array>( );
593 template<
typename Allocator>
596 template<
typename Allocator>
604 template<
typename Allocator>
608 template<
typename Allocator>
614 json_details::NoAllocator> {
616 using BasicParsePolicy::BasicParsePolicy;
624 template<
json_options_t PolicyFlags = json_details::default_policy_flag,
625 typename Allocator = json_details::NoAllocator>
627 daw::conditional_t<(PolicyFlags == json_details::default_policy_flag and
628 std::is_same_v<Allocator, json_details::NoAllocator>),
631 template<
typename ParsePolicy>
633 daw::conditional_t<ParsePolicy::is_default_parse_policy,
641 template<
auto... PolicyFlags>
644 json_details::are_option_flags<
decltype( PolicyFlags )...>,
645 "Only registered policy types are allowed" );
651 json_details::default_policy_flag;
655 template<
typename... Ts>
658 template<
auto... PolicyFlags>
661 template<
auto... PolicyFlags>
663 if constexpr(
decltype( details::is_policy_flag(
664 PolicyFlags... ) )::value ) {
665 static_assert(
sizeof...( PolicyFlags ) == 1 );
667 return ( PolicyFlags, ... );
677 template<
auto... PolicyFlags>
679 details::make_parse_flags<PolicyFlags...>( );
682#define DAW_JSON_CONFORMANCE_FLAGS \
683 daw::json::options::AllowEscapedNames::yes, \
684 daw::json::options::MustVerifyEndOfDataIsValid::yes, \
685 daw::json::options::IEEE754Precise::yes, \
686 daw::json::options::ExcludeSpecialEscapes::yes
689 options::parse_flags<DAW_JSON_CONFORMANCE_FLAGS>;
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
std::uint32_t json_options_t
DAW_CONSTEVAL auto make_parse_flags()
std::false_type is_policy_flag(Ts...)
constexpr auto parse_flags
Specify parse policy flags in to_json calls. See cookbook item parse_options.md.
daw::conditional_t<(PolicyFlags==json_details::default_policy_flag and std::is_same_v< Allocator, json_details::NoAllocator >), DefaultParsePolicy, BasicParsePolicy< PolicyFlags, Allocator > > GetParsePolicy
daw::conditional_t< ParsePolicy::is_default_parse_policy, DefaultParsePolicy, ParsePolicy > TryDefaultParsePolicy
constexpr auto ConformancePolicy
std::bool_constant< is_zero_terminated_string_v< T > > is_zero_terminated_string
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.
DAW_ATTRIB_INLINE constexpr iterator data_end() const
constexpr BasicParsePolicy(iterator f, iterator l)
constexpr bool is_null() const
constexpr bool is_opening_bracket_checked() const
static constexpr BasicParsePolicy with_allocator(iterator f, iterator l, iterator cf, iterator cl, json_details::NoAllocator const &)
DAW_ATTRIB_INLINE constexpr BasicParsePolicy skip_bracketed_item_checked()
DAW_ATTRIB_INLINE constexpr BasicParsePolicy skip_array()
constexpr bool is_literal_end() const
DAW_ATTRIB_INLINE constexpr BasicParsePolicy skip_bracketed_item_unchecked()
DAW_ATTRIB_INLINE constexpr bool has_more() const
constexpr bool is_opening_brace_checked() const
DAW_ATTRIB_INLINE constexpr iterator begin() const
DAW_ATTRIB_INLINE constexpr std::size_t size() const
constexpr BasicParsePolicy(iterator f, iterator l, iterator cf, iterator cl, Allocator const &alloc)
DAW_ATTRIB_INLINE constexpr void remove_prefix(std::size_t n)
DAW_ATTRIB_INLINE constexpr iterator data() const
constexpr void set_class_position(class_pos_t new_pos)
constexpr class_pos_t get_class_position() const
constexpr BasicParsePolicy(iterator f, iterator l, iterator cf, iterator cl)
DAW_ATTRIB_INLINE constexpr void move_next_member()
DAW_ATTRIB_INLINE constexpr auto with_allocator(json_details::NoAllocator const &) const
DAW_ATTRIB_INLINE constexpr bool empty() const
constexpr bool starts_with_skip(char const (&rhs)[N])
constexpr bool is_at_next_array_element() const
constexpr auto with_allocator(BasicParsePolicy< PolicyFlags, Alloc > p) const
constexpr void trim_left_checked()
constexpr bool is_at_next_class_member() const
static constexpr BasicParsePolicy with_allocator(iterator f, iterator l, json_details::NoAllocator const &)
DAW_ATTRIB_INLINE constexpr void move_to_next_of()
switch_t< json_details::get_bits_for< options::ExecModeTypes, std::size_t >(PolicyFlags), default_exec_tag, constexpr_exec_tag, runtime_exec_tag, simd_exec_tag > exec_tag_t
constexpr BasicParsePolicy copy(iterator f=iterator{ }, iterator l=iterator{ }, iterator cf=iterator{ }, iterator cl=iterator{ }) const
DAW_ATTRIB_INLINE constexpr void remove_prefix()
constexpr BasicParsePolicy(iterator f, iterator l, iterator cf, iterator cl, std::size_t cnter)
constexpr void move_to_next_class_member()
constexpr void trim_left_unchecked()
constexpr void set_class_position()
DAW_ATTRIB_INLINE constexpr void move_to_next_of_unchecked()
DAW_ATTRIB_INLINE constexpr iterator end() const
DAW_ATTRIB_INLINE constexpr decltype(auto) get_allocator() const
DAW_ATTRIB_INLINE constexpr void move_next_member_or_end()
constexpr BasicParsePolicy(iterator f, iterator l, Allocator &alloc)
constexpr bool is_at_token_after_value() const
static constexpr with_allocator_type< Alloc > with_allocator(iterator f, iterator l, Alloc const &alloc)
static constexpr with_allocator_type< Alloc > with_allocator(iterator f, iterator l, iterator cf, iterator cl, Alloc const &alloc)
DAW_ATTRIB_INLINE constexpr bool is_space_unchecked() const
DAW_ATTRIB_INLINE constexpr char front() const
constexpr bool starts_with(char const (&rhs)[N]) const
BasicParsePolicy()=default
switch_t< json_details::get_bits_for< options::PolicyCommentTypes, std::size_t >(PolicyFlags), NoCommentSkippingPolicy, CppCommentSkippingPolicy, HashCommentSkippingPolicy > CommentPolicy
constexpr bool is_quotes_checked() const
constexpr void move_next_member_or_end_checked()
DAW_ATTRIB_INLINE constexpr BasicParsePolicy skip_class()
DAW_ATTRIB_INLINE constexpr void trim_left()
constexpr with_allocator_type< Alloc > with_allocator(Alloc const &alloc) const
static DAW_CONSTEVAL json_options_t policy_flags()
constexpr void move_next_member_or_end_unchecked()
std::conditional_t< allow_string_mutation, char *, char const * > iterator
DAW_ATTRIB_INLINE constexpr char front_checked() const
DAW_ATTRIB_INLINE constexpr void move_to_next_of_checked()
constexpr bool is_closing_brace_checked() const
constexpr DefaultParsePolicy(BasicParsePolicy &&other) noexcept
constexpr DefaultParsePolicy(BasicParsePolicy const &other) noexcept
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.