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/container_adaptor.hpp 10 /// \brief Container adaptor to build a type that is compliant to the concept of a container. 11 12 #ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP 13 #define BOOST_BIMAP_CONTAINER_ADAPTOR_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/aux_/na.hpp> 25 #include <boost/bimap/container_adaptor/detail/identity_converters.hpp> 26 #include <boost/iterator/iterator_traits.hpp> 27 28 #include <boost/bimap/container_adaptor/detail/functor_bag.hpp> 29 #include <boost/mpl/vector.hpp> 30 #include <boost/mpl/copy.hpp> 31 #include <boost/mpl/front_inserter.hpp> 32 #include <boost/call_traits.hpp> 33 34 35 36 namespace boost { 37 namespace bimaps { 38 39 /// \brief Container Adaptor toolbox, easy way to build new containers from existing ones. 40 41 namespace container_adaptor { 42 43 /// \brief Container adaptor to build a type that is compliant to the concept of a container. 44 45 template 46 < 47 class Base, 48 49 class Iterator, 50 class ConstIterator, 51 52 class IteratorToBaseConverter = ::boost::mpl::na, 53 class IteratorFromBaseConverter = ::boost::mpl::na, 54 class ValueToBaseConverter = ::boost::mpl::na, 55 class ValueFromBaseConverter = ::boost::mpl::na, 56 57 class FunctorsFromDerivedClasses = mpl::vector<> 58 > 59 class container_adaptor 60 { 61 // MetaData ------------------------------------------------------------- 62 63 public: 64 65 typedef Iterator iterator; 66 typedef ConstIterator const_iterator; 67 68 typedef BOOST_DEDUCED_TYPENAME iterator_value < iterator >::type value_type; 69 typedef BOOST_DEDUCED_TYPENAME iterator_pointer < iterator >::type pointer; 70 typedef BOOST_DEDUCED_TYPENAME iterator_reference< iterator >::type reference; 71 typedef BOOST_DEDUCED_TYPENAME iterator_reference< const_iterator >::type const_reference; 72 73 typedef BOOST_DEDUCED_TYPENAME Base::size_type size_type; 74 typedef BOOST_DEDUCED_TYPENAME Base::difference_type difference_type; 75 76 typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorToBaseConverter>, 77 // { 78 ::boost::bimaps::container_adaptor::detail:: 79 iterator_to_base_identity 80 < 81 BOOST_DEDUCED_TYPENAME Base::iterator , iterator, 82 BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator 83 >, 84 // } 85 // else 86 // { 87 IteratorToBaseConverter 88 // } 89 90 >::type iterator_to_base; 91 92 typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorFromBaseConverter>, 93 // { 94 ::boost::bimaps::container_adaptor::detail:: 95 iterator_from_base_identity 96 < 97 BOOST_DEDUCED_TYPENAME Base::iterator , iterator, 98 BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator 99 >, 100 // } 101 // else 102 // { 103 IteratorFromBaseConverter 104 // } 105 106 >::type iterator_from_base; 107 108 typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueToBaseConverter>, 109 // { 110 ::boost::bimaps::container_adaptor::detail:: 111 value_to_base_identity 112 < 113 BOOST_DEDUCED_TYPENAME Base::value_type, 114 value_type 115 >, 116 // } 117 // else 118 // { 119 ValueToBaseConverter 120 // } 121 122 >::type value_to_base; 123 124 typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueFromBaseConverter>, 125 // { 126 ::boost::bimaps::container_adaptor::detail:: 127 value_from_base_identity 128 < 129 BOOST_DEDUCED_TYPENAME Base::value_type, 130 value_type 131 >, 132 // } 133 // else 134 // { 135 ValueFromBaseConverter 136 // } 137 138 >::type value_from_base; 139 140 // ACCESS ----------------------------------------------------------------- 141 142 public: 143 container_adaptor(Base & c)144 explicit container_adaptor(Base & c) : dwfb(c) {} 145 146 protected: 147 148 typedef Base base_type; 149 150 typedef container_adaptor container_adaptor_; 151 base() const152 const Base & base() const { return dwfb.data; } base()153 Base & base() { return dwfb.data; } 154 155 // Interface -------------------------------------------------------------- 156 157 public: 158 size() const159 size_type size() const { return base().size(); } max_size() const160 size_type max_size() const { return base().max_size(); } empty() const161 bool empty() const { return base().empty(); } 162 begin()163 iterator begin() 164 { 165 return this->template functor<iterator_from_base>()( base().begin() ); 166 } 167 end()168 iterator end() 169 { 170 return this->template functor<iterator_from_base>()( base().end() ); 171 } 172 begin() const173 const_iterator begin() const 174 { 175 return this->template functor<iterator_from_base>()( base().begin() ); 176 } 177 end() const178 const_iterator end() const 179 { 180 return this->template functor<iterator_from_base>()( base().end() ); 181 } 182 183 erase(iterator pos)184 iterator erase(iterator pos) 185 { 186 return this->template functor<iterator_from_base>()( 187 base().erase(this->template functor<iterator_to_base>()(pos)) 188 ); 189 } 190 erase(iterator first,iterator last)191 iterator erase(iterator first, iterator last) 192 { 193 return this->template functor<iterator_from_base>()( 194 base().erase( 195 this->template functor<iterator_to_base>()(first), 196 this->template functor<iterator_to_base>()(last) 197 ) 198 ); 199 } 200 clear()201 void clear() 202 { 203 base().clear(); 204 } 205 206 template< class InputIterator > insert(InputIterator iterBegin,InputIterator iterEnd)207 void insert(InputIterator iterBegin, InputIterator iterEnd) 208 { 209 for( ; iterBegin != iterEnd ; ++iterBegin ) 210 { 211 base().insert( this->template 212 functor<value_to_base>()( *iterBegin ) 213 ); 214 } 215 } 216 insert(BOOST_DEDUCED_TYPENAME::boost::call_traits<value_type>::param_type x)217 std::pair<iterator, bool> insert( 218 BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x) 219 { 220 std::pair< BOOST_DEDUCED_TYPENAME Base::iterator, bool > r( 221 base().insert( this->template functor<value_to_base>()(x) ) 222 ); 223 224 return std::pair<iterator, bool>( this->template 225 functor<iterator_from_base>()(r.first),r.second 226 ); 227 } 228 insert(iterator pos,BOOST_DEDUCED_TYPENAME::boost::call_traits<value_type>::param_type x)229 iterator insert(iterator pos, 230 BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x) 231 { 232 return this->template functor<iterator_from_base>()( 233 base().insert( 234 this->template functor<iterator_to_base>()(pos), 235 this->template functor<value_to_base>()(x)) 236 ); 237 } 238 swap(container_adaptor & c)239 void swap( container_adaptor & c ) 240 { 241 base().swap( c.base() ); 242 } 243 244 // Access to functors ---------------------------------------------------- 245 246 protected: 247 248 template< class Functor > functor()249 Functor & functor() 250 { 251 return dwfb.template functor<Functor>(); 252 } 253 254 template< class Functor > functor() const255 Functor const & functor() const 256 { 257 return dwfb.template functor<Functor>(); 258 } 259 260 // Data ------------------------------------------------------------------ 261 262 private: 263 264 ::boost::bimaps::container_adaptor::detail::data_with_functor_bag 265 < 266 Base &, 267 268 BOOST_DEDUCED_TYPENAME mpl::copy 269 < 270 mpl::vector 271 < 272 iterator_to_base, 273 iterator_from_base, 274 value_to_base, 275 value_from_base 276 >, 277 278 mpl::front_inserter< FunctorsFromDerivedClasses > 279 280 >::type 281 282 > dwfb; 283 }; 284 285 286 } // namespace container_adaptor 287 } // namespace bimaps 288 } // namespace boost 289 290 291 #endif // BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP 292