1 // Boost.Bimap 2 // 3 // Copyright (c) 2006-2007 Matias Capeletto 4 // 5 // Distributed under the Boost Software License, Version 1.0. 6 // (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 /// \file container_adaptor/sequence_container_adaptor.hpp 10 /// \brief Container adaptor to build a type that is compliant to the concept of a weak associative container. 11 12 #ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_SEQUENCE_CONTAINER_ADAPTOR_HPP 13 #define BOOST_BIMAP_CONTAINER_ADAPTOR_SEQUENCE_CONTAINER_ADAPTOR_HPP 14 15 #if defined(_MSC_VER) 16 #pragma once 17 #endif 18 19 #include <boost/config.hpp> 20 21 #include <utility> 22 23 #include <boost/mpl/if.hpp> 24 #include <boost/mpl/vector.hpp> 25 #include <boost/mpl/aux_/na.hpp> 26 #include <boost/bimap/container_adaptor/detail/identity_converters.hpp> 27 #include <boost/bimap/container_adaptor/container_adaptor.hpp> 28 #include <boost/call_traits.hpp> 29 #include <boost/operators.hpp> 30 31 namespace boost { 32 namespace bimaps { 33 namespace container_adaptor { 34 35 #ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES 36 37 template 38 < 39 class Base, class Iterator, class ConstIterator, 40 class ReverseIterator, class ConstReverseIterator, 41 class IteratorToBaseConverter, class IteratorFromBaseConverter, 42 class ReverseIteratorFromBaseConverter, 43 class ValueToBaseConverter, class ValueFromBaseConverter, 44 class FunctorsFromDerivedClasses 45 > 46 struct sequence_container_adaptor_base 47 { 48 typedef container_adaptor 49 < 50 Base, Iterator, ConstIterator, 51 IteratorToBaseConverter, IteratorFromBaseConverter, 52 ValueToBaseConverter, ValueFromBaseConverter, 53 54 BOOST_DEDUCED_TYPENAME mpl::push_front< 55 56 FunctorsFromDerivedClasses, 57 58 BOOST_DEDUCED_TYPENAME mpl::if_< 59 ::boost::mpl::is_na<ReverseIteratorFromBaseConverter>, 60 // { 61 detail::iterator_from_base_identity 62 < 63 BOOST_DEDUCED_TYPENAME Base::reverse_iterator, 64 ReverseIterator, 65 BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator, 66 ConstReverseIterator 67 >, 68 // } 69 // else 70 // { 71 ReverseIteratorFromBaseConverter 72 // } 73 74 >::type 75 76 >::type 77 78 > type; 79 }; 80 81 #endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES 82 83 /// \brief Container adaptor to build a type that is compliant to the concept of a sequence container. 84 85 template 86 < 87 class Base, 88 89 class Iterator, 90 class ConstIterator, 91 92 class ReverseIterator, 93 class ConstReverseIterator, 94 95 class IteratorToBaseConverter = ::boost::mpl::na, 96 class IteratorFromBaseConverter = ::boost::mpl::na, 97 class ReverseIteratorFromBaseConverter = ::boost::mpl::na, 98 class ValueToBaseConverter = ::boost::mpl::na, 99 class ValueFromBaseConverter = ::boost::mpl::na, 100 101 class FunctorsFromDerivedClasses = mpl::vector<> 102 > 103 class sequence_container_adaptor : 104 105 public sequence_container_adaptor_base 106 < 107 Base, Iterator, ConstIterator, 108 ReverseIterator, ConstReverseIterator, 109 IteratorToBaseConverter, IteratorFromBaseConverter, 110 ReverseIteratorFromBaseConverter, 111 ValueToBaseConverter, ValueFromBaseConverter, 112 FunctorsFromDerivedClasses 113 114 >::type, 115 116 ::boost::totally_ordered 117 < 118 sequence_container_adaptor 119 < 120 Base, Iterator, ConstIterator, 121 ReverseIterator, ConstReverseIterator, 122 IteratorToBaseConverter, IteratorFromBaseConverter, 123 ReverseIteratorFromBaseConverter, 124 ValueToBaseConverter, ValueFromBaseConverter, 125 FunctorsFromDerivedClasses 126 > 127 > 128 { 129 typedef BOOST_DEDUCED_TYPENAME sequence_container_adaptor_base 130 < 131 Base, Iterator, ConstIterator, 132 ReverseIterator, ConstReverseIterator, 133 IteratorToBaseConverter, IteratorFromBaseConverter, 134 ReverseIteratorFromBaseConverter, 135 ValueToBaseConverter, ValueFromBaseConverter, 136 FunctorsFromDerivedClasses 137 138 >::type base_; 139 140 // MetaData ------------------------------------------------------------- 141 142 public: 143 144 typedef ReverseIterator reverse_iterator; 145 typedef ConstReverseIterator const_reverse_iterator; 146 147 protected: 148 149 typedef BOOST_DEDUCED_TYPENAME mpl::if_< 150 ::boost::mpl::is_na<ReverseIteratorFromBaseConverter>, 151 // { 152 detail::iterator_from_base_identity 153 < 154 BOOST_DEDUCED_TYPENAME Base::reverse_iterator, 155 reverse_iterator, 156 BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator, 157 const_reverse_iterator 158 >, 159 // } 160 // else 161 // { 162 ReverseIteratorFromBaseConverter 163 // } 164 165 >::type reverse_iterator_from_base; 166 167 168 // Access ----------------------------------------------------------------- 169 170 public: 171 sequence_container_adaptor(Base & c)172 explicit sequence_container_adaptor(Base & c) 173 : base_(c) {} 174 175 protected: 176 177 178 typedef sequence_container_adaptor sequence_container_adaptor_; 179 180 // Interface -------------------------------------------------------------- 181 182 public: 183 rbegin()184 reverse_iterator rbegin() 185 { 186 return this->template functor< 187 reverse_iterator_from_base 188 >() ( this->base().rbegin() ); 189 190 } 191 rend()192 reverse_iterator rend() 193 { 194 return this->template functor< 195 reverse_iterator_from_base 196 >() ( this->base().rend() ); 197 } 198 rbegin() const199 const_reverse_iterator rbegin() const 200 { 201 return this->template functor< 202 reverse_iterator_from_base 203 >() ( this->base().rbegin() ); 204 } 205 rend() const206 const_reverse_iterator rend() const 207 { 208 return this->template functor< 209 reverse_iterator_from_base 210 >() ( this->base().rend() ); 211 } 212 resize(BOOST_DEDUCED_TYPENAME base_::size_type n,BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME base_::value_type>::param_type x=BOOST_DEDUCED_TYPENAME base_::value_type ())213 void resize(BOOST_DEDUCED_TYPENAME base_::size_type n, 214 BOOST_DEDUCED_TYPENAME ::boost::call_traits< 215 BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x = 216 BOOST_DEDUCED_TYPENAME base_::value_type()) 217 { 218 this->base().resize(n, 219 this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x) 220 ); 221 } 222 front()223 BOOST_DEDUCED_TYPENAME base_::reference front() 224 { 225 return this->template functor< 226 BOOST_DEDUCED_TYPENAME base_::value_from_base>() 227 ( 228 this->base().front() 229 ); 230 } 231 back()232 BOOST_DEDUCED_TYPENAME base_::reference back() 233 { 234 return this->template functor< 235 BOOST_DEDUCED_TYPENAME base_::value_from_base>() 236 ( 237 this->base().back() 238 ); 239 } 240 front() const241 BOOST_DEDUCED_TYPENAME base_::const_reference front() const 242 { 243 return this->template functor< 244 BOOST_DEDUCED_TYPENAME base_::value_from_base>() 245 ( 246 this->base().front() 247 ); 248 } 249 back() const250 BOOST_DEDUCED_TYPENAME base_::const_reference back() const 251 { 252 return this->template functor< 253 BOOST_DEDUCED_TYPENAME base_::value_from_base>() 254 ( 255 this->base().back() 256 ); 257 } 258 push_front(BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME base_::value_type>::param_type x)259 void push_front( 260 BOOST_DEDUCED_TYPENAME ::boost::call_traits< 261 BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) 262 { 263 this->base().push_front( 264 this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x)); 265 } 266 pop_front()267 void pop_front() 268 { 269 this->base().pop_front(); 270 } 271 push_back(BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME base_::value_type>::param_type x)272 void push_back( 273 BOOST_DEDUCED_TYPENAME ::boost::call_traits< 274 BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) 275 { 276 this->base().push_back( 277 this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x)); 278 } 279 pop_back()280 void pop_back() 281 { 282 this->base().pop_back(); 283 } 284 285 std::pair<BOOST_DEDUCED_TYPENAME base_::iterator,bool> insert(BOOST_DEDUCED_TYPENAME base_::iterator position,BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME base_::value_type>::param_type x)286 insert(BOOST_DEDUCED_TYPENAME base_::iterator position, 287 BOOST_DEDUCED_TYPENAME ::boost::call_traits< 288 BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) 289 { 290 std::pair< BOOST_DEDUCED_TYPENAME Base::iterator, bool > r( 291 this->base().insert( 292 this->template functor< 293 BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), 294 this->template functor< 295 BOOST_DEDUCED_TYPENAME base_::value_to_base >()(x) 296 ) 297 ); 298 299 return std::pair<BOOST_DEDUCED_TYPENAME base_::iterator, bool>( 300 this->template functor< 301 BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(r.first), 302 r.second 303 ); 304 } 305 insert(BOOST_DEDUCED_TYPENAME base_::iterator position,BOOST_DEDUCED_TYPENAME base_::size_type m,BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME base_::value_type>::param_type x)306 void insert(BOOST_DEDUCED_TYPENAME base_::iterator position, 307 BOOST_DEDUCED_TYPENAME base_::size_type m, 308 BOOST_DEDUCED_TYPENAME ::boost::call_traits< 309 BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) 310 { 311 this->base().insert( 312 this->template functor< 313 BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position), 314 m, 315 this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base >()(x) 316 ); 317 } 318 319 template< class InputIterator > insert(BOOST_DEDUCED_TYPENAME base_::iterator position,InputIterator first,InputIterator last)320 void insert(BOOST_DEDUCED_TYPENAME base_::iterator position, 321 InputIterator first, InputIterator last) 322 { 323 // This is the same problem found in the insert function 324 // of container_adaptor 325 // For now, do the simple thing. This can be optimized 326 327 for( ; first != last ; ++first ) 328 { 329 this->base().insert( 330 this->template functor< 331 BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()( position ), 332 this->template functor< 333 BOOST_DEDUCED_TYPENAME base_::value_to_base >()( *first ) 334 ); 335 } 336 } 337 338 // Totally ordered implementation 339 operator ==(const sequence_container_adaptor & c) const340 bool operator==(const sequence_container_adaptor & c) const 341 { 342 return ( this->base() == c.base() ); 343 } 344 operator <(const sequence_container_adaptor & c) const345 bool operator<(const sequence_container_adaptor & c) const 346 { 347 return ( this->base() < c.base() ); 348 } 349 }; 350 351 } // namespace container_adaptor 352 } // namespace bimaps 353 } // namespace boost 354 355 356 #endif // BOOST_BIMAP_CONTAINER_ADAPTOR_SEQUENCE_CONTAINER_ADAPTOR_HPP 357