12 #ifndef NONSTD_RING_SPAN_LITE_HPP 13 #define NONSTD_RING_SPAN_LITE_HPP 15 #define ring_span_lite_MAJOR 0 16 #define ring_span_lite_MINOR 3 17 #define ring_span_lite_PATCH 0 19 #define ring_span_lite_VERSION nsrs_STRINGIFY(ring_span_lite_MAJOR) "." nsrs_STRINGIFY(ring_span_lite_MINOR) "." nsrs_STRINGIFY(ring_span_lite_PATCH) 21 #define nsrs_STRINGIFY( x ) nsrs_STRINGIFY_( x ) 22 #define nsrs_STRINGIFY_( x ) #x 26 #define nsrs_RING_SPAN_DEFAULT 0 27 #define nsrs_RING_SPAN_NONSTD 1 28 #define nsrs_RING_SPAN_STD 2 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 ) 34 #ifndef nsrs_CONFIG_STRICT_P0059 35 # define nsrs_CONFIG_STRICT_P0059 0 38 #define nsrs_RING_SPAN_LITE_EXTENSION (! nsrs_CONFIG_STRICT_P0059) 40 #ifndef nsrs_CONFIG_CONFIRMS_COMPILATION_ERRORS 41 # define nsrs_CONFIG_CONFIRMS_COMPILATION_ERRORS 0 47 #ifndef nsrs_CPLUSPLUS 48 # if defined(_MSVC_LANG ) && !defined(__clang__) 49 # define nsrs_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) 51 # define nsrs_CPLUSPLUS __cplusplus 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 ) 64 #define nsrs_HAVE_STD_RING_SPAN 0 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) ) 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 ) ) ) 99 # define nsrs_COMPILER_MSVC_VER 0 100 # define nsrs_COMPILER_MSVC_VERSION 0 103 #define nsrs_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) 105 #if defined(__clang__) 106 # define nsrs_COMPILER_CLANG_VERSION nsrs_COMPILER_VERSION( __clang_major__, __clang_minor__, __clang_patchlevel__ ) 108 # define nsrs_COMPILER_CLANG_VERSION 0 111 #if defined(__GNUC__) && !defined(__clang__) 112 # define nsrs_COMPILER_GNUC_VERSION nsrs_COMPILER_VERSION( __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ ) 114 # define nsrs_COMPILER_GNUC_VERSION 0 123 # define nsrs_HAS_CPP0X _HAS_CPP0X 125 # define nsrs_HAS_CPP0X 0 130 #if nsrs_COMPILER_MSVC_VER >= 1900 131 # undef nsrs_CPP11_OR_GREATER 132 # define nsrs_CPP11_OR_GREATER 1 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) 141 #define nsrs_CPP14_000 (nsrs_CPP14_OR_GREATER) 142 #define nsrs_CPP17_000 (nsrs_CPP17_OR_GREATER) 147 #define nsrs_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) 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 159 #define nsrs_HAVE_CONSTEXPR_14 nsrs_CPP14_000 169 #if defined(__clang__) 170 # pragma clang diagnostic push 171 # pragma clang diagnostic ignored "-Wundef" 172 # define nsrs_RESTORE_WARNINGS() _Pragma( "clang diagnostic pop" ) 174 #elif defined __GNUC__ 175 # pragma GCC diagnostic push 176 # pragma GCC diagnostic ignored "-Wundef" 177 # define nsrs_RESTORE_WARNINGS() _Pragma( "GCC diagnostic pop" ) 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 )) 195 nsrs_DISABLE_MSVC_WARNINGS( 4345 26439 26440 26472 26473 26481 26490 )
198 # define nsrs_RESTORE_WARNINGS() 203 #if nsrs_HAVE_CONSTEXPR_11 204 # define nsrs_constexpr constexpr 206 # define nsrs_constexpr 209 #if nsrs_HAVE_CONSTEXPR_14 210 # define nsrs_constexpr14 constexpr 212 # define nsrs_constexpr14 215 #if nsrs_HAVE_NOEXCEPT 216 # define nsrs_noexcept noexcept 217 # define nsrs_noexcept_op noexcept 219 # define nsrs_noexcept 220 # define nsrs_noexcept_op(expr) 223 #if nsrs_HAVE_NULLPTR 224 # define nsrs_nullptr nullptr 226 # define nsrs_nullptr NULL 231 #if nsrs_CPP11_OR_GREATER 233 #define nsrs_REQUIRES_0(...) \ 234 template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 > 236 #define nsrs_REQUIRES_T(...) \ 237 , typename std::enable_if< (__VA_ARGS__), int >::type = 0 249 #if ! nsrs_CPP11_OR_GREATER 250 # include <algorithm> 253 namespace nonstd {
namespace ring_span_lite {
259 #if nsrs_CPP11_OR_GREATER 262 template<
typename T > T
const &
move( T
const & t ) {
return t; }
265 template<
bool B,
class T,
class F >
268 template<
class T,
class F >
277 #if nsrs_CPP17_OR_GREATER 279 using std::is_swappable;
280 using std::is_nothrow_swappable;
282 #elif nsrs_CPP11_OR_GREATER 290 template<
typename T,
typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
291 static std::true_type test(
int );
294 static std::false_type test(...);
297 struct is_nothrow_swappable
301 template<
typename T >
302 static constexpr
bool test()
304 return noexcept(
swap( std::declval<T&>(), std::declval<T&>() ) );
307 template<
typename T >
308 static auto test(
int ) -> std::integral_constant<bool, test<T>()>{}
311 static std::false_type test(...);
318 template<
typename T >
319 struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
321 template<
typename T >
322 struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
324 #endif // nsrs_CPP17_OR_GREATER 356 #if nsrs_RING_SPAN_LITE_EXTENSION 357 # if nsrs_CPP11_OR_GREATER 385 template<
class,
bool >
393 template<
class T,
class Popper = default_popper<T> >
409 #if nsrs_RING_SPAN_LITE_EXTENSION 416 template<
class ContiguousIterator >
418 ContiguousIterator begin
419 , ContiguousIterator end
420 , Popper popper = Popper()
422 : m_data ( &* begin )
424 , m_capacity ( static_cast<size_type>( end - begin ) )
426 , m_popper ( std11::
move( popper ) )
429 template<
class ContiguousIterator >
431 ContiguousIterator begin
432 , ContiguousIterator end
433 , ContiguousIterator first
435 , Popper popper = Popper()
437 : m_data ( &* begin )
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 ) )
443 assert( m_size <= m_capacity );
446 #if nsrs_HAVE_IS_DEFAULT 465 return m_size == m_capacity;
480 #if nsrs_RING_SPAN_LITE_EXTENSION 483 assert( idx < m_size );
return at_(idx);
488 assert( idx < m_size );
return at_(idx);
516 return iterator( 0,
this );
526 return const_iterator( 0,
this );
531 return iterator( size(),
this );
541 return const_iterator( size(),
this );
544 #if nsrs_RING_SPAN_LITE_EXTENSION 548 return reverse_iterator( end() );
553 return reverse_iterator( begin() );
568 return const_reverse_iterator( cend() );
573 return const_reverse_iterator(cbegin());
583 reference element = front_();
586 return m_popper( element );
589 #if nsrs_RING_SPAN_LITE_EXTENSION 594 reference element = back_();
597 return m_popper( element );
601 #if nsrs_CPP11_OR_GREATER 608 if ( full() ) increment_front_and_back_();
609 else increment_back_();
614 #if nsrs_CPP11_OR_GREATER 618 if ( full() ) increment_front_and_back_();
619 else increment_back_();
624 template<
typename... Args
630 void emplace_back( Args &&... args ) noexcept
636 if ( full() ) increment_front_and_back_();
637 else increment_back_();
639 back_() = T( std::forward<Args>(args)...);
643 #if nsrs_RING_SPAN_LITE_EXTENSION 645 #if nsrs_CPP11_OR_GREATER 652 if ( full() ) decrement_front_and_back_();
653 else decrement_front_();
658 #if nsrs_CPP11_OR_GREATER 662 if ( full() ) decrement_front_and_back_();
663 else decrement_front_();
668 template<
typename... Args
674 void emplace_front( Args&&... args ) noexcept
680 if ( full() ) decrement_front_and_back_();
681 else decrement_front_();
683 front_() = T( std::forward<Args>(args)...);
686 #endif // nsrs_RING_SPAN_LITE_EXTENSION 691 #if nsrs_CPP11_OR_GREATER 711 return idx % m_capacity;
716 return m_data[ normalize_(m_front_idx + idx) ];
721 return m_data[ normalize_(m_front_idx + idx) ];
726 return *( m_data + m_front_idx );
731 return *( m_data + m_front_idx );
736 return *( m_data + normalize_(m_front_idx + m_size - 1) );
741 return *( m_data + normalize_(m_front_idx + m_size - 1) );
746 m_front_idx = normalize_(m_front_idx + 1);
752 m_front_idx = normalize_(m_front_idx + m_capacity - 1);
768 m_front_idx = normalize_( m_front_idx + 1 );
773 m_front_idx = normalize_( m_front_idx + m_capacity - 1 );
786 template<
class T,
class Popper >
798 template<
class RS,
bool is_const >
799 class ring_iterator :
public std::iterator
801 std::random_access_iterator_tag
802 , typename std11::conditional<is_const, const typename RS::value_type, typename RS::value_type>::type
819 #if nsrs_CPP11_OR_GREATER 825 #if nsrs_RING_SPAN_LITE_EXTENSION 838 return m_rs->at_( m_idx );
845 ++m_idx;
return *
this;
850 type r(*
this); ++*
this;
return r;
855 --m_idx;
return *
this;
860 type r(*
this); --*
this;
return r;
863 #if defined(__clang__) || defined(__GNUC__) 864 # pragma GCC diagnostic push 865 # pragma GCC diagnostic ignored "-Wsign-conversion" 870 m_idx += i;
return *
this;
875 m_idx -= i;
return *
this;
878 #if defined(__clang__) || defined(__GNUC__) 879 # pragma GCC diagnostic pop 882 #if nsrs_RING_SPAN_LITE_EXTENSION 887 return static_cast<difference_type
>( this->m_idx ) - static_cast<difference_type>( rhs.m_idx );
896 assert( this->m_rs == rhs.m_rs );
return ( this->m_idx < rhs.m_idx );
902 assert( this->m_rs == rhs.m_rs );
return ( this->m_idx == rhs.m_idx );
910 return ! ( *
this == rhs );
914 inline bool operator<=( ring_iterator<RS,C>
const & rhs )
const nsrs_noexcept 916 return ! ( rhs < *this );
928 return ! ( *
this < rhs );
950 template<
class RS,
bool C >
956 template<
class RS,
bool C >
974 #endif // NONSTD_RING_SPAN_LITE_HPP
void decrement_back_() nsrs_noexcept
void increment_front_and_back_() nsrs_noexcept
ring_span(ContiguousIterator begin, ContiguousIterator end, Popper popper=Popper()) nsrs_noexcept
enum MQTTPropertyCodes value
std11::conditional< is_const, const value_type, value_type >::type & reference
std11::conditional< is_const, const value_type, value_type >::type * pointer
bool operator>(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
type & operator-=(int i) nsrs_noexcept
size_type normalize_(size_type const idx) const nsrs_noexcept
const_iterator end() const nsrs_noexcept
void push_front(T const &value)
reference at_(size_type idx) nsrs_noexcept
RS::value_type value_type
const_reference front_() const nsrs_noexcept
iterator begin() nsrs_noexcept
size_type capacity() const nsrs_noexcept
const_iterator cend() const nsrs_noexcept
iterator end() nsrs_noexcept
type & operator--() nsrs_noexcept
T const & move(T const &t)
detail::ring_iterator< type, true > const_iterator
const_reverse_iterator rend() const nsrs_noexcept
type operator--(int) nsrs_noexcept
detail::ring_iterator< type, false > iterator
reference front_() nsrs_noexcept
ring_span(ContiguousIterator begin, ContiguousIterator end, ContiguousIterator first, size_type size, Popper popper=Popper()) nsrs_noexcept
difference_type operator-(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
const_iterator cbegin() const nsrs_noexcept
bool operator!=(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
const_reverse_iterator crbegin() const nsrs_noexcept
bool operator>=(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
reference back() nsrs_noexcept
ring_iterator< RS, is_const > type
type operator++(int) nsrs_noexcept
ring_span< T, Popper > type
reference operator[](size_type idx) nsrs_noexcept
const_reverse_iterator crend() const nsrs_noexcept
void operator()(T &) const nsrs_noexcept
bool full() const nsrs_noexcept
type & operator+=(int i) nsrs_noexcept
ring_iterator< RS, C > operator-(ring_iterator< RS, C > it, int i) nsrs_noexcept
void increment_front_() nsrs_noexcept
ring_iterator(size_type idx, typename std11::conditional< is_const, const RS, RS >::type *rs) nsrs_noexcept
reverse_iterator rend() nsrs_noexcept
reference operator*() const nsrs_noexcept
#define nsrs_noexcept_op(expr)
Popper::return_type pop_back()
type & operator++() nsrs_noexcept
ring_iterator< RS, C > operator+(ring_iterator< RS, C > it, int i) nsrs_noexcept
std::reverse_iterator< iterator > reverse_iterator
Popper::return_type pop_front()
#define assert(a, b, c, d)
const_reference front() const nsrs_noexcept
std11::conditional< is_const, const RS, RS >::type ring_type
bool empty() const nsrs_noexcept
reverse_iterator rbegin() nsrs_noexcept
const_iterator begin() const nsrs_noexcept
void decrement_front_() nsrs_noexcept
size_type size() const nsrs_noexcept
reference back_() nsrs_noexcept
const_reverse_iterator rbegin() const nsrs_noexcept
void decrement_front_and_back_() nsrs_noexcept
const_reference back_() const nsrs_noexcept
const_reference at_(size_type idx) const nsrs_noexcept
bool operator==(ring_iterator< RS, C > const &rhs) const nsrs_noexcept
T const & const_reference
reference front() nsrs_noexcept
const_reference operator[](size_type idx) const nsrs_noexcept
void swap(ring_span< T, Popper > &lhs, ring_span< T, Popper > &rhs) nsrs_noexcept_op(nsrs_noexcept_op(lhs.swap(rhs)))
void increment_back_() nsrs_noexcept
#define nsrs_RESTORE_WARNINGS()
std::random_access_iterator_tag iterator_category
std::reverse_iterator< const_iterator > const_reverse_iterator
void push_back(value_type const &value)
std::ptrdiff_t difference_type
const_reference back() const nsrs_noexcept