libwordring
serialize_iterator.hpp
1 #pragma once
2 
3 #include <algorithm>
4 #include <cstddef>
5 #include <iterator>
6 #include <type_traits>
7 
8 #include <wordring/serialize/serialize.hpp>
9 
10 namespace wordring
11 {
12  // ------------------------------------------------------------------------
13  // serialize_iterator
14  // ------------------------------------------------------------------------
15 
49  template <typename InputIterator>
51  {
52  template <typename InputIterator1>
53  friend bool operator==(serialize_iterator<InputIterator1> const&, serialize_iterator<InputIterator1> const&);
54 
55  template <typename InputIterator1>
56  friend bool operator!=(serialize_iterator<InputIterator1> const&, serialize_iterator<InputIterator1> const&);
57 
58  public:
59  using iterator_type = InputIterator;
60  using unsigned_type = std::make_unsigned_t<typename std::iterator_traits<iterator_type>::value_type>;
61 
62  using difference_type = std::ptrdiff_t;
63  using value_type = std::uint8_t;
64  using pointer = value_type*;
65  using reference = value_type&;
66  using iterator_category = std::input_iterator_tag;
67 
68  static std::uint32_t constexpr coefficient = sizeof(unsigned_type);
69 
70  static_assert(std::is_integral_v<typename std::iterator_traits<iterator_type>::value_type>);
71 
72  public:
76  : m_index(0)
77  {
78  }
79 
84  serialize_iterator(iterator_type base)
85  : m_it(base)
86  , m_index(0)
87  {
88  }
89 
92  iterator_type base() const
93  {
94  return m_it;
95  }
96 
97  value_type operator*() const
98  {
99  std::uint32_t n = (coefficient - 1) - (m_index % coefficient);
100 
101  return (static_cast<unsigned_type>(*m_it) >> n * 8) & 0xFFu;
102  }
103 
104  serialize_iterator& operator++()
105  {
106  ++m_index;
107  if (m_index % coefficient == 0) ++m_it;
108  return *this;
109  }
110 
111  serialize_iterator operator++(int)
112  {
113  auto result = *this;
114  operator++();
115  return result;
116  }
117 
118  private:
119  iterator_type m_it;
120  std::uint32_t m_index;
121  };
122 
123  template <typename InputIterator1>
124  inline bool operator==(serialize_iterator<InputIterator1> const& lhs, serialize_iterator<InputIterator1> const& rhs)
125  {
126  return !(lhs != rhs);
127  }
128 
129  template <typename InputIterator1>
130  inline bool operator!=(serialize_iterator<InputIterator1> const& lhs, serialize_iterator<InputIterator1> const& rhs)
131  {
132  std::uint32_t constexpr coefficient = serialize_iterator<InputIterator1>::coefficient;
133  return lhs.m_it != rhs.m_it || lhs.m_index % coefficient != rhs.m_index % coefficient;
134  }
135 
136  // ------------------------------------------------------------------------
137  // deserialize_iterator
138  // ------------------------------------------------------------------------
139 
167  template <typename Value, typename ForwardIterator>
169  {
170  template <typename Value1, typename ForwardIterator1>
172 
173  template <typename Value1, typename ForwardIterator1>
175 
176  public:
177  using iterator_type = ForwardIterator;
178  using unsigned_type = std::make_unsigned_t<Value>;
179 
180  using difference_type = std::ptrdiff_t;
181  using value_type = Value;
182  using pointer = value_type*;
183  using reference = value_type&;
184  using iterator_category = std::input_iterator_tag;
185 
186  static std::uint32_t constexpr coefficient = sizeof(unsigned_type);
187 
188  public:
190  : m_it()
191  {
192  }
193 
194  deserialize_iterator(iterator_type it)
195  : m_it(it)
196  {
197  using category = typename std::iterator_traits<iterator_type>::iterator_category;
198 
199  static_assert(
200  std::is_same_v<category, std::forward_iterator_tag>
201  || std::is_same_v<category, std::bidirectional_iterator_tag>
202  || std::is_same_v<category, std::random_access_iterator_tag>);
203  }
204 
205  value_type operator*() const
206  {
207  unsigned_type v = 0;
208 
209  iterator_type it = m_it;
210  for (std::uint32_t i = 0; i < coefficient; ++i) v = (v << 8) + static_cast<std::uint8_t>(*it++);
211 
212  return v;
213  }
214 
215  deserialize_iterator& operator++()
216  {
217  std::advance(m_it, coefficient);
218  return *this;
219  }
220 
221  deserialize_iterator operator++(int)
222  {
223  auto result = *this;
224  operator++();
225  return result;
226  }
227 
228  protected:
229  iterator_type m_it;
230  };
231 
232  template <typename Value1, typename ForwardIterator1>
234  {
235  return lhs.m_it == rhs.m_it;
236  }
237 
238  template <typename Value1, typename ForwardIterator1>
239  inline bool operator!=(deserialize_iterator<Value1, ForwardIterator1> const& lhs, deserialize_iterator<Value1, ForwardIterator1> const& rhs)
240  {
241  return lhs.m_it != rhs.m_it;
242  }
243 }
wordring::serialize_iterator
任意型の整数列に対するイテレータをバイトを返すイテレータへ変換する
Definition: serialize_iterator.hpp:50
wordring::serialize_iterator::serialize_iterator
serialize_iterator(iterator_type base)
元となるイテレータから直列化イテレータを構築する
Definition: serialize_iterator.hpp:84
wordring
Definition: algorithm_.hpp:10
wordring::deserialize_iterator
バイト列に対するイテレータを任意型の整数を返すイテレータへ変換する
Definition: serialize_iterator.hpp:168
wordring::serialize_iterator::base
iterator_type base() const
元となるイテレータを返す
Definition: serialize_iterator.hpp:92
wordring::serialize_iterator::serialize_iterator
serialize_iterator()
空のイテレータを構築する
Definition: serialize_iterator.hpp:75
wordring::html::operator==
bool operator==(simple_attr< String1 > const &lhs, simple_attr< String1 > const &rhs)
名前空間、接頭辞、ローカル名が一致する場合、true を返す
Definition: simple_node.hpp:168