DAW JSON Link
daw_json_parse_kv_array_iterator.h
Go to the documentation of this file.
1 // Copyright (c) Darrell Wright
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6 // Official repository: https://github.com/beached/daw_json_link
7 //
8 
9 #pragma once
10 
11 #include "daw_json_arrow_proxy.h"
12 #include "daw_json_assert.h"
14 
15 #include <ciso646>
16 
17 namespace daw::json::json_details {
18  template<typename Range, bool>
19  struct json_parse_kv_array_iterator_base {
20  using iterator_category = std::input_iterator_tag;
21  using difference_type = std::ptrdiff_t;
22  static constexpr bool has_counter = false;
23  Range *rng = nullptr;
24  };
25 
26  template<typename Range>
27  struct json_parse_kv_array_iterator_base<Range, true> {
28  // We have to lie so that std::distance uses O(1) instead of O(N)
29  using iterator_category = std::random_access_iterator_tag;
30  using difference_type = std::ptrdiff_t;
31  static constexpr bool has_counter = true;
32  Range *rng = nullptr;
33 
34  constexpr difference_type
35  operator-( json_parse_kv_array_iterator_base const &rhs ) const {
36  if( rhs.rng ) {
37  return static_cast<difference_type>( rhs.rng->counter );
38  }
39  return 0;
40  }
41  };
42 
43  template<typename JsonMember, typename Range, bool KnownBounds>
44  struct json_parse_kv_array_iterator
45  : json_parse_kv_array_iterator_base<Range, can_random_v<KnownBounds>> {
46 
47  using base =
48  json_parse_kv_array_iterator_base<Range, can_random_v<KnownBounds>>;
49  using iterator_category = typename base::iterator_category;
50  using json_key_t = typename JsonMember::json_key_t;
51  using json_element_t = typename JsonMember::json_value_t;
52  using value_type = std::pair<typename json_key_t::parse_to_t const,
53  typename json_element_t::parse_to_t>;
54  using reference = value_type;
55  using pointer = arrow_proxy<value_type>;
56  using iterator_range_t = Range;
57  using difference_type = typename base::difference_type;
58 
59  using json_class_type = typename JsonMember::json_class_t;
60  inline constexpr json_parse_kv_array_iterator( ) = default;
61 
62  inline constexpr explicit json_parse_kv_array_iterator(
63  iterator_range_t &r )
64  : base{ &r } {
65  if( base::rng->front( ) == ']' ) {
66  if constexpr( not KnownBounds ) {
67  // Cleanup at end of value
68  base::rng->remove_prefix( );
69  base::rng->trim_left_checked( );
70  // Ensure we are equal to default
71  }
72  base::rng = nullptr;
73  }
74  }
75 
76  private:
77  static constexpr value_type
78  get_pair( typename json_class_type::parse_to_t &&v ) {
79  return value_type( std::get<0>( std::move( v.members ) ),
80  std::get<1>( std::move( v.members ) ) );
81  }
82 
83  public:
84  constexpr value_type operator*( ) {
85  daw_json_assert_weak( base::rng and base::rng->has_more( ),
86  ErrorReason::UnexpectedEndOfData, *base::rng );
87 
88  return get_pair( parse_value<json_class_type>(
89  ParseTag<JsonParseTypes::Class>{ }, *base::rng ) );
90  }
91 
92  inline constexpr json_parse_kv_array_iterator &operator++( ) {
93  daw_json_assert_weak( base::rng, ErrorReason::UnexpectedEndOfData );
94  base::rng->clean_tail( );
95  daw_json_assert_weak( base::rng->has_more( ),
96  ErrorReason::UnexpectedEndOfData );
97  if( base::rng->front( ) == ']' ) {
98 #ifndef NDEBUG
99  if constexpr( base::has_counter ) {
100  daw_json_assert_weak( base::rng->counter == 0,
101  ErrorReason::UnexpectedEndOfData );
102  }
103 #endif
104  if constexpr( not KnownBounds ) {
105  // Cleanup at end of value
106  base::rng->remove_prefix( );
107  base::rng->trim_left_checked( );
108  // Ensure we are equal to default
109  }
110  base::rng = nullptr;
111  }
112 #ifndef NDEBUG
113  if constexpr( base::has_counter ) {
114  if( base::rng ) {
115  daw_json_assert_weak( base::rng->counter > 0,
116  ErrorReason::UnexpectedEndOfData );
117  base::rng->counter--;
118  }
119  }
120 #endif
121  return *this;
122  }
123 
124  inline constexpr json_parse_kv_array_iterator operator++( int ) {
125  auto result = *this;
126  (void)this->operator++( );
127  return result;
128  }
129 
130  inline constexpr bool
131  operator==( json_parse_kv_array_iterator const &rhs ) const {
132  return base::rng == rhs.base::rng;
133  }
134 
135  inline constexpr bool
136  operator!=( json_parse_kv_array_iterator const &rhs ) const {
137  return base::rng != rhs.base::rng;
138  }
139  };
140 } // namespace daw::json::json_details
daw_json_assert_weak
#define daw_json_assert_weak(Bool,...)
Definition: daw_json_assert.h:206
daw_json_parse_value_fwd.h
daw_json_arrow_proxy.h
daw_json_assert.h