]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/poly_collection/detail/iterator_impl.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / poly_collection / detail / iterator_impl.hpp
1 /* Copyright 2016-2017 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * See http://www.boost.org/libs/poly_collection for library home page.
7 */
8
9 #ifndef BOOST_POLY_COLLECTION_DETAIL_ITERATOR_IMPL_HPP
10 #define BOOST_POLY_COLLECTION_DETAIL_ITERATOR_IMPL_HPP
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include <boost/iterator/iterator_adaptor.hpp>
17 #include <boost/iterator/iterator_facade.hpp>
18 #include <boost/poly_collection/detail/is_constructible.hpp>
19 #include <boost/poly_collection/detail/iterator_traits.hpp>
20 #include <type_traits>
21 #include <typeinfo>
22
23 namespace boost{
24
25 namespace poly_collection{
26
27 namespace detail{
28
29 /* Implementations of poly_collection::[const_][local_[base_]]iterator moved
30 * out of class to allow for use in deduced contexts.
31 */
32
33 template<typename PolyCollection,bool Const>
34 using iterator_impl_value_type=typename std::conditional<
35 Const,
36 const typename PolyCollection::value_type,
37 typename PolyCollection::value_type
38 >::type;
39
40 template<typename PolyCollection,bool Const>
41 class iterator_impl:
42 public boost::iterator_facade<
43 iterator_impl<PolyCollection,Const>,
44 iterator_impl_value_type<PolyCollection,Const>,
45 boost::forward_traversal_tag
46 >
47 {
48 using segment_type=typename PolyCollection::segment_type;
49 using const_segment_base_iterator=
50 typename PolyCollection::const_segment_base_iterator;
51 using const_segment_base_sentinel=
52 typename PolyCollection::const_segment_base_sentinel;
53 using const_segment_map_iterator=
54 typename PolyCollection::const_segment_map_iterator;
55
56 public:
57 using value_type=iterator_impl_value_type<PolyCollection,Const>;
58
59 private:
60 iterator_impl(
61 const_segment_map_iterator mapit,
62 const_segment_map_iterator mapend)noexcept:
63 mapit{mapit},mapend{mapend}
64 {
65 next_segment_position();
66 }
67
68 iterator_impl(
69 const_segment_map_iterator mapit_,const_segment_map_iterator mapend_,
70 const_segment_base_iterator segpos_)noexcept:
71 mapit{mapit_},mapend{mapend_},segpos{segpos_}
72 {
73 if(mapit!=mapend&&segpos==sentinel()){
74 ++mapit;
75 next_segment_position();
76 }
77 }
78
79 public:
80 iterator_impl()=default;
81 iterator_impl(const iterator_impl&)=default;
82 iterator_impl& operator=(const iterator_impl&)=default;
83
84 template<bool Const2,typename std::enable_if<!Const2>::type* =nullptr>
85 iterator_impl(const iterator_impl<PolyCollection,Const2>& x):
86 mapit{x.mapit},mapend{x.mapend},segpos{x.segpos}{}
87
88 private:
89 template<typename,bool>
90 friend class iterator_impl;
91 friend PolyCollection;
92 friend class boost::iterator_core_access;
93 template<typename>
94 friend struct iterator_traits;
95
96 value_type& dereference()const noexcept
97 {return const_cast<value_type&>(*segpos);}
98 bool equal(const iterator_impl& x)const noexcept{return segpos==x.segpos;}
99
100 void increment()noexcept
101 {
102 if(++segpos==sentinel()){
103 ++mapit;
104 next_segment_position();
105 }
106 }
107
108 void next_segment_position()noexcept
109 {
110 for(;mapit!=mapend;++mapit){
111 segpos=segment().begin();
112 if(segpos!=sentinel())return;
113 }
114 segpos=nullptr;
115 }
116
117 segment_type& segment()noexcept
118 {return const_cast<segment_type&>(mapit->second);}
119 const segment_type& segment()const noexcept{return mapit->second;}
120
121 const_segment_base_sentinel sentinel()const noexcept
122 {return segment().sentinel();}
123
124 const_segment_map_iterator mapit,mapend;
125 const_segment_base_iterator segpos;
126 };
127
128 template<typename PolyCollection,bool Const>
129 struct poly_collection_of<iterator_impl<PolyCollection,Const>>
130 {
131 using type=PolyCollection;
132 };
133
134 template<typename PolyCollection,typename BaseIterator>
135 class local_iterator_impl:
136 public boost::iterator_adaptor<
137 local_iterator_impl<PolyCollection,BaseIterator>,
138 BaseIterator
139 >
140 {
141 using segment_type=typename PolyCollection::segment_type;
142 using segment_base_iterator=typename PolyCollection::segment_base_iterator;
143 using const_segment_map_iterator=
144 typename PolyCollection::const_segment_map_iterator;
145
146 template<typename Iterator>
147 local_iterator_impl(
148 const_segment_map_iterator mapit,
149 Iterator it):
150 local_iterator_impl::iterator_adaptor_{BaseIterator(it)},
151 mapit{mapit}
152 {}
153
154 public:
155 using base_iterator=BaseIterator;
156
157 local_iterator_impl()=default;
158 local_iterator_impl(const local_iterator_impl&)=default;
159 local_iterator_impl& operator=(const local_iterator_impl&)=default;
160
161 template<
162 typename BaseIterator2,
163 typename std::enable_if<
164 std::is_convertible<BaseIterator2,BaseIterator>::value
165 >::type* =nullptr
166 >
167 local_iterator_impl(
168 const local_iterator_impl<PolyCollection,BaseIterator2>& x):
169 local_iterator_impl::iterator_adaptor_{x.base()},
170 mapit{x.mapit}{}
171
172 template<
173 typename BaseIterator2,
174 typename std::enable_if<
175 !std::is_convertible<BaseIterator2,BaseIterator>::value&&
176 is_constructible<BaseIterator,BaseIterator2>::value
177 >::type* =nullptr
178 >
179 explicit local_iterator_impl(
180 const local_iterator_impl<PolyCollection,BaseIterator2>& x):
181 local_iterator_impl::iterator_adaptor_{BaseIterator(x.base())},
182 mapit{x.mapit}{}
183
184 template<
185 typename BaseIterator2,
186 typename std::enable_if<
187 !is_constructible<BaseIterator,BaseIterator2>::value&&
188 is_constructible<BaseIterator,segment_base_iterator>::value&&
189 is_constructible<BaseIterator2,segment_base_iterator>::value
190 >::type* =nullptr
191 >
192 explicit local_iterator_impl(
193 const local_iterator_impl<PolyCollection,BaseIterator2>& x):
194 local_iterator_impl::iterator_adaptor_{
195 base_iterator_from(x.segment(),x.base())},
196 mapit{x.mapit}{}
197
198 /* define [] to avoid Boost.Iterator operator_brackets_proxy mess */
199
200 template<typename DifferenceType>
201 typename std::iterator_traits<BaseIterator>::reference
202 operator[](DifferenceType n)const{return *(*this+n);}
203
204 private:
205 template<typename,typename>
206 friend class local_iterator_impl;
207 friend PolyCollection;
208 template<typename>
209 friend struct iterator_traits;
210
211 template<typename BaseIterator2>
212 static BaseIterator base_iterator_from(
213 const segment_type& s,BaseIterator2 it)
214 {
215 segment_base_iterator bit=s.begin();
216 return BaseIterator{bit+(it-static_cast<BaseIterator2>(bit))};
217 }
218
219 base_iterator base()const noexcept
220 {return local_iterator_impl::iterator_adaptor_::base();}
221 const std::type_info& type_info()const{return *mapit->first;}
222 segment_type& segment()noexcept
223 {return const_cast<segment_type&>(mapit->second);}
224 const segment_type& segment()const noexcept{return mapit->second;}
225
226 const_segment_map_iterator mapit;
227 };
228
229 template<typename PolyCollection,typename BaseIterator>
230 struct poly_collection_of<local_iterator_impl<PolyCollection,BaseIterator>>
231 {
232 using type=PolyCollection;
233 };
234
235
236 } /* namespace poly_collection::detail */
237
238 } /* namespace poly_collection */
239
240 } /* namespace boost */
241
242 #endif