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/ordered_associative_container_adaptor.hpp
10 /// \brief Container adaptor to build a type that is compliant to the concept of an ordered associative container.
11 
12 #ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_ORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP
13 #define BOOST_BIMAP_CONTAINER_ADAPTOR_ORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP
14 
15 #if defined(_MSC_VER)
16 #pragma once
17 #endif
18 
19 #include <boost/config.hpp>
20 
21 #include <boost/bimap/container_adaptor/associative_container_adaptor.hpp>
22 #include <boost/bimap/container_adaptor/detail/comparison_adaptor.hpp>
23 #include <boost/mpl/if.hpp>
24 #include <boost/mpl/vector.hpp>
25 #include <boost/mpl/push_front.hpp>
26 #include <boost/mpl/aux_/na.hpp>
27 #include <boost/operators.hpp>
28 #include <boost/call_traits.hpp>
29 
30 namespace boost {
31 namespace bimaps {
32 namespace container_adaptor {
33 
34 #ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
35 
36 template
37 <
38     class Base, class Iterator, class ConstIterator,
39     class ReverseIterator, class ConstReverseIterator, class KeyType,
40     class IteratorToBaseConverter, class IteratorFromBaseConverter,
41     class ReverseIteratorFromBaseConverter,
42     class ValueToBaseConverter, class ValueFromBaseConverter,
43     class KeyToBaseConverter,
44     class FunctorsFromDerivedClasses
45 >
46 struct ordered_associative_container_adaptor_base
47 {
48     typedef associative_container_adaptor<
49         Base, Iterator, ConstIterator, KeyType,
50         IteratorToBaseConverter, IteratorFromBaseConverter,
51         ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter,
52 
53         BOOST_DEDUCED_TYPENAME mpl::push_front<
54 
55             FunctorsFromDerivedClasses,
56 
57             BOOST_DEDUCED_TYPENAME mpl::if_<
58                 ::boost::mpl::is_na<ReverseIteratorFromBaseConverter>,
59             // {
60                     detail::iterator_from_base_identity
61                     <
62                         BOOST_DEDUCED_TYPENAME Base::reverse_iterator,
63                         ReverseIterator,
64                         BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator,
65                         ConstReverseIterator
66                     >,
67             // }
68             // else
69             // {
70                     ReverseIteratorFromBaseConverter
71             // }
72 
73             >::type
74 
75         >::type
76 
77     > type;
78 };
79 
80 #endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
81 
82 /// \brief Container adaptor to build a type that is compliant to the concept of an ordered associative container.
83 
84 template
85 <
86     class Base,
87 
88     class Iterator,
89     class ConstIterator,
90     class ReverseIterator,
91     class ConstReverseIterator,
92 
93     class KeyType,
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     class KeyToBaseConverter               = ::boost::mpl::na,
101 
102     class FunctorsFromDerivedClasses = mpl::vector<>
103 >
104 class ordered_associative_container_adaptor :
105 
106     public ordered_associative_container_adaptor_base
107     <
108         Base, Iterator, ConstIterator,
109         ReverseIterator, ConstReverseIterator, KeyType,
110         IteratorToBaseConverter, IteratorFromBaseConverter,
111         ReverseIteratorFromBaseConverter,
112         ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter,
113         FunctorsFromDerivedClasses
114 
115     >::type,
116 
117     ::boost::totally_ordered
118     <
119         ordered_associative_container_adaptor
120         <
121             Base, Iterator, ConstIterator,
122             ReverseIterator, ConstReverseIterator,
123             KeyType, IteratorToBaseConverter, IteratorFromBaseConverter,
124             ReverseIteratorFromBaseConverter,
125             ValueToBaseConverter, ValueFromBaseConverter,
126             KeyToBaseConverter, FunctorsFromDerivedClasses
127         >
128     >
129 {
130     // MetaData -------------------------------------------------------------
131 
132     typedef BOOST_DEDUCED_TYPENAME ordered_associative_container_adaptor_base
133     <
134         Base, Iterator, ConstIterator,
135         ReverseIterator, ConstReverseIterator, KeyType,
136         IteratorToBaseConverter, IteratorFromBaseConverter,
137         ReverseIteratorFromBaseConverter,
138         ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter,
139         FunctorsFromDerivedClasses
140 
141     >::type base_;
142 
143     public:
144 
145     typedef detail::compatible_comparison_adaptor
146     <
147         BOOST_DEDUCED_TYPENAME Base::key_compare,
148         BOOST_DEDUCED_TYPENAME base_::key_type,
149         BOOST_DEDUCED_TYPENAME base_::key_to_base
150 
151     > key_compare;
152 
153     typedef detail::comparison_adaptor
154     <
155         BOOST_DEDUCED_TYPENAME Base::value_compare,
156         BOOST_DEDUCED_TYPENAME base_::value_type,
157         BOOST_DEDUCED_TYPENAME base_::value_to_base
158 
159     > value_compare;
160 
161     typedef ReverseIterator      reverse_iterator;
162     typedef ConstReverseIterator const_reverse_iterator;
163 
164     protected:
165 
166     typedef BOOST_DEDUCED_TYPENAME mpl::if_<
167         ::boost::mpl::is_na<ReverseIteratorFromBaseConverter>,
168         // {
169                 detail::iterator_from_base_identity
170                 <
171                     BOOST_DEDUCED_TYPENAME Base::reverse_iterator,
172                     reverse_iterator,
173                     BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator,
174                     const_reverse_iterator
175                 >,
176         // }
177         // else
178         // {
179                 ReverseIteratorFromBaseConverter
180         // }
181 
182         >::type reverse_iterator_from_base;
183 
184     // Access -----------------------------------------------------------------
185 
186     public:
187 
ordered_associative_container_adaptor(Base & c)188     explicit ordered_associative_container_adaptor(Base & c)
189         : base_(c) {}
190 
191     protected:
192 
193     typedef ordered_associative_container_adaptor
194                 ordered_associative_container_adaptor_;
195 
196     // Interface --------------------------------------------------------------
197 
198     public:
199 
rbegin()200     reverse_iterator rbegin()
201     {
202         return this->template functor<
203             reverse_iterator_from_base
204         >()                            ( this->base().rbegin() );
205 
206     }
207 
rend()208     reverse_iterator rend()
209     {
210         return this->template functor<
211             reverse_iterator_from_base
212         >()                            ( this->base().rend() );
213     }
214 
rbegin() const215     const_reverse_iterator rbegin() const
216     {
217         return this->template functor<
218             reverse_iterator_from_base
219         >()                            ( this->base().rbegin() );
220     }
221 
rend() const222     const_reverse_iterator rend() const
223     {
224         return this->template functor<
225             reverse_iterator_from_base
226         >()                            ( this->base().rend() );
227     }
228 
key_comp() const229     key_compare key_comp() const
230     {
231         typedef BOOST_DEDUCED_TYPENAME base_::key_to_base key_to_base_;
232 
233         return key_compare(
234             this->base().key_comp(),
235             this->template functor<key_to_base_>()
236         );
237     }
238 
value_comp() const239     value_compare value_comp() const
240     {
241         typedef BOOST_DEDUCED_TYPENAME base_::value_to_base value_to_base_;
242 
243         return value_compare(
244             this->base().value_comp(),
245             this->template functor<value_to_base_>()
246         );
247     }
248 
249     template< class CompatibleKey >
lower_bound(const CompatibleKey & k)250     BOOST_DEDUCED_TYPENAME base_::iterator lower_bound(const CompatibleKey & k)
251     {
252        return this->template functor<
253             BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(
254                 this->base().lower_bound(
255                     this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)
256                 )
257             );
258     }
259 
260     template< class CompatibleKey >
lower_bound(const CompatibleKey & k) const261     BOOST_DEDUCED_TYPENAME base_::const_iterator lower_bound(const CompatibleKey & k) const
262     {
263        return this->template functor<
264             BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(
265                 this->base().lower_bound(
266                     this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)
267                 )
268             );
269     }
270 
271     template< class CompatibleKey >
upper_bound(const CompatibleKey & k)272     BOOST_DEDUCED_TYPENAME base_::iterator upper_bound(const CompatibleKey & k)
273     {
274        return this->template functor<
275             BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(
276                 this->base().upper_bound(
277                     this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)
278                 )
279             );
280     }
281 
282     template< class CompatibleKey >
upper_bound(const CompatibleKey & k) const283     BOOST_DEDUCED_TYPENAME base_::const_iterator upper_bound(const CompatibleKey & k) const
284     {
285         return this->template functor<
286             BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(
287                 this->base().upper_bound(
288                     this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)
289                 )
290             );
291     }
292 
293     // Totally ordered implementation
294 
operator ==(const ordered_associative_container_adaptor & c) const295     bool operator==(const ordered_associative_container_adaptor & c) const
296     {
297         return ( this->base() == c.base() );
298     }
299 
operator <(const ordered_associative_container_adaptor & c) const300     bool operator<(const ordered_associative_container_adaptor & c) const
301     {
302         return ( this->base() < c.base() );
303     }
304 };
305 
306 
307 } // namespace container_adaptor
308 } // namespace bimaps
309 } // namespace boost
310 
311 
312 #endif // BOOST_BIMAP_CONTAINER_ADAPTOR_ORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP
313