100.00% Lines (77/77) 100.00% Functions (27/27)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/cppalliance/http 7   // Official repository: https://github.com/cppalliance/http
8   // 8   //
9   9  
10   #ifndef BOOST_HTTP_IMPL_FIELDS_BASE_HPP 10   #ifndef BOOST_HTTP_IMPL_FIELDS_BASE_HPP
11   #define BOOST_HTTP_IMPL_FIELDS_BASE_HPP 11   #define BOOST_HTTP_IMPL_FIELDS_BASE_HPP
12   12  
13   #include <boost/core/detail/string_view.hpp> 13   #include <boost/core/detail/string_view.hpp>
14   #include <boost/assert.hpp> 14   #include <boost/assert.hpp>
15   15  
16   namespace boost { 16   namespace boost {
17   namespace http { 17   namespace http {
18   18  
19   //------------------------------------------------ 19   //------------------------------------------------
20   // 20   //
21   // iterator 21   // iterator
22   // 22   //
23   //------------------------------------------------ 23   //------------------------------------------------
24   24  
25   class fields_base::iterator 25   class fields_base::iterator
26   { 26   {
27   detail::header const* ph_ = nullptr; 27   detail::header const* ph_ = nullptr;
28   std::size_t i_ = 0; 28   std::size_t i_ = 0;
29   29  
30   friend class fields_base; 30   friend class fields_base;
31   31  
HITCBC 32   1701 iterator( 32   1701 iterator(
33   detail::header const* ph, 33   detail::header const* ph,
34   std::size_t i) noexcept 34   std::size_t i) noexcept
HITCBC 35   1701 : ph_(ph) 35   1701 : ph_(ph)
HITCBC 36   1701 , i_(i) 36   1701 , i_(i)
37   { 37   {
HITCBC 38   1701 } 38   1701 }
39   39  
40   public: 40   public:
41   using value_type = 41   using value_type =
42   fields_base::value_type; 42   fields_base::value_type;
43   using reference = 43   using reference =
44   fields_base::reference; 44   fields_base::reference;
45   using pointer = reference; 45   using pointer = reference;
46   using difference_type = 46   using difference_type =
47   std::ptrdiff_t; 47   std::ptrdiff_t;
48   using iterator_category = 48   using iterator_category =
49   std::bidirectional_iterator_tag; 49   std::bidirectional_iterator_tag;
50   50  
HITCBC 51   2 iterator() = default; 51   2 iterator() = default;
52   iterator(iterator const&) = default; 52   iterator(iterator const&) = default;
53   iterator& operator=( 53   iterator& operator=(
54   iterator const&) = default; 54   iterator const&) = default;
55   55  
56   bool 56   bool
HITCBC 57   1887 operator==( 57   1887 operator==(
58   iterator const& other) const noexcept 58   iterator const& other) const noexcept
59   { 59   {
60   // If this assert goes off, it means you 60   // If this assert goes off, it means you
61   // are trying to compare iterators from 61   // are trying to compare iterators from
62   // different containers, which is undefined! 62   // different containers, which is undefined!
HITCBC 63   1887 BOOST_ASSERT(ph_ == other.ph_); 63   1887 BOOST_ASSERT(ph_ == other.ph_);
64   64  
HITCBC 65   1887 return i_ == other.i_; 65   1887 return i_ == other.i_;
66   } 66   }
67   67  
68   bool 68   bool
HITCBC 69   1822 operator!=( 69   1822 operator!=(
70   iterator const& other) const noexcept 70   iterator const& other) const noexcept
71   { 71   {
HITCBC 72   1822 return !(*this == other); 72   1822 return !(*this == other);
73   } 73   }
74   74  
75   BOOST_HTTP_DECL 75   BOOST_HTTP_DECL
76   reference 76   reference
77   operator*() const noexcept; 77   operator*() const noexcept;
78   78  
79   pointer 79   pointer
HITCBC 80   1781 operator->() const noexcept 80   1781 operator->() const noexcept
81   { 81   {
HITCBC 82   1781 return *(*this); 82   1781 return *(*this);
83   } 83   }
84   84  
85   iterator& 85   iterator&
HITCBC 86   1174 operator++() noexcept 86   1174 operator++() noexcept
87   { 87   {
HITCBC 88   1174 BOOST_ASSERT(i_ < ph_->count); 88   1174 BOOST_ASSERT(i_ < ph_->count);
HITCBC 89   1174 ++i_; 89   1174 ++i_;
HITCBC 90   1174 return *this; 90   1174 return *this;
91   } 91   }
92   92  
93   iterator 93   iterator
HITCBC 94   1 operator++(int) noexcept 94   1 operator++(int) noexcept
95   { 95   {
HITCBC 96   1 auto temp = *this; 96   1 auto temp = *this;
HITCBC 97   1 ++(*this); 97   1 ++(*this);
HITCBC 98   1 return temp; 98   1 return temp;
99   } 99   }
100   100  
101   iterator& 101   iterator&
HITCBC 102   25 operator--() noexcept 102   25 operator--() noexcept
103   { 103   {
HITCBC 104   25 BOOST_ASSERT(i_ > 0); 104   25 BOOST_ASSERT(i_ > 0);
HITCBC 105   25 --i_; 105   25 --i_;
HITCBC 106   25 return *this; 106   25 return *this;
107   } 107   }
108   108  
109   iterator 109   iterator
HITCBC 110   1 operator--(int) noexcept 110   1 operator--(int) noexcept
111   { 111   {
HITCBC 112   1 auto temp = *this; 112   1 auto temp = *this;
HITCBC 113   1 --(*this); 113   1 --(*this);
HITCBC 114   1 return temp; 114   1 return temp;
115   } 115   }
116   }; 116   };
117   117  
118   //------------------------------------------------ 118   //------------------------------------------------
119   119  
120   class fields_base::reverse_iterator 120   class fields_base::reverse_iterator
121   { 121   {
122   detail::header const* ph_ = nullptr; 122   detail::header const* ph_ = nullptr;
123   std::size_t i_ = 0; 123   std::size_t i_ = 0;
124   124  
125   friend class fields_base; 125   friend class fields_base;
126   126  
127   reverse_iterator( 127   reverse_iterator(
128   detail::header const* ph, 128   detail::header const* ph,
129   std::size_t i) noexcept 129   std::size_t i) noexcept
130   : ph_(ph) 130   : ph_(ph)
131   , i_(i) 131   , i_(i)
132   { 132   {
133   } 133   }
134   134  
135   public: 135   public:
136   using value_type = 136   using value_type =
137   fields_base::value_type; 137   fields_base::value_type;
138   using reference = 138   using reference =
139   fields_base::reference; 139   fields_base::reference;
140   using pointer = reference; 140   using pointer = reference;
141   using difference_type = 141   using difference_type =
142   std::ptrdiff_t; 142   std::ptrdiff_t;
143   using iterator_category = 143   using iterator_category =
144   std::bidirectional_iterator_tag; 144   std::bidirectional_iterator_tag;
145   145  
HITCBC 146   2 reverse_iterator() = default; 146   2 reverse_iterator() = default;
147   reverse_iterator(reverse_iterator const&) = default; 147   reverse_iterator(reverse_iterator const&) = default;
148   reverse_iterator& operator=( 148   reverse_iterator& operator=(
149   reverse_iterator const&) = default; 149   reverse_iterator const&) = default;
150   150  
151   explicit 151   explicit
HITCBC 152   5 reverse_iterator( 152   5 reverse_iterator(
153   iterator it) noexcept 153   iterator it) noexcept
HITCBC 154   5 : ph_(it.ph_) 154   5 : ph_(it.ph_)
HITCBC 155   5 , i_(it.i_) 155   5 , i_(it.i_)
156   { 156   {
HITCBC 157   5 } 157   5 }
158   158  
159   bool 159   bool
HITCBC 160   5 operator==( 160   5 operator==(
161   reverse_iterator const& other) const noexcept 161   reverse_iterator const& other) const noexcept
162   { 162   {
163   // If this assert goes off, it means you 163   // If this assert goes off, it means you
164   // are trying to compare iterators from 164   // are trying to compare iterators from
165   // different containers, which is undefined! 165   // different containers, which is undefined!
HITCBC 166   5 BOOST_ASSERT(ph_ == other.ph_); 166   5 BOOST_ASSERT(ph_ == other.ph_);
167   167  
HITCBC 168   5 return i_ == other.i_; 168   5 return i_ == other.i_;
169   } 169   }
170   170  
171   bool 171   bool
HITCBC 172   1 operator!=( 172   1 operator!=(
173   reverse_iterator const& other) const noexcept 173   reverse_iterator const& other) const noexcept
174   { 174   {
HITCBC 175   1 return !(*this == other); 175   1 return !(*this == other);
176   } 176   }
177   177  
178   BOOST_HTTP_DECL 178   BOOST_HTTP_DECL
179   reference 179   reference
180   operator*() const noexcept; 180   operator*() const noexcept;
181   181  
182   pointer 182   pointer
HITCBC 183   24 operator->() const noexcept 183   24 operator->() const noexcept
184   { 184   {
HITCBC 185   24 return *(*this); 185   24 return *(*this);
186   } 186   }
187   187  
188   reverse_iterator& 188   reverse_iterator&
HITCBC 189   3 operator++() noexcept 189   3 operator++() noexcept
190   { 190   {
HITCBC 191   3 BOOST_ASSERT(i_ > 0); 191   3 BOOST_ASSERT(i_ > 0);
HITCBC 192   3 --i_; 192   3 --i_;
HITCBC 193   3 return *this; 193   3 return *this;
194   } 194   }
195   195  
196   reverse_iterator 196   reverse_iterator
HITCBC 197   1 operator++(int) noexcept 197   1 operator++(int) noexcept
198   { 198   {
HITCBC 199   1 auto temp = *this; 199   1 auto temp = *this;
HITCBC 200   1 ++(*this); 200   1 ++(*this);
HITCBC 201   1 return temp; 201   1 return temp;
202   } 202   }
203   203  
204   reverse_iterator& 204   reverse_iterator&
HITCBC 205   3 operator--() noexcept 205   3 operator--() noexcept
206   { 206   {
HITCBC 207   3 BOOST_ASSERT(i_ < ph_->count); 207   3 BOOST_ASSERT(i_ < ph_->count);
HITCBC 208   3 ++i_; 208   3 ++i_;
HITCBC 209   3 return *this; 209   3 return *this;
210   } 210   }
211   211  
212   reverse_iterator 212   reverse_iterator
HITCBC 213   1 operator--(int) noexcept 213   1 operator--(int) noexcept
214   { 214   {
HITCBC 215   1 auto temp = *this; 215   1 auto temp = *this;
HITCBC 216   1 --(*this); 216   1 --(*this);
HITCBC 217   1 return temp; 217   1 return temp;
218   } 218   }
219   }; 219   };
220   220  
221   //------------------------------------------------ 221   //------------------------------------------------
222   // 222   //
223   // subrange 223   // subrange
224   // 224   //
225   //------------------------------------------------ 225   //------------------------------------------------
226   226  
227   class fields_base::subrange 227   class fields_base::subrange
228   { 228   {
229   detail::header const* ph_ = nullptr; 229   detail::header const* ph_ = nullptr;
230   std::size_t i_ = 0; 230   std::size_t i_ = 0;
231   231  
232   friend class fields_base; 232   friend class fields_base;
233   friend struct detail::header; 233   friend struct detail::header;
234   234  
HITCBC 235   21 subrange( 235   21 subrange(
236   detail::header const* ph, 236   detail::header const* ph,
237   std::size_t i) noexcept 237   std::size_t i) noexcept
HITCBC 238   21 : ph_(ph) 238   21 : ph_(ph)
HITCBC 239   21 , i_(i) 239   21 , i_(i)
240   { 240   {
HITCBC 241   21 } 241   21 }
242   242  
243   public: 243   public:
244   class iterator; 244   class iterator;
245   //class reverse_iterator; 245   //class reverse_iterator;
246   using const_iterator = iterator; 246   using const_iterator = iterator;
247   using value_type = std::string; 247   using value_type = std::string;
248   using reference = core::string_view; 248   using reference = core::string_view;
249   using const_reference = reference; 249   using const_reference = reference;
250   using size_type = std::size_t; 250   using size_type = std::size_t;
251   using difference_type = std::ptrdiff_t; 251   using difference_type = std::ptrdiff_t;
252   252  
253   /** Constructor 253   /** Constructor
254   254  
255   Default-constructed subranges are empty. 255   Default-constructed subranges are empty.
256   */ 256   */
257   subrange() noexcept = default; 257   subrange() noexcept = default;
258   258  
259   subrange(subrange const&) noexcept = default; 259   subrange(subrange const&) noexcept = default;
260   subrange& operator=( 260   subrange& operator=(
261   subrange const&) noexcept = default; 261   subrange const&) noexcept = default;
262   262  
263   iterator begin() const noexcept; 263   iterator begin() const noexcept;
264   iterator end() const noexcept; 264   iterator end() const noexcept;
265   }; 265   };
266   266  
267   //------------------------------------------------ 267   //------------------------------------------------
268   // 268   //
269   // subrange::iterator 269   // subrange::iterator
270   // 270   //
271   //------------------------------------------------ 271   //------------------------------------------------
272   272  
273   class fields_base::subrange:: 273   class fields_base::subrange::
274   iterator 274   iterator
275   { 275   {
276   detail::header const* ph_ = nullptr; 276   detail::header const* ph_ = nullptr;
277   std::size_t i_ = 0; 277   std::size_t i_ = 0;
278   278  
279   friend class fields_base::subrange; 279   friend class fields_base::subrange;
280   280  
281   BOOST_HTTP_DECL 281   BOOST_HTTP_DECL
282   iterator( 282   iterator(
283   detail::header const* ph, 283   detail::header const* ph,
284   std::size_t i) noexcept; 284   std::size_t i) noexcept;
285   285  
286   // end 286   // end
287   BOOST_HTTP_DECL 287   BOOST_HTTP_DECL
288   iterator( 288   iterator(
289   detail::header const* ph) noexcept; 289   detail::header const* ph) noexcept;
290   290  
291   public: 291   public:
292   using value_type = std::string; 292   using value_type = std::string;
293   using reference = core::string_view; 293   using reference = core::string_view;
294   using pointer = void const*; 294   using pointer = void const*;
295   using difference_type = 295   using difference_type =
296   std::ptrdiff_t; 296   std::ptrdiff_t;
297   using iterator_category = 297   using iterator_category =
298   std::forward_iterator_tag; 298   std::forward_iterator_tag;
299   299  
300   iterator() = default; 300   iterator() = default;
301   iterator(iterator const&) = default; 301   iterator(iterator const&) = default;
302   iterator& operator=( 302   iterator& operator=(
303   iterator const&) = default; 303   iterator const&) = default;
304   304  
305   // conversion to regular iterator 305   // conversion to regular iterator
306   operator 306   operator
307   fields_base:: 307   fields_base::
308   iterator() const noexcept 308   iterator() const noexcept
309   { 309   {
310   return {ph_, i_}; 310   return {ph_, i_};
311   } 311   }
312   312  
313   bool 313   bool
HITCBC 314   48 operator==( 314   48 operator==(
315   iterator const& other) const noexcept 315   iterator const& other) const noexcept
316   { 316   {
317   // If this assert goes off, it means you 317   // If this assert goes off, it means you
318   // are trying to compare iterators from 318   // are trying to compare iterators from
319   // different containers, which is undefined! 319   // different containers, which is undefined!
HITCBC 320   48 BOOST_ASSERT(ph_ == other.ph_); 320   48 BOOST_ASSERT(ph_ == other.ph_);
321   321  
HITCBC 322   48 return i_ == other.i_; 322   48 return i_ == other.i_;
323   } 323   }
324   324  
325   bool 325   bool
HITCBC 326   48 operator!=( 326   48 operator!=(
327   iterator const& other) const noexcept 327   iterator const& other) const noexcept
328   { 328   {
HITCBC 329   48 return !(*this == other); 329   48 return !(*this == other);
330   } 330   }
331   331  
332   BOOST_HTTP_DECL 332   BOOST_HTTP_DECL
333   reference const 333   reference const
334   operator*() const noexcept; 334   operator*() const noexcept;
335   335  
336   reference const 336   reference const
337   operator->() const noexcept 337   operator->() const noexcept
338   { 338   {
339   return *(*this); 339   return *(*this);
340   } 340   }
341   341  
342   BOOST_HTTP_DECL 342   BOOST_HTTP_DECL
343   iterator& 343   iterator&
344   operator++() noexcept; 344   operator++() noexcept;
345   345  
346   iterator 346   iterator
347   operator++(int) noexcept 347   operator++(int) noexcept
348   { 348   {
349   auto temp = *this; 349   auto temp = *this;
350   ++(*this); 350   ++(*this);
351   return temp; 351   return temp;
352   } 352   }
353   }; 353   };
354   354  
355   inline 355   inline
356   auto 356   auto
HITCBC 357   21 fields_base:: 357   21 fields_base::
358   subrange:: 358   subrange::
359   begin() const noexcept -> 359   begin() const noexcept ->
360   iterator 360   iterator
361   { 361   {
HITCBC 362   21 return {ph_, i_}; 362   21 return {ph_, i_};
363   } 363   }
364   364  
365   inline 365   inline
366   auto 366   auto
HITCBC 367   21 fields_base:: 367   21 fields_base::
368   subrange:: 368   subrange::
369   end() const noexcept -> 369   end() const noexcept ->
370   iterator 370   iterator
371   { 371   {
HITCBC 372   21 return {ph_}; 372   21 return {ph_};
373   } 373   }
374   374  
375   //------------------------------------------------ 375   //------------------------------------------------
376   376  
377   inline 377   inline
378   fields_base:: 378   fields_base::
379   value_type:: 379   value_type::
380   operator 380   operator
381   fields_base:: 381   fields_base::
382   reference() const noexcept 382   reference() const noexcept
383   { 383   {
384   return reference{ 384   return reference{
385   id, name, value}; 385   id, name, value};
386   } 386   }
387   387  
388   //------------------------------------------------ 388   //------------------------------------------------
389   389  
390   inline 390   inline
391   auto 391   auto
HITCBC 392   762 fields_base:: 392   762 fields_base::
393   begin() const noexcept -> 393   begin() const noexcept ->
394   iterator 394   iterator
395   { 395   {
HITCBC 396   762 return iterator(&h_, 0); 396   762 return iterator(&h_, 0);
397   } 397   }
398   398  
399   inline 399   inline
400   auto 400   auto
HITCBC 401   939 fields_base:: 401   939 fields_base::
402   end() const noexcept -> 402   end() const noexcept ->
403   iterator 403   iterator
404   { 404   {
HITCBC 405   939 return iterator(&h_, h_.count); 405   939 return iterator(&h_, h_.count);
406   } 406   }
407   407  
408   inline 408   inline
409   auto 409   auto
HITCBC 410   3 fields_base:: 410   3 fields_base::
411   rbegin() const noexcept -> 411   rbegin() const noexcept ->
412   reverse_iterator 412   reverse_iterator
413   { 413   {
HITCBC 414   3 return reverse_iterator(end()); 414   3 return reverse_iterator(end());
415   } 415   }
416   416  
417   inline 417   inline
418   auto 418   auto
HITCBC 419   2 fields_base:: 419   2 fields_base::
420   rend() const noexcept -> 420   rend() const noexcept ->
421   reverse_iterator 421   reverse_iterator
422   { 422   {
HITCBC 423   2 return reverse_iterator(begin()); 423   2 return reverse_iterator(begin());
424   } 424   }
425   425  
426   } // http 426   } // http
427   } // boost 427   } // boost
428   428  
429   #endif 429   #endif