File indexing completed on 2025-09-17 08:45:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_POLY_COLLECTION_DETAIL_FIXED_VARIANT_ITERATOR_HPP
0010 #define BOOST_POLY_COLLECTION_DETAIL_FIXED_VARIANT_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 <boost/poly_collection/detail/fixed_variant.hpp>
0020 #include <type_traits>
0021
0022 namespace boost{
0023
0024 namespace poly_collection{
0025
0026 namespace detail{
0027
0028
0029
0030
0031
0032 template<typename Variant,typename T>
0033 class fixed_variant_alternative_iterator:
0034 public boost::iterator_facade<
0035 fixed_variant_alternative_iterator<Variant,T>,
0036 T,
0037 boost::random_access_traversal_tag
0038 >
0039 {
0040 static constexpr std::size_t Stride=sizeof(
0041 fixed_variant_impl::fixed_variant_closure<
0042 typename std::remove_const<T>::type,Variant>);
0043
0044 public:
0045 fixed_variant_alternative_iterator()=default;
0046 fixed_variant_alternative_iterator(T* p)noexcept:p{p}{}
0047 fixed_variant_alternative_iterator(
0048 const fixed_variant_alternative_iterator&)=default;
0049 fixed_variant_alternative_iterator& operator=(
0050 const fixed_variant_alternative_iterator&)=default;
0051
0052 template<
0053 typename NonConstT,
0054 typename std::enable_if<
0055 std::is_same<T,const NonConstT>::value>::type* =nullptr
0056 >
0057 fixed_variant_alternative_iterator(
0058 const fixed_variant_alternative_iterator<Variant,NonConstT>& x)noexcept:
0059 p{x.p}{}
0060
0061 template<
0062 typename NonConstT,
0063 typename std::enable_if<
0064 std::is_same<T,const NonConstT>::value>::type* =nullptr
0065 >
0066 fixed_variant_alternative_iterator& operator=(
0067 const fixed_variant_alternative_iterator<Variant,NonConstT>& x)noexcept
0068 {
0069 p=x.p;
0070 return *this;
0071 }
0072
0073
0074
0075 fixed_variant_alternative_iterator& operator=(T* p_)noexcept
0076 {p=p_;return *this;}
0077 operator T*()const noexcept{return p;}
0078
0079 std::size_t stride()const noexcept{return Stride;}
0080
0081 private:
0082 template<typename,typename>
0083 friend class fixed_variant_alternative_iterator;
0084
0085 using char_pointer=typename std::conditional<
0086 std::is_const<T>::value,
0087 const char*,
0088 char*
0089 >::type;
0090
0091 static char_pointer char_ptr(T* p)noexcept
0092 {return reinterpret_cast<char_pointer>(p);}
0093 static T* value_ptr(char_pointer p)noexcept
0094 {return reinterpret_cast<T*>(p);}
0095
0096 friend class boost::iterator_core_access;
0097
0098 T& dereference()const noexcept{return *p;}
0099 bool equal(const fixed_variant_alternative_iterator& x)const noexcept
0100 {return p==x.p;}
0101 void increment()noexcept{p=value_ptr(char_ptr(p)+Stride);}
0102 void decrement()noexcept{p=value_ptr(char_ptr(p)-Stride);}
0103 template<typename Integral>
0104 void advance(Integral n)noexcept
0105 {p=value_ptr(char_ptr(p)+n*(std::ptrdiff_t)Stride);}
0106 std::ptrdiff_t distance_to(
0107 const fixed_variant_alternative_iterator& x)const noexcept
0108 {return (char_ptr(x.p)-char_ptr(p))/(std::ptrdiff_t)Stride;}
0109
0110 T* p;
0111 };
0112
0113
0114
0115
0116
0117
0118 template<typename Variant>
0119 class fixed_variant_iterator:
0120 public boost::iterator_facade<
0121 fixed_variant_iterator<Variant>,
0122 Variant,
0123 boost::random_access_traversal_tag
0124 >
0125 {
0126 public:
0127 fixed_variant_iterator()=default;
0128 fixed_variant_iterator(Variant* p,std::size_t stride)noexcept:
0129 p{p},stride_{stride}{}
0130 fixed_variant_iterator(const fixed_variant_iterator&)=default;
0131 fixed_variant_iterator& operator=(const fixed_variant_iterator&)=default;
0132
0133 template<
0134 typename NonConstVariant,
0135 typename std::enable_if<
0136 std::is_same<Variant,const NonConstVariant>::value>::type* =nullptr
0137 >
0138 fixed_variant_iterator(
0139 const fixed_variant_iterator<NonConstVariant>& x)noexcept:
0140 p{x.p},stride_{x.stride_}{}
0141
0142 template<
0143 typename NonConstVariant,
0144 typename std::enable_if<
0145 std::is_same<Variant,const NonConstVariant>::value>::type* =nullptr
0146 >
0147 fixed_variant_iterator& operator=(
0148 const fixed_variant_iterator<NonConstVariant>& x)noexcept
0149 {
0150 p=x.p;stride_=x.stride_;
0151 return *this;
0152 }
0153
0154
0155
0156 fixed_variant_iterator& operator=(Variant* p_)noexcept{p=p_;return *this;}
0157 operator Variant*()const noexcept{return p;}
0158
0159
0160
0161 #include <boost/poly_collection/detail/begin_no_sanitize.hpp>
0162
0163 template<
0164 typename T,
0165 typename NonConstT=typename std::remove_const<T>::type,
0166 typename NonConstVariant=typename std::remove_const<Variant>::type,
0167 typename std::enable_if<
0168 mp11::mp_contains<NonConstVariant,NonConstT>::value&&
0169 (!std::is_const<Variant>::value||std::is_const<T>::value)
0170 >::type* =nullptr
0171 >
0172 BOOST_POLY_COLLECTION_NO_SANITIZE explicit operator
0173 fixed_variant_alternative_iterator<NonConstVariant,T>()const noexcept
0174 {
0175 return p?std::addressof(unsafe_get<NonConstT>(*p)):nullptr;
0176 }
0177
0178 #include <boost/poly_collection/detail/end_no_sanitize.hpp>
0179
0180 std::size_t stride()const noexcept{return stride_;}
0181
0182 private:
0183 template<typename>
0184 friend class fixed_variant_iterator;
0185
0186 using char_pointer=typename std::conditional<
0187 std::is_const<Variant>::value,
0188 const char*,
0189 char*
0190 >::type;
0191
0192 static char_pointer char_ptr(Variant* p)noexcept
0193 {return reinterpret_cast<char_pointer>(p);}
0194 static Variant* value_ptr(char_pointer p)noexcept
0195 {return reinterpret_cast<Variant*>(p);}
0196
0197 friend class boost::iterator_core_access;
0198
0199 Variant& dereference()const noexcept{return *p;}
0200 bool equal(const fixed_variant_iterator& x)const noexcept{return p==x.p;}
0201 void increment()noexcept{p=value_ptr(char_ptr(p)+stride_);}
0202 void decrement()noexcept{p=value_ptr(char_ptr(p)-stride_);}
0203 template<typename Integral>
0204 void advance(Integral n)noexcept
0205 {p=value_ptr(char_ptr(p)+n*(std::ptrdiff_t)stride_);}
0206 std::ptrdiff_t distance_to(const fixed_variant_iterator& x)const noexcept
0207 {return (char_ptr(x.p)-char_ptr(p))/(std::ptrdiff_t)stride_;}
0208
0209 Variant* p;
0210 std::size_t stride_;
0211 };
0212
0213 }
0214
0215 }
0216
0217 }
0218
0219 #endif