ring_span.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2015 Arthur O'Dwyer
3 // Copyright 2017-2019 by Martin Moene
4 //
5 // https://github.com/martinmoene/ring-span-lite
6 //
7 // Distributed under the Boost Software License, Version 1.0.
8 // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 
10 #pragma once
11 
12 #ifndef NONSTD_RING_SPAN_LITE_HPP
13 #define NONSTD_RING_SPAN_LITE_HPP
14 
15 #define ring_span_lite_MAJOR 0
16 #define ring_span_lite_MINOR 3
17 #define ring_span_lite_PATCH 0
18 
19 #define ring_span_lite_VERSION nsrs_STRINGIFY(ring_span_lite_MAJOR) "." nsrs_STRINGIFY(ring_span_lite_MINOR) "." nsrs_STRINGIFY(ring_span_lite_PATCH)
20 
21 #define nsrs_STRINGIFY( x ) nsrs_STRINGIFY_( x )
22 #define nsrs_STRINGIFY_( x ) #x
23 
24 // ring-span-lite configuration:
25 
26 #define nsrs_RING_SPAN_DEFAULT 0
27 #define nsrs_RING_SPAN_NONSTD 1
28 #define nsrs_RING_SPAN_STD 2
29 
30 #if !defined( nsrs_CONFIG_SELECT_RING_SPAN )
31 # define nsrs_CONFIG_SELECT_RING_SPAN ( nsrs_HAVE_STD_RING_SPAN ? nsrs_RING_SPAN_STD : nsrs_RING_SPAN_NONSTD )
32 #endif
33 
34 #ifndef nsrs_CONFIG_STRICT_P0059
35 # define nsrs_CONFIG_STRICT_P0059 0
36 #endif
37 
38 #define nsrs_RING_SPAN_LITE_EXTENSION (! nsrs_CONFIG_STRICT_P0059)
39 
40 #ifndef nsrs_CONFIG_CONFIRMS_COMPILATION_ERRORS
41 # define nsrs_CONFIG_CONFIRMS_COMPILATION_ERRORS 0
42 #endif
43 
44 // C++ language version detection (C++20 is speculative):
45 // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
46 
47 #ifndef nsrs_CPLUSPLUS
48 # if defined(_MSVC_LANG ) && !defined(__clang__)
49 # define nsrs_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
50 # else
51 # define nsrs_CPLUSPLUS __cplusplus
52 # endif
53 #endif
54 
55 #define nsrs_CPP98_OR_GREATER ( nsrs_CPLUSPLUS >= 199711L )
56 #define nsrs_CPP11_OR_GREATER ( nsrs_CPLUSPLUS >= 201103L )
57 #define nsrs_CPP11_OR_GREATER_ ( nsrs_CPLUSPLUS >= 201103L )
58 #define nsrs_CPP14_OR_GREATER ( nsrs_CPLUSPLUS >= 201402L )
59 #define nsrs_CPP17_OR_GREATER ( nsrs_CPLUSPLUS >= 201703L )
60 #define nsrs_CPP20_OR_GREATER ( nsrs_CPLUSPLUS >= 202000L )
61 
62 // Use C++XX std::ring_span if available and requested:
63 
64 #define nsrs_HAVE_STD_RING_SPAN 0
65 
66 //#if nsrs_CPP17_OR_GREATER && defined(__has_include )
67 //# if __has_include( <any> )
68 //# define nsrs_HAVE_STD_RING_SPAN 1
69 //# else
70 //# define nsrs_HAVE_STD_RING_SPAN 0
71 //# endif
72 //#else
73 //# define nsrs_HAVE_STD_RING_SPAN 0
74 //#endif
75 
76 #define nsrs_USES_STD_RING_SPAN ( (nsrs_CONFIG_SELECT_RING_SPAN == nsrs_RING_SPAN_STD) || ((nsrs_CONFIG_SELECT_RING_SPAN == nsrs_RING_SPAN_DEFAULT) && nsrs_HAVE_STD_RING_SPAN) )
77 
78 // Compiler versions:
79 //
80 // MSVC++ 6.0 _MSC_VER == 1200 nsrs_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
81 // MSVC++ 7.0 _MSC_VER == 1300 nsrs_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
82 // MSVC++ 7.1 _MSC_VER == 1310 nsrs_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
83 // MSVC++ 8.0 _MSC_VER == 1400 nsrs_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
84 // MSVC++ 9.0 _MSC_VER == 1500 nsrs_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
85 // MSVC++ 10.0 _MSC_VER == 1600 nsrs_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
86 // MSVC++ 11.0 _MSC_VER == 1700 nsrs_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
87 // MSVC++ 12.0 _MSC_VER == 1800 nsrs_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
88 // MSVC++ 14.0 _MSC_VER == 1900 nsrs_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
89 // ............ _MSVC_LANG: 201402 for -std:c++14, default
90 // MSVC++ 14.1 _MSC_VER >= 1910 nsrs_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
91 // ............ _MSVC_LANG: 201402 for -std:c++14, default
92 // ............ _MSVC_LANG: 201703 for -std:c++17
93 // MSVC++ 14.2 _MSC_VER >= 1920 nsrs_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
94 
95 #if defined(_MSC_VER ) && !defined(__clang__)
96 # define nsrs_COMPILER_MSVC_VER (_MSC_VER )
97 # define nsrs_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
98 #else
99 # define nsrs_COMPILER_MSVC_VER 0
100 # define nsrs_COMPILER_MSVC_VERSION 0
101 #endif
102 
103 #define nsrs_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
104 
105 #if defined(__clang__)
106 # define nsrs_COMPILER_CLANG_VERSION nsrs_COMPILER_VERSION( __clang_major__, __clang_minor__, __clang_patchlevel__ )
107 #else
108 # define nsrs_COMPILER_CLANG_VERSION 0
109 #endif
110 
111 #if defined(__GNUC__) && !defined(__clang__)
112 # define nsrs_COMPILER_GNUC_VERSION nsrs_COMPILER_VERSION( __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ )
113 #else
114 # define nsrs_COMPILER_GNUC_VERSION 0
115 #endif
116 
117 // half-open range [lo..hi):
118 //#define nsrs_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
119 
120 // Presence of language and library features:
121 
122 #ifdef _HAS_CPP0X
123 # define nsrs_HAS_CPP0X _HAS_CPP0X
124 #else
125 # define nsrs_HAS_CPP0X 0
126 #endif
127 
128 // Unless defined otherwise below, consider VC14 as C++11 for ring-span-lite:
129 
130 #if nsrs_COMPILER_MSVC_VER >= 1900
131 # undef nsrs_CPP11_OR_GREATER
132 # define nsrs_CPP11_OR_GREATER 1
133 #endif
134 
135 #define nsrs_CPP11_90 (nsrs_CPP11_OR_GREATER_ || nsrs_COMPILER_MSVC_VER >= 1500)
136 #define nsrs_CPP11_100 (nsrs_CPP11_OR_GREATER_ || nsrs_COMPILER_MSVC_VER >= 1600)
137 #define nsrs_CPP11_110 (nsrs_CPP11_OR_GREATER_ || nsrs_COMPILER_MSVC_VER >= 1700)
138 #define nsrs_CPP11_120 (nsrs_CPP11_OR_GREATER_ || nsrs_COMPILER_MSVC_VER >= 1800)
139 #define nsrs_CPP11_140 (nsrs_CPP11_OR_GREATER_ || nsrs_COMPILER_MSVC_VER >= 1900)
140 
141 #define nsrs_CPP14_000 (nsrs_CPP14_OR_GREATER)
142 #define nsrs_CPP17_000 (nsrs_CPP17_OR_GREATER)
143 
144 // Presence of C++11 language features:
145 
146 // half-open range [lo..hi):
147 #define nsrs_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
148 
149 // Presence of C++11 language features:
150 
151 #define nsrs_HAVE_CONSTEXPR_11 nsrs_CPP11_140
152 #define nsrs_HAVE_IS_DEFAULT nsrs_CPP11_140
153 #define nsrs_HAVE_IS_DELETE nsrs_CPP11_140
154 #define nsrs_HAVE_NOEXCEPT nsrs_CPP11_140
155 #define nsrs_HAVE_NULLPTR nsrs_CPP11_100
156 
157 // Presence of C++14 language features:
158 
159 #define nsrs_HAVE_CONSTEXPR_14 nsrs_CPP14_000
160 
161 // Presence of C++17 language features:
162 // no tag
163 
164 // Presence of C++ library features:
165 // no tag
166 
167 // Compiler warning suppression:
168 
169 #if defined(__clang__)
170 # pragma clang diagnostic push
171 # pragma clang diagnostic ignored "-Wundef"
172 # define nsrs_RESTORE_WARNINGS() _Pragma( "clang diagnostic pop" )
173 
174 #elif defined __GNUC__
175 # pragma GCC diagnostic push
176 # pragma GCC diagnostic ignored "-Wundef"
177 # define nsrs_RESTORE_WARNINGS() _Pragma( "GCC diagnostic pop" )
178 
179 #elif nsrs_COMPILER_MSVC_VERSION >= 140
180 # define nsrs_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes))
181 # define nsrs_RESTORE_WARNINGS() __pragma(warning(pop ))
182 
183 // Suppress the following MSVC warnings:
184 // - C4345: initialization behavior changed
185 //
186 // Suppress the following MSVC GSL warnings:
187 // - C26439, gsl::f.6 : special function 'function' can be declared 'noexcept'
188 // - C26440, gsl::f.6 : function 'function' can be declared 'noexcept'
189 // - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
190 // use brace initialization, gsl::narrow_cast or gsl::narrow
191 // - C26473: gsl::t.1 : don't cast between pointer types where the source type and the target type are the same
192 // - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
193 // - C26490: gsl::t.1 : don't use reinterpret_cast
194 
195 nsrs_DISABLE_MSVC_WARNINGS( 4345 26439 26440 26472 26473 26481 26490 )
196 
197 #else
198 # define nsrs_RESTORE_WARNINGS() /*empty*/
199 #endif
200 
201 // C++ feature usage:
202 
203 #if nsrs_HAVE_CONSTEXPR_11
204 # define nsrs_constexpr constexpr
205 #else
206 # define nsrs_constexpr /*constexpr*/
207 #endif
208 
209 #if nsrs_HAVE_CONSTEXPR_14
210 # define nsrs_constexpr14 constexpr
211 #else
212 # define nsrs_constexpr14 /*constexpr*/
213 #endif
214 
215 #if nsrs_HAVE_NOEXCEPT
216 # define nsrs_noexcept noexcept
217 # define nsrs_noexcept_op noexcept
218 #else
219 # define nsrs_noexcept /*noexcept*/
220 # define nsrs_noexcept_op(expr) /*noexcept(expr)*/
221 #endif
222 
223 #if nsrs_HAVE_NULLPTR
224 # define nsrs_nullptr nullptr
225 #else
226 # define nsrs_nullptr NULL
227 #endif
228 
229 // Method enabling
230 
231 #if nsrs_CPP11_OR_GREATER
232 
233 #define nsrs_REQUIRES_0(...) \
234  template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
235 
236 #define nsrs_REQUIRES_T(...) \
237  , typename std::enable_if< (__VA_ARGS__), int >::type = 0
238 
239 #endif
240 
241 // includes:
242 
243 #include <cassert>
244 #include <iterator>
245 #include <utility>
246 
247 // additional includes:
248 
249 #if ! nsrs_CPP11_OR_GREATER
250 # include <algorithm> // std::swap() until C++11
251 #endif
252 
253 namespace nonstd { namespace ring_span_lite {
254 
255 // type traits C++11:
256 
257 namespace std11 {
258 
259 #if nsrs_CPP11_OR_GREATER
260 using std::move;
261 #else
262 template< typename T > T const & move( T const & t ) { return t; }
263 #endif
264 
265 template< bool B, class T, class F >
266 struct conditional { typedef T type; };
267 
268 template< class T, class F >
269 struct conditional<false, T, F> { typedef F type; };
270 
271 } // namespace std11
272 
273 // type traits C++17:
274 
275 namespace std17 {
276 
277 #if nsrs_CPP17_OR_GREATER
278 
279 using std::is_swappable;
280 using std::is_nothrow_swappable;
281 
282 #elif nsrs_CPP11_OR_GREATER
283 
284 namespace detail {
285 
286 using std::swap;
287 
288 struct is_swappable
289 {
290  template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
291  static std::true_type test( int );
292 
293  template< typename >
294  static std::false_type test(...);
295 };
296 
297 struct is_nothrow_swappable
298 {
299  // wrap noexcept(epr) in separate function as work-around for VC140 (VS2015):
300 
301  template< typename T >
302  static constexpr bool test()
303  {
304  return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
305  }
306 
307  template< typename T >
308  static auto test( int ) -> std::integral_constant<bool, test<T>()>{}
309 
310  template< typename >
311  static std::false_type test(...);
312 };
313 
314 } // namespace detail
315 
316 // is [nothow] swappable:
317 
318 template< typename T >
319 struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
320 
321 template< typename T >
322 struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
323 
324 #endif // nsrs_CPP17_OR_GREATER
325 
326 } // namespace std17
327 
328 //
329 // element extraction policies:
330 //
331 
332 template< class T >
334 {
335  typedef void return_type;
336 
337  void operator()( T & ) const nsrs_noexcept {}
338 };
339 
340 template< class T >
342 {
343  typedef T return_type;
344 
345  T operator()( T & t ) const
346  {
347  return std11::move( t );
348  }
349 };
350 
351 template< class T >
353 {
354  typedef T return_type;
355 
356 #if nsrs_RING_SPAN_LITE_EXTENSION
357 # if nsrs_CPP11_OR_GREATER
358  copy_popper( T t )
359  : m_copy( std::move(t) )
360  {}
361 # else
362  copy_popper( T const & t )
363  : m_copy( t )
364  {}
365 # endif
366 #else
367  copy_popper( T && t )
368  : copy( std::move(t) )
369  {}
370 #endif
371 
372  T operator()( T & t ) const
373  {
374  using std::swap;
375  T result( m_copy ); swap( t, result ); return result;
376  }
377 
379 };
380 
381 // forward-declare iterator:
382 
383 namespace detail {
384 
385 template< class, bool >
387 
388 }
389 
390 //
391 // ring span:
392 //
393 template< class T, class Popper = default_popper<T> >
395 {
396 public:
397  typedef T value_type;
398  typedef T * pointer;
399  typedef T & reference;
400  typedef T const & const_reference;
401 
402  typedef std::size_t size_type;
403 
405 
408 
409 #if nsrs_RING_SPAN_LITE_EXTENSION
410  typedef std::reverse_iterator<iterator > reverse_iterator;
411  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
412 #endif
413 
414  // construction:
415 
416  template< class ContiguousIterator >
418  ContiguousIterator begin
419  , ContiguousIterator end
420  , Popper popper = Popper()
421  ) nsrs_noexcept
422  : m_data ( &* begin )
423  , m_size ( 0 )
424  , m_capacity ( static_cast<size_type>( end - begin ) )
425  , m_front_idx( 0 )
426  , m_popper ( std11::move( popper ) )
427  {}
428 
429  template< class ContiguousIterator >
431  ContiguousIterator begin
432  , ContiguousIterator end
433  , ContiguousIterator first
434  , size_type size
435  , Popper popper = Popper()
436  ) nsrs_noexcept
437  : m_data ( &* begin )
438  , m_size ( size )
439  , m_capacity ( static_cast<size_type>( end - begin ) )
440  , m_front_idx( static_cast<size_type>( first - begin ) )
441  , m_popper ( std11::move( popper ) )
442  {
443  assert( m_size <= m_capacity );
444  }
445 
446 #if nsrs_HAVE_IS_DEFAULT
447  ring_span( ring_span && ) = default;
448  ring_span& operator=( ring_span && ) = default;
449 #else
450 private:
451  ring_span( ring_span const & );
452  ring_span & operator=( ring_span const & );
453 public:
454 #endif
455 
456  // observers:
457 
458  bool empty() const nsrs_noexcept
459  {
460  return m_size == 0;
461  }
462 
463  bool full() const nsrs_noexcept
464  {
465  return m_size == m_capacity;
466  }
467 
468  size_type size() const nsrs_noexcept
469  {
470  return m_size;
471  }
472 
473  size_type capacity() const nsrs_noexcept
474  {
475  return m_capacity;
476  }
477 
478  // element access:
479 
480 #if nsrs_RING_SPAN_LITE_EXTENSION
481  reference operator[]( size_type idx ) nsrs_noexcept
482  {
483  assert( idx < m_size ); return at_(idx);
484  }
485 
486  const_reference operator[]( size_type idx ) const nsrs_noexcept
487  {
488  assert( idx < m_size ); return at_(idx);
489  }
490 #endif
491 
492  reference front() nsrs_noexcept
493  {
494  return *begin();
495  }
496 
497  const_reference front() const nsrs_noexcept
498  {
499  return *begin();
500  }
501 
502  reference back() nsrs_noexcept
503  {
504  return *(--end());
505  }
506 
507  const_reference back() const nsrs_noexcept
508  {
509  return *(--end());
510  }
511 
512  // iteration:
513 
514  iterator begin() nsrs_noexcept
515  {
516  return iterator( 0, this );
517  }
518 
519  const_iterator begin() const nsrs_noexcept
520  {
521  return cbegin();
522  }
523 
524  const_iterator cbegin() const nsrs_noexcept
525  {
526  return const_iterator( 0, this );
527  }
528 
529  iterator end() nsrs_noexcept
530  {
531  return iterator( size(), this );
532  }
533 
534  const_iterator end() const nsrs_noexcept
535  {
536  return cend();
537  }
538 
539  const_iterator cend() const nsrs_noexcept
540  {
541  return const_iterator( size(), this );
542  }
543 
544 #if nsrs_RING_SPAN_LITE_EXTENSION
545 
546  reverse_iterator rbegin() nsrs_noexcept
547  {
548  return reverse_iterator( end() );
549  }
550 
551  reverse_iterator rend() nsrs_noexcept
552  {
553  return reverse_iterator( begin() );
554  }
555 
556  const_reverse_iterator rbegin() const nsrs_noexcept
557  {
558  return crbegin();
559  }
560 
561  const_reverse_iterator rend() const nsrs_noexcept
562  {
563  return crend();
564  }
565 
566  const_reverse_iterator crbegin() const nsrs_noexcept
567  {
568  return const_reverse_iterator( cend() );
569  }
570 
571  const_reverse_iterator crend() const nsrs_noexcept
572  {
573  return const_reverse_iterator(cbegin());
574  }
575 #endif
576 
577  // element insertion, extraction:
578 
579  typename Popper::return_type pop_front()
580  {
581  assert( ! empty() );
582 
583  reference element = front_();
584  increment_front_();
585 
586  return m_popper( element );
587  }
588 
589 #if nsrs_RING_SPAN_LITE_EXTENSION
590  typename Popper::return_type pop_back()
591  {
592  assert( ! empty() );
593 
594  reference element = back_();
595  decrement_back_();
596 
597  return m_popper( element );
598  }
599 #endif
600 
601 #if nsrs_CPP11_OR_GREATER
602  nsrs_REQUIRES_0( std::is_copy_assignable<T>::value )
603  void push_back( value_type const & value) noexcept( std::is_nothrow_copy_assignable<T>::value )
604 #else
605  void push_back( value_type const & value )
606 #endif
607  {
608  if ( full() ) increment_front_and_back_();
609  else increment_back_();
610 
611  back_() = value;
612  }
613 
614 #if nsrs_CPP11_OR_GREATER
615  nsrs_REQUIRES_0( std::is_move_assignable<T>::value )
616  void push_back( value_type && value ) noexcept( std::is_nothrow_move_assignable<T>::value )
617  {
618  if ( full() ) increment_front_and_back_();
619  else increment_back_();
620 
621  back_() = std::move( value );
622  }
623 
624  template< typename... Args
625  nsrs_REQUIRES_T(
628  )
629  >
630  void emplace_back( Args &&... args ) noexcept
631  (
634  )
635  {
636  if ( full() ) increment_front_and_back_();
637  else increment_back_();
638 
639  back_() = T( std::forward<Args>(args)...);
640  }
641 #endif
642 
643 #if nsrs_RING_SPAN_LITE_EXTENSION
644 
645 #if nsrs_CPP11_OR_GREATER
646  nsrs_REQUIRES_0( std::is_copy_assignable<T>::value )
647  void push_front( T const & value ) noexcept(( std::is_nothrow_copy_assignable<T>::value ))
648 #else
649  void push_front( T const & value )
650 #endif
651  {
652  if ( full() ) decrement_front_and_back_();
653  else decrement_front_();
654 
655  front_() = value;
656  }
657 
658 #if nsrs_CPP11_OR_GREATER
659  nsrs_REQUIRES_0( std::is_move_assignable<T>::value )
660  void push_front( T && value ) noexcept(( std::is_nothrow_move_assignable<T>::value ))
661  {
662  if ( full() ) decrement_front_and_back_();
663  else decrement_front_();
664 
665  front_() = std::move(value);
666  }
667 
668  template< typename... Args
669  nsrs_REQUIRES_T(
672  )
673  >
674  void emplace_front( Args&&... args ) noexcept
675  (
678  )
679  {
680  if ( full() ) decrement_front_and_back_();
681  else decrement_front_();
682 
683  front_() = T( std::forward<Args>(args)...);
684  }
685 #endif
686 #endif // nsrs_RING_SPAN_LITE_EXTENSION
687 
688  // swap:
689 
690  void swap( type & rhs )
691 #if nsrs_CPP11_OR_GREATER
692  noexcept(
694  )
695 #endif
696  {
697  using std::swap;
698  swap( m_data , rhs.m_data );
699  swap( m_size , rhs.m_size );
700  swap( m_capacity , rhs.m_capacity );
701  swap( m_front_idx, rhs.m_front_idx );
702  swap( m_popper , rhs.m_popper );
703  }
704 
705 private:
706  friend class detail::ring_iterator<ring_span, true >; // const_iterator;
707  friend class detail::ring_iterator<ring_span, false>; // iterator;
708 
709  size_type normalize_( size_type const idx ) const nsrs_noexcept
710  {
711  return idx % m_capacity;
712  }
713 
714  reference at_( size_type idx ) nsrs_noexcept
715  {
716  return m_data[ normalize_(m_front_idx + idx) ];
717  }
718 
719  const_reference at_( size_type idx ) const nsrs_noexcept
720  {
721  return m_data[ normalize_(m_front_idx + idx) ];
722  }
723 
724  reference front_() nsrs_noexcept
725  {
726  return *( m_data + m_front_idx );
727  }
728 
729  const_reference front_() const nsrs_noexcept
730  {
731  return *( m_data + m_front_idx );
732  }
733 
734  reference back_() nsrs_noexcept
735  {
736  return *( m_data + normalize_(m_front_idx + m_size - 1) );
737  }
738 
739  const_reference back_() const nsrs_noexcept
740  {
741  return *( m_data + normalize_(m_front_idx + m_size - 1) );
742  }
743 
745  {
746  m_front_idx = normalize_(m_front_idx + 1);
747  --m_size;
748  }
749 
751  {
752  m_front_idx = normalize_(m_front_idx + m_capacity - 1);
753  ++m_size;
754  }
755 
757  {
758  ++m_size;
759  }
760 
762  {
763  --m_size;
764  }
765 
767  {
768  m_front_idx = normalize_( m_front_idx + 1 );
769  }
770 
772  {
773  m_front_idx = normalize_( m_front_idx + m_capacity - 1 );
774  }
775 
776 private:
777  pointer m_data;
778  size_type m_size;
779  size_type m_capacity;
780  size_type m_front_idx;
781  Popper m_popper;
782 };
783 
784 // swap:
785 
786 template< class T, class Popper >
787 inline void swap( ring_span<T,Popper> & lhs, ring_span<T,Popper> & rhs ) nsrs_noexcept_op( nsrs_noexcept_op( lhs.swap(rhs) ) )
788 {
789  lhs.swap(rhs);
790 }
791 
792 namespace detail {
793 
794 //
795 // ring iterator:
796 //
797 #if 0
798 template< class RS, bool is_const >
799 class ring_iterator : public std::iterator
800 <
801  std::random_access_iterator_tag
802  , typename std11::conditional<is_const, const typename RS::value_type, typename RS::value_type>::type
803 >
804 #endif
805 
806 template< class RS, bool is_const >
807 class ring_iterator
808 {
809 public:
811 
812  typedef std::ptrdiff_t difference_type;
813  typedef typename RS::value_type value_type;
814 
817  typedef std::random_access_iterator_tag iterator_category;
818 
819 #if nsrs_CPP11_OR_GREATER
820  ring_iterator() = default;
821 #else
822  ring_iterator() : m_idx(), m_rs() {}
823 #endif
824 
825 #if nsrs_RING_SPAN_LITE_EXTENSION
826  // conversion to const iterator:
827 
829  {
830  return ring_iterator<RS, true>( m_idx, m_rs );
831  }
832 #endif
833 
834  // access content:
835 
836  reference operator*() const nsrs_noexcept
837  {
838  return m_rs->at_( m_idx );
839  }
840 
841  // advance iterator:
842 
844  {
845  ++m_idx; return *this;
846  }
847 
849  {
850  type r(*this); ++*this; return r;
851  }
852 
854  {
855  --m_idx; return *this;
856  }
857 
859  {
860  type r(*this); --*this; return r;
861  }
862 
863 #if defined(__clang__) || defined(__GNUC__)
864 # pragma GCC diagnostic push
865 # pragma GCC diagnostic ignored "-Wsign-conversion"
866 #endif
867 
868  type & operator+=( int i ) nsrs_noexcept
869  {
870  m_idx += i; return *this;
871  }
872 
873  type & operator-=( int i ) nsrs_noexcept
874  {
875  m_idx -= i; return *this;
876  }
877 
878 #if defined(__clang__) || defined(__GNUC__)
879 # pragma GCC diagnostic pop
880 #endif
881 
882 #if nsrs_RING_SPAN_LITE_EXTENSION
883 
884  template< bool C >
885  difference_type operator-( ring_iterator<RS,C> const & rhs ) const nsrs_noexcept
886  {
887  return static_cast<difference_type>( this->m_idx ) - static_cast<difference_type>( rhs.m_idx );
888  }
889 #endif
890 
891  // comparison:
892 
893  template< bool C >
894  bool operator<( ring_iterator<RS,C> const & rhs ) const nsrs_noexcept
895  {
896  assert( this->m_rs == rhs.m_rs ); return ( this->m_idx < rhs.m_idx );
897  }
898 
899  template< bool C >
900  bool operator==( ring_iterator<RS,C> const & rhs ) const nsrs_noexcept
901  {
902  assert( this->m_rs == rhs.m_rs ); return ( this->m_idx == rhs.m_idx );
903  }
904 
905  // other comparisons expressed in <, ==:
906 
907  template< bool C >
908  inline bool operator!=( ring_iterator<RS,C> const & rhs ) const nsrs_noexcept
909  {
910  return ! ( *this == rhs );
911  }
912 
913  template< bool C >
914  inline bool operator<=( ring_iterator<RS,C> const & rhs ) const nsrs_noexcept
915  {
916  return ! ( rhs < *this );
917  }
918 
919  template< bool C >
920  inline bool operator>( ring_iterator<RS,C> const & rhs ) const nsrs_noexcept
921  {
922  return rhs < *this;
923  }
924 
925  template< bool C >
926  inline bool operator>=( ring_iterator<RS,C> const & rhs ) const nsrs_noexcept
927  {
928  return ! ( *this < rhs );
929  }
930 
931 private:
932  friend RS; // clang: non-class friend type 'RS' is a C++11 extension [-Wc++11-extensions]
933  friend class ring_iterator<RS, ! is_const>;
934 
935  typedef typename RS::size_type size_type;
937 
939  : m_idx( idx )
940  , m_rs ( rs )
941  {}
942 
943 private:
944  size_type m_idx;
945  ring_type * m_rs;
946 };
947 
948 // advanced iterator:
949 
950 template< class RS, bool C >
952 {
953  it += i; return it;
954 }
955 
956 template< class RS, bool C >
958 {
959  it -= i; return it;
960 }
961 
962 } // namespace detail
963 } // namespace ring_span_lite
964 
969 
970 } // namespace nonstd
971 
973 
974 #endif // NONSTD_RING_SPAN_LITE_HPP
void decrement_back_() nsrs_noexcept
Definition: ring_span.hpp:761
void increment_front_and_back_() nsrs_noexcept
Definition: ring_span.hpp:766
ring_span(ContiguousIterator begin, ContiguousIterator end, Popper popper=Popper()) nsrs_noexcept
Definition: ring_span.hpp:417
enum MQTTPropertyCodes value
std11::conditional< is_const, const value_type, value_type >::type & reference
Definition: ring_span.hpp:816
std11::conditional< is_const, const value_type, value_type >::type * pointer
Definition: ring_span.hpp:815
bool operator>(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
Definition: ring_span.hpp:920
type & operator-=(int i) nsrs_noexcept
Definition: ring_span.hpp:873
size_type normalize_(size_type const idx) const nsrs_noexcept
Definition: ring_span.hpp:709
const_iterator end() const nsrs_noexcept
Definition: ring_span.hpp:534
void push_front(T const &value)
Definition: ring_span.hpp:649
reference at_(size_type idx) nsrs_noexcept
Definition: ring_span.hpp:714
const_reference front_() const nsrs_noexcept
Definition: ring_span.hpp:729
iterator begin() nsrs_noexcept
Definition: ring_span.hpp:514
size_type capacity() const nsrs_noexcept
Definition: ring_span.hpp:473
const_iterator cend() const nsrs_noexcept
Definition: ring_span.hpp:539
iterator end() nsrs_noexcept
Definition: ring_span.hpp:529
Definition: json.hpp:4042
T const & move(T const &t)
Definition: ring_span.hpp:262
detail::ring_iterator< type, true > const_iterator
Definition: ring_span.hpp:407
const_reverse_iterator rend() const nsrs_noexcept
Definition: ring_span.hpp:561
detail::ring_iterator< type, false > iterator
Definition: ring_span.hpp:406
reference front_() nsrs_noexcept
Definition: ring_span.hpp:724
ring_span(ContiguousIterator begin, ContiguousIterator end, ContiguousIterator first, size_type size, Popper popper=Popper()) nsrs_noexcept
Definition: ring_span.hpp:430
difference_type operator-(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
Definition: ring_span.hpp:885
const_iterator cbegin() const nsrs_noexcept
Definition: ring_span.hpp:524
bool operator!=(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
Definition: ring_span.hpp:908
#define nsrs_noexcept
Definition: ring_span.hpp:219
const_reverse_iterator crbegin() const nsrs_noexcept
Definition: ring_span.hpp:566
bool operator>=(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
Definition: ring_span.hpp:926
Definition: chrono.h:284
reference back() nsrs_noexcept
Definition: ring_span.hpp:502
ring_iterator< RS, is_const > type
Definition: ring_span.hpp:810
ring_span< T, Popper > type
Definition: ring_span.hpp:404
reference operator[](size_type idx) nsrs_noexcept
Definition: ring_span.hpp:481
const_reverse_iterator crend() const nsrs_noexcept
Definition: ring_span.hpp:571
void operator()(T &) const nsrs_noexcept
Definition: ring_span.hpp:337
bool full() const nsrs_noexcept
Definition: ring_span.hpp:463
type & operator+=(int i) nsrs_noexcept
Definition: ring_span.hpp:868
Definition: any.hpp:144
ring_iterator< RS, C > operator-(ring_iterator< RS, C > it, int i) nsrs_noexcept
Definition: ring_span.hpp:957
void increment_front_() nsrs_noexcept
Definition: ring_span.hpp:744
ring_iterator(size_type idx, typename std11::conditional< is_const, const RS, RS >::type *rs) nsrs_noexcept
Definition: ring_span.hpp:938
reverse_iterator rend() nsrs_noexcept
Definition: ring_span.hpp:551
reference operator*() const nsrs_noexcept
Definition: ring_span.hpp:836
#define nsrs_noexcept_op(expr)
Definition: ring_span.hpp:220
Popper::return_type pop_back()
Definition: ring_span.hpp:590
ring_iterator< RS, C > operator+(ring_iterator< RS, C > it, int i) nsrs_noexcept
Definition: ring_span.hpp:951
std::reverse_iterator< iterator > reverse_iterator
Definition: ring_span.hpp:410
Popper::return_type pop_front()
Definition: ring_span.hpp:579
#define assert(a, b, c, d)
const_reference front() const nsrs_noexcept
Definition: ring_span.hpp:497
std11::conditional< is_const, const RS, RS >::type ring_type
Definition: ring_span.hpp:936
bool empty() const nsrs_noexcept
Definition: ring_span.hpp:458
string template
reverse_iterator rbegin() nsrs_noexcept
Definition: ring_span.hpp:546
const_iterator begin() const nsrs_noexcept
Definition: ring_span.hpp:519
void decrement_front_() nsrs_noexcept
Definition: ring_span.hpp:750
size_type size() const nsrs_noexcept
Definition: ring_span.hpp:468
reference back_() nsrs_noexcept
Definition: ring_span.hpp:734
const_reverse_iterator rbegin() const nsrs_noexcept
Definition: ring_span.hpp:556
void decrement_front_and_back_() nsrs_noexcept
Definition: ring_span.hpp:771
const_reference back_() const nsrs_noexcept
Definition: ring_span.hpp:739
const_reference at_(size_type idx) const nsrs_noexcept
Definition: ring_span.hpp:719
bool operator==(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
Definition: ring_span.hpp:900
reference front() nsrs_noexcept
Definition: ring_span.hpp:492
const_reference operator[](size_type idx) const nsrs_noexcept
Definition: ring_span.hpp:486
void swap(ring_span< T, Popper > &lhs, ring_span< T, Popper > &rhs) nsrs_noexcept_op(nsrs_noexcept_op(lhs.swap(rhs)))
Definition: ring_span.hpp:787
void increment_back_() nsrs_noexcept
Definition: ring_span.hpp:756
#define nsrs_RESTORE_WARNINGS()
Definition: ring_span.hpp:198
std::random_access_iterator_tag iterator_category
Definition: ring_span.hpp:817
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: ring_span.hpp:411
void push_back(value_type const &value)
Definition: ring_span.hpp:605
const_reference back() const nsrs_noexcept
Definition: ring_span.hpp:507


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:11