Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / bimap / container_adaptor / container_adaptor.hpp
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) && (_MSC_VER>=1200)
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
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
152     const Base & base() const { return dwfb.data; }
153           Base & base()       { return dwfb.data; }
154
155     // Interface --------------------------------------------------------------
156
157     public:
158
159     size_type size() const                    { return base().size();         }
160     size_type max_size() const                { return base().max_size();     }
161     bool empty() const                        { return base().empty();        }
162
163     iterator begin()
164     {
165         return this->template functor<iterator_from_base>()( base().begin() );
166     }
167
168     iterator end()
169     {
170         return this->template functor<iterator_from_base>()( base().end() );
171     }
172
173     const_iterator begin() const
174     {
175         return this->template functor<iterator_from_base>()( base().begin() );
176     }
177
178     const_iterator end() const
179     {
180         return this->template functor<iterator_from_base>()( base().end() );
181     }
182
183
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
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
201     void clear()
202     {
203         base().clear();
204     }
205
206     template< class InputIterator >
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
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
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
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 >
249     Functor & functor()
250     {
251         return dwfb.template functor<Functor>();
252     }
253
254     template< class Functor >
255     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