File indexing completed on 2025-02-22 10:22:15
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_POLY_COLLECTION_DETAIL_ITERATOR_IMPL_HPP
0010 #define BOOST_POLY_COLLECTION_DETAIL_ITERATOR_IMPL_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/detail/workaround.hpp>
0017 #include <boost/iterator/iterator_adaptor.hpp>
0018 #include <boost/iterator/iterator_facade.hpp>
0019 #include <boost/poly_collection/detail/is_constructible.hpp>
0020 #include <boost/poly_collection/detail/iterator_traits.hpp>
0021 #include <type_traits>
0022 #include <typeinfo>
0023
0024 namespace boost{
0025
0026 namespace poly_collection{
0027
0028 namespace detail{
0029
0030
0031
0032
0033
0034 template<typename PolyCollection,bool Const>
0035 using iterator_impl_value_type=typename std::conditional<
0036 Const,
0037 const typename PolyCollection::value_type,
0038 typename PolyCollection::value_type
0039 >::type;
0040
0041 template<typename PolyCollection,bool Const>
0042 class iterator_impl:
0043 public boost::iterator_facade<
0044 iterator_impl<PolyCollection,Const>,
0045 iterator_impl_value_type<PolyCollection,Const>,
0046 boost::forward_traversal_tag
0047 >
0048 {
0049 using segment_type=typename PolyCollection::segment_type;
0050 using const_segment_base_iterator=
0051 typename PolyCollection::const_segment_base_iterator;
0052 using const_segment_base_sentinel=
0053 typename PolyCollection::const_segment_base_sentinel;
0054 using const_segment_map_iterator=
0055 typename PolyCollection::const_segment_map_iterator;
0056
0057 public:
0058 using value_type=iterator_impl_value_type<PolyCollection,Const>;
0059
0060 private:
0061 iterator_impl(
0062 const_segment_map_iterator mapit,
0063 const_segment_map_iterator mapend)noexcept:
0064 mapit{mapit},mapend{mapend}
0065 {
0066 next_segment_position();
0067 }
0068
0069 iterator_impl(
0070 const_segment_map_iterator mapit_,const_segment_map_iterator mapend_,
0071 const_segment_base_iterator segpos_)noexcept:
0072 mapit{mapit_},mapend{mapend_},segpos{segpos_}
0073 {
0074 if(mapit!=mapend&&segpos==sentinel()){
0075 ++mapit;
0076 next_segment_position();
0077 }
0078 }
0079
0080 public:
0081 iterator_impl()=default;
0082 iterator_impl(const iterator_impl&)=default;
0083 iterator_impl& operator=(const iterator_impl&)=default;
0084
0085 template<bool Const2,typename std::enable_if<!Const2>::type* =nullptr>
0086 iterator_impl(const iterator_impl<PolyCollection,Const2>& x):
0087 mapit{x.mapit},mapend{x.mapend},segpos{x.segpos}{}
0088
0089 private:
0090 template<typename,bool>
0091 friend class iterator_impl;
0092 friend PolyCollection;
0093 friend class boost::iterator_core_access;
0094 template<typename>
0095 friend struct iterator_traits;
0096
0097 value_type& dereference()const noexcept
0098 {return const_cast<value_type&>(*segpos);}
0099 bool equal(const iterator_impl& x)const noexcept{return segpos==x.segpos;}
0100
0101 void increment()noexcept
0102 {
0103 if(++segpos==sentinel()){
0104 ++mapit;
0105 next_segment_position();
0106 }
0107 }
0108
0109 void next_segment_position()noexcept
0110 {
0111 for(;mapit!=mapend;++mapit){
0112 segpos=segment().begin();
0113 if(segpos!=sentinel())return;
0114 }
0115 segpos=nullptr;
0116 }
0117
0118 segment_type& segment()noexcept
0119 {return const_cast<segment_type&>(mapit->second);}
0120 const segment_type& segment()const noexcept{return mapit->second;}
0121
0122 const_segment_base_sentinel sentinel()const noexcept
0123 {return segment().sentinel();}
0124
0125 const_segment_map_iterator mapit,mapend;
0126 const_segment_base_iterator segpos;
0127 };
0128
0129 template<typename PolyCollection,bool Const>
0130 struct poly_collection_of<iterator_impl<PolyCollection,Const>>
0131 {
0132 using type=PolyCollection;
0133 };
0134
0135 template<typename PolyCollection,typename BaseIterator>
0136 class local_iterator_impl:
0137 public boost::iterator_adaptor<
0138 local_iterator_impl<PolyCollection,BaseIterator>,
0139 BaseIterator
0140 >
0141 {
0142 using segment_type=typename PolyCollection::segment_type;
0143 using segment_base_iterator=typename PolyCollection::segment_base_iterator;
0144 using const_segment_map_iterator=
0145 typename PolyCollection::const_segment_map_iterator;
0146
0147 #if BOOST_WORKAROUND(BOOST_GCC_VERSION,>=90300)&&\
0148 BOOST_WORKAROUND(BOOST_GCC_VERSION,<100300)
0149
0150
0151 public:
0152 #else
0153 private:
0154 #endif
0155
0156 template<typename Iterator>
0157 local_iterator_impl(
0158 const_segment_map_iterator mapit,
0159 Iterator it):
0160 local_iterator_impl::iterator_adaptor_{BaseIterator(it)},
0161 mapit{mapit}
0162 {}
0163
0164 public:
0165 using base_iterator=BaseIterator;
0166
0167 local_iterator_impl()=default;
0168 local_iterator_impl(const local_iterator_impl&)=default;
0169 local_iterator_impl& operator=(const local_iterator_impl&)=default;
0170
0171 template<
0172 typename BaseIterator2,
0173 typename std::enable_if<
0174 std::is_convertible<BaseIterator2,BaseIterator>::value
0175 >::type* =nullptr
0176 >
0177 local_iterator_impl(
0178 const local_iterator_impl<PolyCollection,BaseIterator2>& x):
0179 local_iterator_impl::iterator_adaptor_{x.base()},
0180 mapit{x.mapit}{}
0181
0182 template<
0183 typename BaseIterator2,
0184 typename std::enable_if<
0185 !std::is_convertible<BaseIterator2,BaseIterator>::value&&
0186 is_constructible<BaseIterator,BaseIterator2>::value
0187 >::type* =nullptr
0188 >
0189 explicit local_iterator_impl(
0190 const local_iterator_impl<PolyCollection,BaseIterator2>& x):
0191 local_iterator_impl::iterator_adaptor_{BaseIterator(x.base())},
0192 mapit{x.mapit}{}
0193
0194 template<
0195 typename BaseIterator2,
0196 typename std::enable_if<
0197 !is_constructible<BaseIterator,BaseIterator2>::value&&
0198 is_constructible<BaseIterator,segment_base_iterator>::value&&
0199 is_constructible<BaseIterator2,segment_base_iterator>::value
0200 >::type* =nullptr
0201 >
0202 explicit local_iterator_impl(
0203 const local_iterator_impl<PolyCollection,BaseIterator2>& x):
0204 local_iterator_impl::iterator_adaptor_{
0205 base_iterator_from(x.segment(),x.base())},
0206 mapit{x.mapit}{}
0207
0208
0209
0210 template<typename DifferenceType>
0211 typename std::iterator_traits<BaseIterator>::reference
0212 operator[](DifferenceType n)const{return *(*this+n);}
0213
0214 private:
0215 template<typename,typename>
0216 friend class local_iterator_impl;
0217 friend PolyCollection;
0218 template<typename>
0219 friend struct iterator_traits;
0220
0221 template<typename BaseIterator2>
0222 static BaseIterator base_iterator_from(
0223 const segment_type& s,BaseIterator2 it)
0224 {
0225 segment_base_iterator bit=s.begin();
0226 return BaseIterator{bit+(it-static_cast<BaseIterator2>(bit))};
0227 }
0228
0229 base_iterator base()const noexcept
0230 {return local_iterator_impl::iterator_adaptor_::base();}
0231 const std::type_info& type_info()const{return *mapit->first;}
0232 segment_type& segment()noexcept
0233 {return const_cast<segment_type&>(mapit->second);}
0234 const segment_type& segment()const noexcept{return mapit->second;}
0235
0236 const_segment_map_iterator mapit;
0237 };
0238
0239 template<typename PolyCollection,typename BaseIterator>
0240 struct poly_collection_of<local_iterator_impl<PolyCollection,BaseIterator>>
0241 {
0242 using type=PolyCollection;
0243 };
0244
0245 }
0246
0247 }
0248
0249 }
0250
0251 #endif