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 detail/set_view_base.hpp
10 /// \brief Helper base for the construction of the bimap views types.
11 
12 #ifndef BOOST_BIMAP_DETAIL_SET_VIEW_BASE_HPP
13 #define BOOST_BIMAP_DETAIL_SET_VIEW_BASE_HPP
14 
15 #if defined(_MSC_VER)
16 #pragma once
17 #endif
18 
19 #include <boost/config.hpp>
20 
21 #include <boost/bimap/relation/member_at.hpp>
22 #include <boost/bimap/relation/support/data_extractor.hpp>
23 #include <boost/bimap/detail/modifier_adaptor.hpp>
24 #include <boost/bimap/detail/set_view_iterator.hpp>
25 #include <boost/bimap/relation/support/get_pair_functor.hpp>
26 #include <boost/bimap/relation/detail/to_mutable_relation_functor.hpp>
27 #include <boost/bimap/relation/mutant_relation.hpp>
28 #include <boost/bimap/container_adaptor/support/iterator_facade_converters.hpp>
29 
30 namespace boost {
31 namespace bimaps {
32 namespace detail {
33 
34 template< class Key, class Value, class KeyToBase >
35 class set_view_key_to_base
36 {
37     public:
operator ()(const Value & v) const38     const Key operator()( const Value & v ) const
39     {
40         return keyToBase( v );
41     }
42     private:
43     KeyToBase keyToBase;
44 };
45 
46 template< class MutantRelationStorage, class KeyToBase >
47 class set_view_key_to_base<MutantRelationStorage,MutantRelationStorage,KeyToBase>
48 {
49     typedef BOOST_DEDUCED_TYPENAME MutantRelationStorage::non_mutable_storage non_mutable_storage;
50     public:
operator ()(const non_mutable_storage & k) const51     const MutantRelationStorage & operator()( const non_mutable_storage & k ) const
52     {
53         return ::boost::bimaps::relation::detail::mutate<MutantRelationStorage>(k);
54     }
operator ()(const MutantRelationStorage & k) const55     const MutantRelationStorage & operator()( const MutantRelationStorage & k ) const
56     {
57         return k;
58     }
59 };
60 
61 
62 // The next macro can be converted in a metafunctor to gain code robustness.
63 /*===========================================================================*/
64 #define BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR(                               \
65     CONTAINER_ADAPTOR, CORE_INDEX, OTHER_ITER, CONST_OTHER_ITER               \
66 )                                                                             \
67 ::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR                         \
68 <                                                                             \
69     CORE_INDEX,                                                               \
70     ::boost::bimaps::detail::                                                 \
71               set_view_iterator<                                              \
72                     BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator         >,    \
73     ::boost::bimaps::detail::                                                 \
74         const_set_view_iterator<                                              \
75                     BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator   >,    \
76     ::boost::bimaps::detail::                                                 \
77               set_view_iterator<                                              \
78                     BOOST_DEDUCED_TYPENAME CORE_INDEX::OTHER_ITER       >,    \
79     ::boost::bimaps::detail::                                                 \
80         const_set_view_iterator<                                              \
81                     BOOST_DEDUCED_TYPENAME CORE_INDEX::CONST_OTHER_ITER >,    \
82     ::boost::bimaps::container_adaptor::support::iterator_facade_to_base      \
83     <                                                                         \
84         ::boost::bimaps::detail::      set_view_iterator<                     \
85             BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator>,                     \
86         ::boost::bimaps::detail::const_set_view_iterator<                     \
87             BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator>                \
88                                                                               \
89     >,                                                                        \
90     ::boost::mpl::na,                                                         \
91     ::boost::mpl::na,                                                         \
92     ::boost::bimaps::relation::detail::                                       \
93         get_mutable_relation_functor<                                         \
94             BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >,                  \
95     ::boost::bimaps::relation::support::                                      \
96         get_above_view_functor<                                               \
97             BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >,                  \
98     ::boost::bimaps::detail::set_view_key_to_base<                            \
99         BOOST_DEDUCED_TYPENAME CORE_INDEX::key_type,                          \
100         BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type,                        \
101         BOOST_DEDUCED_TYPENAME CORE_INDEX::key_from_value                     \
102     >                                                                         \
103 >
104 /*===========================================================================*/
105 
106 
107 /*===========================================================================*/
108 #define BOOST_BIMAP_SEQUENCED_SET_VIEW_CONTAINER_ADAPTOR(                     \
109     CONTAINER_ADAPTOR, CORE_INDEX, OTHER_ITER, CONST_OTHER_ITER               \
110 )                                                                             \
111 ::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR                         \
112 <                                                                             \
113     CORE_INDEX,                                                               \
114     ::boost::bimaps::detail::                                                 \
115               set_view_iterator<                                              \
116                     BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator         >,    \
117     ::boost::bimaps::detail::                                                 \
118         const_set_view_iterator<                                              \
119                     BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator   >,    \
120     ::boost::bimaps::detail::                                                 \
121               set_view_iterator<                                              \
122                     BOOST_DEDUCED_TYPENAME CORE_INDEX::OTHER_ITER       >,    \
123     ::boost::bimaps::detail::                                                 \
124         const_set_view_iterator<                                              \
125                     BOOST_DEDUCED_TYPENAME CORE_INDEX::CONST_OTHER_ITER >,    \
126     ::boost::bimaps::container_adaptor::support::iterator_facade_to_base      \
127     <                                                                         \
128         ::boost::bimaps::detail::      set_view_iterator<                     \
129             BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator>,                     \
130         ::boost::bimaps::detail::const_set_view_iterator<                     \
131             BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator>                \
132                                                                               \
133     >,                                                                        \
134     ::boost::mpl::na,                                                         \
135     ::boost::mpl::na,                                                         \
136     ::boost::bimaps::relation::detail::                                       \
137         get_mutable_relation_functor<                                         \
138             BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >,                  \
139     ::boost::bimaps::relation::support::                                      \
140         get_above_view_functor<                                               \
141             BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >                   \
142 >
143 /*===========================================================================*/
144 
145 
146 #if defined(BOOST_MSVC)
147 /*===========================================================================*/
148 #define BOOST_BIMAP_SET_VIEW_BASE_FRIEND(TYPE,INDEX_TYPE)                     \
149     typedef ::boost::bimaps::detail::set_view_base<                           \
150         TYPE< INDEX_TYPE >, INDEX_TYPE > template_class_friend;               \
151     friend class template_class_friend;
152 /*===========================================================================*/
153 #else
154 /*===========================================================================*/
155 #define BOOST_BIMAP_SET_VIEW_BASE_FRIEND(TYPE,INDEX_TYPE)                     \
156     friend class ::boost::bimaps::detail::set_view_base<                      \
157         TYPE< INDEX_TYPE >, INDEX_TYPE >;
158 /*===========================================================================*/
159 #endif
160 
161 
162 /// \brief Common base for set views.
163 
164 template< class Derived, class Index >
165 class set_view_base
166 {
167     typedef ::boost::bimaps::container_adaptor::support::
168     iterator_facade_to_base
169     <
170         ::boost::bimaps::detail::
171                   set_view_iterator<BOOST_DEDUCED_TYPENAME Index::      iterator>,
172         ::boost::bimaps::detail::
173             const_set_view_iterator<BOOST_DEDUCED_TYPENAME Index::const_iterator>
174 
175     > iterator_to_base_;
176 
177     typedef BOOST_DEDUCED_TYPENAME Index::value_type::left_value_type          left_type_;
178 
179     typedef BOOST_DEDUCED_TYPENAME Index::value_type::right_value_type        right_type_;
180 
181     typedef BOOST_DEDUCED_TYPENAME Index::value_type                          value_type_;
182 
183     typedef ::boost::bimaps::detail::
184                     set_view_iterator<BOOST_DEDUCED_TYPENAME Index::iterator>   iterator_;
185 
186     public:
187 
replace(iterator_ position,const value_type_ & x)188     bool replace(iterator_ position,
189                  const value_type_ & x)
190     {
191         return derived().base().replace(
192             derived().template functor<iterator_to_base_>()(position),x
193         );
194     }
195 
196     template< class CompatibleLeftType >
replace_left(iterator_ position,const CompatibleLeftType & l)197     bool replace_left(iterator_ position,
198                       const CompatibleLeftType & l)
199     {
200         return derived().base().replace(
201             derived().template functor<iterator_to_base_>()(position),
202             ::boost::bimaps::relation::detail::copy_with_left_replaced(*position,l)
203         );
204     }
205 
206     template< class CompatibleRightType >
replace_right(iterator_ position,const CompatibleRightType & r)207     bool replace_right(iterator_ position,
208                        const CompatibleRightType & r)
209     {
210         return derived().base().replace(
211             derived().template functor<iterator_to_base_>()(position),
212             ::boost::bimaps::relation::detail::copy_with_right_replaced(*position,r)
213         );
214     }
215 
216     /* This function may be provided in the future
217 
218     template< class Modifier >
219     bool modify(iterator_ position,
220                 Modifier mod)
221     {
222         return derived().base().modify(
223 
224             derived().template functor<iterator_to_base_>()(position),
225 
226             ::boost::bimaps::detail::relation_modifier_adaptor
227             <
228                 Modifier,
229                 BOOST_DEDUCED_TYPENAME Index::value_type,
230                 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
231                 data_extractor
232                 <
233                     ::boost::bimaps::relation::member_at::left,
234                     BOOST_DEDUCED_TYPENAME Index::value_type
235 
236                 >::type,
237                 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
238                 data_extractor
239                 <
240                     ::boost::bimaps::relation::member_at::right,
241                     BOOST_DEDUCED_TYPENAME Index::value_type
242 
243                 >::type
244 
245             >(mod)
246         );
247     }
248     */
249     /*
250     template< class Modifier >
251     bool modify_left(iterator_ position, Modifier mod)
252     {
253         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
254         data_extractor
255         <
256             BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::member_at::right,
257             BOOST_DEDUCED_TYPENAME Index::value_type
258 
259         >::type left_data_extractor_;
260 
261         return derived().base().modify(
262 
263             derived().template functor<iterator_to_base_>()(position),
264 
265             // this may be replaced later by
266             // ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) )
267 
268             ::boost::bimaps::detail::unary_modifier_adaptor
269             <
270                 Modifier,
271                 BOOST_DEDUCED_TYPENAME Index::value_type,
272                 left_data_extractor_
273 
274             >(mod)
275         );
276     }
277 
278     template< class Modifier >
279     bool modify_right(iterator_ position, Modifier mod)
280     {
281         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
282         data_extractor
283         <
284             BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::member_at::right,
285             BOOST_DEDUCED_TYPENAME Index::value_type
286 
287         >::type right_data_extractor_;
288 
289         return derived().base().modify(
290 
291             derived().template functor<iterator_to_base_>()(position),
292 
293             // this may be replaced later by
294             // ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) )
295 
296             ::boost::bimaps::detail::unary_modifier_adaptor
297             <
298                 Modifier,
299                 BOOST_DEDUCED_TYPENAME Index::value_type,
300                 right_data_extractor_
301 
302             >(mod)
303         );
304     }
305     */
306     protected:
307 
308     typedef set_view_base set_view_base_;
309 
310     private:
311 
312     // Curiously Recurring Template interface.
313 
derived()314     Derived& derived()
315     {
316         return *static_cast<Derived*>(this);
317     }
318 
derived() const319     Derived const& derived() const
320     {
321         return *static_cast<Derived const*>(this);
322     }
323 };
324 
325 
326 
327 } // namespace detail
328 } // namespace bimaps
329 } // namespace boost
330 
331 #endif // BOOST_BIMAP_DETAIL_SET_VIEW_BASE_HPP
332