File indexing completed on 2025-09-15 08:48:26
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_POLY_COLLECTION_DETAIL_STRIDE_ITERATOR_HPP
0010 #define BOOST_POLY_COLLECTION_DETAIL_STRIDE_ITERATOR_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/config.hpp>
0017 #include <boost/detail/workaround.hpp>
0018 #include <boost/iterator/iterator_facade.hpp>
0019 #include <type_traits>
0020
0021 namespace boost{
0022
0023 namespace poly_collection{
0024
0025 namespace detail{
0026
0027
0028
0029 template<typename Value>
0030 class stride_iterator:
0031 public boost::iterator_facade<
0032 stride_iterator<Value>,
0033 Value,
0034 boost::random_access_traversal_tag
0035 >
0036 {
0037 public:
0038 stride_iterator()=default;
0039 stride_iterator(Value* p,std::size_t stride)noexcept:p{p},stride_{stride}{}
0040 stride_iterator(const stride_iterator&)=default;
0041 stride_iterator& operator=(const stride_iterator&)=default;
0042
0043 template<
0044 typename NonConstValue,
0045 typename std::enable_if<
0046 std::is_same<Value,const NonConstValue>::value>::type* =nullptr
0047 >
0048 stride_iterator(const stride_iterator<NonConstValue>& x)noexcept:
0049 p{x.p},stride_{x.stride_}{}
0050
0051 template<
0052 typename NonConstValue,
0053 typename std::enable_if<
0054 std::is_same<Value,const NonConstValue>::value>::type* =nullptr
0055 >
0056 stride_iterator& operator=(const stride_iterator<NonConstValue>& x)noexcept
0057 {
0058 p=x.p;stride_=x.stride_;
0059 return *this;
0060 }
0061
0062
0063
0064 stride_iterator& operator=(Value* p_)noexcept{p=p_;return *this;}
0065 operator Value*()const noexcept{return p;}
0066
0067 #include <boost/poly_collection/detail/begin_no_sanitize.hpp>
0068
0069 template<
0070 typename DerivedValue,
0071 typename std::enable_if<
0072 std::is_base_of<Value,DerivedValue>::value&&
0073 (!std::is_const<Value>::value||std::is_const<DerivedValue>::value)
0074 >::type* =nullptr
0075 >
0076 BOOST_POLY_COLLECTION_NO_SANITIZE
0077 explicit operator DerivedValue*()const noexcept
0078 {return static_cast<DerivedValue*>(p);}
0079
0080 #include <boost/poly_collection/detail/end_no_sanitize.hpp>
0081
0082 std::size_t stride()const noexcept{return stride_;}
0083
0084 private:
0085 template<typename>
0086 friend class stride_iterator;
0087
0088 using char_pointer=typename std::conditional<
0089 std::is_const<Value>::value,
0090 const char*,
0091 char*
0092 >::type;
0093
0094 static char_pointer char_ptr(Value* p)noexcept
0095 {return reinterpret_cast<char_pointer>(p);}
0096 static Value* value_ptr(char_pointer p)noexcept
0097 {return reinterpret_cast<Value*>(p);}
0098
0099 friend class boost::iterator_core_access;
0100
0101 Value& dereference()const noexcept{return *p;}
0102 bool equal(const stride_iterator& x)const noexcept{return p==x.p;}
0103 void increment()noexcept{p=value_ptr(char_ptr(p)+stride_);}
0104 void decrement()noexcept{p=value_ptr(char_ptr(p)-stride_);}
0105 template<typename Integral>
0106 void advance(Integral n)noexcept
0107 {p=value_ptr(char_ptr(p)+n*(std::ptrdiff_t)stride_);}
0108 std::ptrdiff_t distance_to(const stride_iterator& x)const noexcept
0109 {return (char_ptr(x.p)-char_ptr(p))/(std::ptrdiff_t)stride_;}
0110
0111 Value* p;
0112 std::size_t stride_;
0113 };
0114
0115 }
0116
0117 }
0118
0119 }
0120
0121 #endif