• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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