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/list_map_adaptor.hpp
10 /// \brief Container adaptor.
11 
12 #ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_MAP_ADAPTOR_HPP
13 #define BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_MAP_ADAPTOR_HPP
14 
15 #if defined(_MSC_VER)
16 #pragma once
17 #endif
18 
19 #include <boost/config.hpp>
20 
21 #include <boost/mpl/list.hpp>
22 #include <boost/mpl/push_front.hpp>
23 
24 #include <boost/bimap/container_adaptor/list_adaptor.hpp>
25 #include <boost/bimap/container_adaptor/detail/identity_converters.hpp>
26 #include <boost/bimap/container_adaptor/detail/key_extractor.hpp>
27 #include <boost/bimap/container_adaptor/detail/comparison_adaptor.hpp>
28 #include <boost/mpl/vector.hpp>
29 #include <boost/mpl/aux_/na.hpp>
30 #include <boost/mpl/if.hpp>
31 
32 namespace boost {
33 namespace bimaps {
34 namespace container_adaptor {
35 
36 #ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
37 
38 template
39 <
40     class Base, class Iterator, class ConstIterator,
41     class ReverseIterator, class ConstReverseIterator,
42     class IteratorToBaseConverter, class IteratorFromBaseConverter,
43     class ReverseIteratorFromBaseConverter,
44     class ValueToBaseConverter, class ValueFromBaseConverter,
45     class KeyFromBaseValueConverter,
46     class FunctorsFromDerivedClasses
47 >
48 struct list_map_adaptor_base
49 {
50     typedef list_adaptor
51     <
52         Base,
53 
54         Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
55 
56         IteratorToBaseConverter, IteratorFromBaseConverter,
57 
58         ReverseIteratorFromBaseConverter,
59 
60         ValueToBaseConverter, ValueFromBaseConverter,
61 
62         BOOST_DEDUCED_TYPENAME mpl::push_front<
63 
64             FunctorsFromDerivedClasses,
65 
66             BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<KeyFromBaseValueConverter>,
67             // {
68                     detail::key_from_pair_extractor
69                     <
70                         BOOST_DEDUCED_TYPENAME Iterator::value_type
71                     >,
72             // }
73             // else
74             // {
75                     KeyFromBaseValueConverter
76             // }
77 
78             >::type
79 
80         >::type
81 
82     > type;
83 };
84 
85 #endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
86 
87 /// \brief Container adaptor to easily build a list map container
88 
89 template
90 <
91     class Base,
92 
93     class Iterator,
94     class ConstIterator,
95     class ReverseIterator,
96     class ConstReverseIterator,
97 
98     class IteratorToBaseConverter          = ::boost::mpl::na,
99     class IteratorFromBaseConverter        = ::boost::mpl::na,
100     class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
101     class ValueToBaseConverter             = ::boost::mpl::na,
102     class ValueFromBaseConverter           = ::boost::mpl::na,
103     class KeyFromBaseValueConverter        = ::boost::mpl::na,
104 
105     class FunctorsFromDerivedClasses = mpl::vector<>
106 >
107 class list_map_adaptor :
108 
109     public list_map_adaptor_base
110     <
111         Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
112         IteratorToBaseConverter, IteratorFromBaseConverter,
113         ReverseIteratorFromBaseConverter,
114         ValueToBaseConverter, ValueFromBaseConverter,
115         KeyFromBaseValueConverter,
116         FunctorsFromDerivedClasses
117 
118     >::type
119 {
120     typedef BOOST_DEDUCED_TYPENAME list_map_adaptor_base
121     <
122         Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
123         IteratorToBaseConverter, IteratorFromBaseConverter,
124         ReverseIteratorFromBaseConverter,
125         ValueToBaseConverter, ValueFromBaseConverter,
126         KeyFromBaseValueConverter,
127         FunctorsFromDerivedClasses
128 
129     >::type base_;
130 
131     // MetaData -------------------------------------------------------------
132 
133     public:
134 
135     typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type  key_type;
136     typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type;
137     typedef data_type mapped_type;
138 
139     protected:
140 
141     typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<KeyFromBaseValueConverter>,
142     // {
143             detail::key_from_pair_extractor< BOOST_DEDUCED_TYPENAME Iterator::value_type >,
144     // }
145     // else
146     // {
147             KeyFromBaseValueConverter
148     // }
149 
150     >::type key_from_base_value;
151 
152     // Access -----------------------------------------------------------------
153 
154     public:
155 
list_map_adaptor(Base & c)156     explicit list_map_adaptor(Base & c) :
157         base_(c) {}
158 
159     protected:
160 
161     typedef list_map_adaptor list_map_adaptor_;
162 
163     // Functions -------------------------------------------------------------
164 
165     public:
166 
167     // The following functions are overwritten in order to work
168     // with key_type instead of value_type
169 
170     template< class Predicate >
remove_if(Predicate pred)171     void remove_if(Predicate pred)
172     {
173         this->base().remove_if(
174             ::boost::bimaps::container_adaptor::detail::unary_check_adaptor
175             <
176                 Predicate,
177                 BOOST_DEDUCED_TYPENAME Base::value_type,
178                 key_from_base_value
179 
180             >( pred, this->template functor<key_from_base_value>() )
181         );
182     }
183 
unique()184     void unique()
185     {
186         this->base().unique(
187             ::boost::bimaps::container_adaptor::detail::comparison_adaptor
188             <
189                 std::equal_to<key_type>,
190                 BOOST_DEDUCED_TYPENAME Base::value_type,
191                 key_from_base_value
192 
193             >(
194                 std::equal_to<key_type>(),
195                 this->template functor<key_from_base_value>()
196             )
197         );
198     }
199 
200     template< class BinaryPredicate >
unique(BinaryPredicate binary_pred)201     void unique(BinaryPredicate binary_pred)
202     {
203         this->base().unique(
204             ::boost::bimaps::container_adaptor::detail::comparison_adaptor
205             <
206                 BinaryPredicate,
207                 BOOST_DEDUCED_TYPENAME Base::value_type,
208                 key_from_base_value
209 
210             >( binary_pred, this->template functor<key_from_base_value>() )
211         );
212     }
213 
merge(list_map_adaptor & x)214     void merge(list_map_adaptor & x)
215     {
216         this->base().merge(x.base(),
217             ::boost::bimaps::container_adaptor::detail::comparison_adaptor
218             <
219                 std::less<key_type>,
220                 BOOST_DEDUCED_TYPENAME Base::value_type,
221                 key_from_base_value
222 
223             >(
224                 std::less<key_type>(),
225                 this->template functor<key_from_base_value>()
226             )
227         );
228     }
229 
230     template< class Compare >
merge(list_map_adaptor & x,Compare comp)231     void merge(list_map_adaptor & x, Compare comp)
232     {
233         this->base().merge(x.base(),
234             ::boost::bimaps::container_adaptor::detail::comparison_adaptor
235             <
236                 Compare,
237                 BOOST_DEDUCED_TYPENAME Base::value_type,
238                 key_from_base_value
239 
240             >( comp, this->template functor<key_from_base_value>() )
241         );
242     }
243 
sort()244     void sort()
245     {
246         this->base().sort(
247             ::boost::bimaps::container_adaptor::detail::comparison_adaptor
248             <
249                 std::less<key_type>,
250                 BOOST_DEDUCED_TYPENAME Base::value_type,
251                 key_from_base_value
252 
253             >(
254                 std::less<key_type>(),
255                 this->template functor<key_from_base_value>()
256             )
257         );
258     }
259 
260     template< class Compare >
sort(Compare comp)261     void sort(Compare comp)
262     {
263         this->base().sort(
264             ::boost::bimaps::container_adaptor::detail::comparison_adaptor
265             <
266                 Compare,
267                 BOOST_DEDUCED_TYPENAME Base::value_type,
268                 key_from_base_value
269 
270             >( comp, this->template functor<key_from_base_value>() )
271         );
272     }
273 
274 };
275 
276 
277 } // namespace container_adaptor
278 } // namespace bimaps
279 } // namespace boost
280 
281 
282 #endif // BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_MAP_ADAPTOR_HPP
283 
284