31    namespace json_details {
 
   45      template<
typename JsonMember, 
typename ParseState>
 
   46      [[nodiscard]] DAW_ATTRIB_INLINE 
static constexpr json_result_t<JsonMember>
 
   47      parse_ordered_class_member( std::size_t &member_index,
 
   48                                  ParseState &parse_state ) {
 
   50        using json_member_t = ordered_member_subtype_t<JsonMember>;
 
   52        parse_state.move_next_member_or_end( );
 
   57        if constexpr( is_an_ordered_member_v<JsonMember> ) {
 
   58          pocm_details::maybe_skip_members<is_json_nullable_v<json_member_t>>(
 
   59            parse_state, member_index, JsonMember::member_index );
 
   62                                ErrorReason::UnexpectedEndOfData, parse_state );
 
   68        if( DAW_UNLIKELY( parse_state.front( ) == 
']' ) ) {
 
   69          if constexpr( is_json_nullable_v<json_member_t> ) {
 
   71            auto loc = ParseState{ };
 
   72            return parse_value<json_member_t, 
true,
 
   73                               json_member_t::expected_type>( loc );
 
   79        return parse_value<json_member_t, false, json_member_t::expected_type>(
 
   93      template<std::size_t member_position, 
typename JsonMember,
 
   94               AllMembersMustExist must_exist, 
bool NeedsClassPositions,
 
   95               typename ParseState, std::size_t N, 
typename CharT, 
bool B>
 
   96      [[nodiscard]] DAW_ATTRIB_FLATINLINE 
static constexpr json_result_t<
 
   98      parse_class_member( ParseState &parse_state,
 
   99                          locations_info_t<N, CharT, B> &locations ) {
 
  100        parse_state.move_next_member_or_end( );
 
  103          not parse_state.empty( ) and parse_state.is_at_next_class_member( ),
 
  104          ErrorReason::MissingMemberNameOrEndOfClass, parse_state );
 
  106        auto [loc, known] = find_class_member<member_position, must_exist>(
 
  107          parse_state, locations, is_json_nullable_v<JsonMember>,
 
  112          if constexpr( NeedsClassPositions ) {
 
  113            auto const cf = parse_state.class_first;
 
  114            auto const cl = parse_state.class_last;
 
  116                            json_result_t<without_name<JsonMember>>> ) {
 
  117              auto const after_parse = daw::on_scope_exit( [&] {
 
  118                parse_state.class_first = cf;
 
  119                parse_state.class_last = cl;
 
  121              return parse_value<without_name<JsonMember>, 
false,
 
  122                                 JsonMember::expected_type>( parse_state );
 
  125                parse_value<without_name<JsonMember>, 
false,
 
  126                            JsonMember::expected_type>( parse_state );
 
  127              parse_state.class_first = cf;
 
  128              parse_state.class_last = cl;
 
  132            return parse_value<without_name<JsonMember>, 
false,
 
  133                               JsonMember::expected_type>( parse_state );
 
  137        if( loc.is_null( ) ) {
 
  138          if constexpr( is_json_nullable_v<JsonMember> ) {
 
  139            return parse_value_null<without_name<JsonMember>, 
true>( loc );
 
  142                              std::data( JsonMember::name ),
 
  143                              std::size( JsonMember::name ) ) ),
 
  149        return parse_value<without_name<JsonMember>, 
true,
 
  150                           JsonMember::expected_type>( loc );
 
  153      template<
bool IsExactClass, 
typename ParseState, 
typename OldClassPos>
 
  154      DAW_ATTRIB_INLINE 
static constexpr void 
  155      class_cleanup_now( ParseState &parse_state,
 
  156                         OldClassPos 
const &old_class_pos ) {
 
  158                              ErrorReason::UnexpectedEndOfData, parse_state );
 
  159        parse_state.move_next_member_or_end( );
 
  161        parse_state.move_to_next_class_member( );
 
  162        if constexpr( IsExactClass ) {
 
  164                                ErrorReason::UnknownMember, parse_state );
 
  165          parse_state.remove_prefix( );
 
  167          (void)parse_state.skip_class( );
 
  171        parse_state.trim_left_checked( );
 
  172        parse_state.set_class_position( old_class_pos );
 
  182      template<
typename JsonClass, 
typename... JsonMembers, 
typename ParseState,
 
  184      [[nodiscard]] DAW_ATTRIB_INLINE 
constexpr json_result_t<JsonClass>
 
  185      parse_json_class( ParseState &parse_state, std::index_sequence<Is...> ) {
 
  186        static_assert( is_a_json_type_v<JsonClass> );
 
  187        using T = json_result_t<JsonClass>;
 
  188        using Constructor = json_constructor_t<JsonClass>;
 
  189        static_assert( has_json_data_contract_trait_v<T>, 
"Unexpected type" );
 
  191          daw::constant<( all_json_members_must_exist_v<T, ParseState>
 
  192                            ? AllMembersMustExist::yes
 
  193                            : AllMembersMustExist::no )>;
 
  195        parse_state.trim_left( );
 
  198                              ErrorReason::InvalidClassStart, parse_state );
 
  200        auto const old_class_pos = parse_state.get_class_position( );
 
  201        parse_state.set_class_position( );
 
  202        parse_state.remove_prefix( );
 
  203        parse_state.trim_left( );
 
  205        if constexpr( 
sizeof...( JsonMembers ) == 0 ) {
 
  207          class_cleanup_now<all_json_members_must_exist_v<T, ParseState>>(
 
  208            parse_state, old_class_pos );
 
  214            return construct_value_tp<T, Constructor>( parse_state,
 
  218          using NeedClassPositions = std::bool_constant<(
 
  219            ( must_be_class_member_v<typename JsonMembers::without_name> or
 
  222#if defined( DAW_JSON_BUGFIX_MSVC_KNOWN_LOC_ICE_003 ) 
  223          auto known_locations =
 
  224            make_locations_info<ParseState, JsonMembers...>( );
 
  226          auto known_locations = DAW_AS_CONSTANT(
 
  227            ( make_locations_info<ParseState, JsonMembers...>( ) ) );
 
  230          if constexpr( is_pinned_type_v<json_result_t<JsonClass>> ) {
 
  234            auto const run_after_parse = daw::on_exit_success( [&] {
 
  235              class_cleanup_now<all_json_members_must_exist_v<T, ParseState>>(
 
  236                parse_state, old_class_pos );
 
  238            (void)run_after_parse;
 
  242              return T{ parse_class_member<
 
  243                Is, daw::traits::nth_type<Is, JsonMembers...>,
 
  244                must_exist::value, NeedClassPositions::value>(
 
  245                parse_state, known_locations )... };
 
  247              return construct_value_tp<T, Constructor>(
 
  248                parse_state, fwd_pack{ parse_class_member<
 
  249                               Is, daw::traits::nth_type<Is, JsonMembers...>,
 
  250                               must_exist::value, NeedClassPositions::value>(
 
  251                               parse_state, known_locations )... } );
 
  256              auto result = T{ parse_class_member<
 
  257                Is, daw::traits::nth_type<Is, JsonMembers...>,
 
  258                must_exist::value, NeedClassPositions::value>(
 
  259                parse_state, known_locations )... };
 
  261              class_cleanup_now<all_json_members_must_exist_v<T, ParseState>>(
 
  262                parse_state, old_class_pos );
 
  265              auto result = construct_value_tp<T, Constructor>(
 
  266                parse_state, fwd_pack{ parse_class_member<
 
  267                               Is, daw::traits::nth_type<Is, JsonMembers...>,
 
  268                               must_exist::value, NeedClassPositions::value>(
 
  269                               parse_state, known_locations )... } );
 
  271              class_cleanup_now<all_json_members_must_exist_v<T, ParseState>>(
 
  272                parse_state, old_class_pos );
 
  284      template<
typename JsonClass, 
typename... JsonMembers, 
typename ParseState>
 
  285      [[nodiscard]] 
static inline constexpr json_result_t<JsonClass>
 
  286      parse_json_tuple_class( ParseState &parse_state ) {
 
  287        static_assert( is_a_json_type_v<JsonClass> );
 
  288        using T = json_base_type_t<JsonClass>;
 
  289        using Constructor = json_constructor_t<JsonClass>;
 
  290        static_assert( has_json_data_contract_trait_v<T>, 
"Unexpected type" );
 
  292          std::is_invocable_v<Constructor, json_result_t<JsonMembers>...>,
 
  293          "Supplied types cannot be used for construction of this type" );
 
  295        parse_state.trim_left( ); 
 
  297                              ErrorReason::InvalidArrayStart, parse_state );
 
  298        auto const old_class_pos = parse_state.get_class_position( );
 
  299        parse_state.set_class_position( );
 
  300        parse_state.remove_prefix( );
 
  301        parse_state.trim_left( );
 
  303        std::size_t current_idx = 0;
 
  305        if constexpr( is_pinned_type_v<json_result_t<JsonClass>> ) {
 
  306          auto const run_after_parse = daw::on_exit_success( [&] {
 
  307            ordered_class_cleanup<all_json_members_must_exist_v<T, ParseState>,
 
  308                                  ParseState, 
decltype( old_class_pos )>(
 
  309              parse_state, old_class_pos );
 
  311          (void)run_after_parse;
 
  314            return T{ parse_ordered_class_member<JsonMembers>(
 
  315              current_idx, parse_state )... };
 
  317            return construct_value_tp<T, Constructor>(
 
  318              parse_state, fwd_pack{ parse_ordered_class_member<JsonMembers>(
 
  319                             current_idx, parse_state )... } );
 
  325              return T{ parse_ordered_class_member<JsonMembers>(
 
  326                current_idx, parse_state )... };
 
  328              return construct_value_tp<T, Constructor>(
 
  329                parse_state, fwd_pack{ parse_ordered_class_member<JsonMembers>(
 
  330                               current_idx, parse_state )... } );
 
  333          if constexpr( all_json_members_must_exist_v<T, ParseState> ) {
 
  334            parse_state.trim_left( );
 
  336                                  ErrorReason::UnknownMember, parse_state );
 
  337            parse_state.remove_prefix( );
 
  338            parse_state.trim_left( );
 
  340            (void)parse_state.skip_array( );
 
  342          parse_state.set_class_position( old_class_pos );