Add SCons configure checks
[senf.git] / boost_ext / boost / bimap / detail / map_view_base.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 detail/map_view_base.hpp
10 /// \brief Helper base for the construction of the bimap views types.
11
12 #ifndef BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
13 #define BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
14
15 #if defined(_MSC_VER) && (_MSC_VER>=1200)
16 #pragma once
17 #endif
18
19 #include <boost/config.hpp>
20
21 #include <stdexcept>
22 #include <utility>
23
24 #include <boost/type_traits/is_const.hpp>
25 #include <boost/mpl/if.hpp>
26
27 #include <boost/bimap/relation/support/get_pair_functor.hpp>
28 #include <boost/bimap/relation/detail/to_mutable_relation_functor.hpp>
29 #include <boost/bimap/container_adaptor/support/iterator_facade_converters.hpp>
30 #include <boost/bimap/relation/support/data_extractor.hpp>
31 #include <boost/bimap/relation/support/opposite_tag.hpp>
32 #include <boost/bimap/relation/support/pair_type_by.hpp>
33 #include <boost/bimap/support/iterator_type_by.hpp>
34 #include <boost/bimap/support/key_type_by.hpp>
35 #include <boost/bimap/support/data_type_by.hpp>
36 #include <boost/bimap/support/value_type_by.hpp>
37 #include <boost/bimap/detail/modifier_adaptor.hpp>
38 #include <boost/bimap/detail/debug/static_error.hpp>
39
40 namespace boost {
41 namespace bimaps {
42
43 namespace detail {
44
45
46 // The next macro can be converted in a metafunctor to gain code robustness.
47 /*===========================================================================*/
48 #define BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR(                               \
49     CONTAINER_ADAPTOR, TAG,BIMAP, OTHER_ITER, CONST_OTHER_ITER                \
50 )                                                                             \
51 ::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR                         \
52 <                                                                             \
53     BOOST_DEDUCED_TYPENAME BIMAP::core_type::                                 \
54         BOOST_NESTED_TEMPLATE index<TAG>::type,                               \
55     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                         \
56         iterator_type_by<TAG,BIMAP>::type,                                    \
57     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                         \
58         const_iterator_type_by<TAG,BIMAP>::type,                              \
59     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                         \
60         OTHER_ITER<TAG,BIMAP>::type,                                          \
61     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                         \
62         CONST_OTHER_ITER<TAG,BIMAP>::type,                                    \
63     ::boost::bimaps::container_adaptor::support::iterator_facade_to_base      \
64     <                                                                         \
65         BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                     \
66                   iterator_type_by<TAG,BIMAP>::type,                          \
67         BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                     \
68             const_iterator_type_by<TAG,BIMAP>::type                           \
69                                                                               \
70     >,                                                                        \
71     ::boost::mpl::na,                                                         \
72     ::boost::mpl::na,                                                         \
73     ::boost::bimaps::relation::detail::                                       \
74         pair_to_relation_functor<TAG,BOOST_DEDUCED_TYPENAME BIMAP::relation>, \
75     ::boost::bimaps::relation::support::                                      \
76         get_pair_functor<TAG, BOOST_DEDUCED_TYPENAME BIMAP::relation >        \
77 >
78 /*===========================================================================*/
79
80
81 #if defined(BOOST_MSVC)
82 /*===========================================================================*/
83 #define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP)                      \
84     typedef ::boost::bimaps::detail::map_view_base<                           \
85         TYPE<TAG,BIMAP>,TAG,BIMAP > friend_map_view_base;                     \
86     friend class friend_map_view_base;
87 /*===========================================================================*/
88 #else
89 /*===========================================================================*/
90 #define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP)                      \
91     friend class ::boost::bimaps::detail::map_view_base<                      \
92         TYPE<TAG,BIMAP>,TAG,BIMAP >;
93 /*===========================================================================*/
94 #endif
95
96
97 /// \brief Common base for map views.
98
99 template< class Derived, class Tag, class BimapType>
100 class map_view_base
101 {
102     typedef ::boost::bimaps::container_adaptor::support::
103         iterator_facade_to_base<
104
105             BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
106                 iterator_type_by<Tag,BimapType>::type,
107
108             BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
109                 const_iterator_type_by<Tag,BimapType>::type
110
111         > iterator_to_base_;
112
113     typedef ::boost::bimaps::relation::detail::
114         pair_to_relation_functor<Tag,
115             BOOST_DEDUCED_TYPENAME BimapType::relation>      value_to_base_;
116
117     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
118                            key_type_by<Tag,BimapType>::type       key_type_;
119
120     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
121                           data_type_by<Tag,BimapType>::type      data_type_;
122
123     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
124            pair_type_by<Tag,
125               BOOST_DEDUCED_TYPENAME BimapType::relation>::type value_type_;
126
127     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
128                     iterator_type_by<Tag,BimapType>::type         iterator_;
129
130     public:
131
132     bool replace(iterator_ position, const value_type_ & x)
133     {
134         return derived().base().replace(
135             derived().template functor<iterator_to_base_>()(position),
136             derived().template functor<value_to_base_>()(x)
137         );
138     }
139
140     template< class CompatibleKey >
141     bool replace_key(iterator_ position, const CompatibleKey & k)
142     {
143         return derived().base().replace(
144             derived().template functor<iterator_to_base_>()(position),
145             derived().template functor<value_to_base_>()(
146                 value_type_(k,position->second)
147             )
148         );
149     }
150
151     template< class CompatibleData >
152     bool replace_data(iterator_ position, const CompatibleData & d)
153     {
154         return derived().base().replace(
155             derived().template functor<iterator_to_base_>()(position),
156             derived().template functor<value_to_base_>()(
157                 value_type_(position->first,d)
158             )
159         );
160     }
161
162     /* This function may be provided in the future
163
164     template< class Modifier >
165     bool modify(iterator_ position, Modifier mod)
166     {
167         return derived().base().modify(
168
169             derived().template functor<iterator_to_base_>()(position),
170
171             ::boost::bimaps::detail::relation_modifier_adaptor
172             <
173                 Modifier,
174                 BOOST_DEDUCED_TYPENAME BimapType::relation,
175                 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
176                 data_extractor
177                 <
178                     Tag, BOOST_DEDUCED_TYPENAME BimapType::relation
179
180                 >::type,
181                 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
182                 data_extractor
183                 <
184                     BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
185                         opossite_tag<Tag,BimapType>::type,
186                     BOOST_DEDUCED_TYPENAME BimapType::relation
187
188                 >::type
189
190             >(mod)
191         );
192     }
193     */
194
195     template< class Modifier >
196     bool modify_key(iterator_ position, Modifier mod)
197     {
198         return derived().base().modify_key(
199             derived().template functor<iterator_to_base_>()(position), mod
200         );
201     }
202
203     template< class Modifier >
204     bool modify_data(iterator_ position, Modifier mod)
205     {
206         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
207         data_extractor
208         <
209             BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
210                         opossite_tag<Tag,BimapType>::type,
211             BOOST_DEDUCED_TYPENAME BimapType::relation
212
213         >::type data_extractor_;
214
215         return derived().base().modify(
216
217             derived().template functor<iterator_to_base_>()(position),
218
219             // this may be replaced later by
220             // ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) )
221
222             ::boost::bimaps::detail::unary_modifier_adaptor
223             <
224                 Modifier,
225                 BOOST_DEDUCED_TYPENAME BimapType::relation,
226                 data_extractor_
227
228             >(mod)
229         );
230     }
231
232     protected:
233
234     typedef map_view_base map_view_base_;
235
236     private:
237
238     // Curiously Recurring Template interface.
239
240     Derived& derived()
241     {
242         return *static_cast<Derived*>(this);
243     }
244
245     Derived const& derived() const
246     {
247         return *static_cast<Derived const*>(this);
248     }
249 };
250
251
252
253
254 template< class Derived, class Tag, class BimapType>
255 class mutable_data_unique_map_view_access
256 {
257     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
258                           data_type_by<Tag,BimapType>::type      data_type_;
259
260     public:
261
262     template< class CompatibleKey >
263     data_type_ & at(const CompatibleKey& k)
264     {
265         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
266                             iterator_type_by<Tag,BimapType>::type iterator;
267
268         iterator iter = derived().find(k);
269         if( iter == derived().end() )
270         {
271             ::boost::throw_exception(
272                 std::out_of_range("bimap<>: invalid key")
273             );
274         }
275         return iter->second;
276     }
277
278     template< class CompatibleKey >
279     const data_type_ & at(const CompatibleKey& k) const
280     {
281         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
282                 const_iterator_type_by<Tag,BimapType>::type const_iterator;
283
284         const_iterator iter = derived().find(k);
285         if( iter == derived().end() )
286         {
287             ::boost::throw_exception(
288                 std::out_of_range("bimap<>: invalid key")
289             );
290         }
291         return iter->second;
292     }
293
294     template< class CompatibleKey >
295     data_type_ & operator[](const CompatibleKey& k)
296     {
297         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
298                       iterator_type_by<Tag,BimapType>::type       iterator;
299
300         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
301                          value_type_by<Tag,BimapType>::type     value_type;
302
303         iterator iter = derived().find(k);
304         if( iter == derived().end() )
305         {
306             iter = derived().insert( value_type(k,data_type_()) ).first;
307         }
308         return iter->second;
309     }
310
311     protected:
312
313     typedef mutable_data_unique_map_view_access
314                 mutable_data_unique_map_view_access_;
315
316     private:
317
318     // Curiously Recurring Template interface.
319
320     Derived& derived()
321     {
322         return *static_cast<Derived*>(this);
323     }
324
325     Derived const& derived() const
326     {
327         return *static_cast<Derived const*>(this);
328     }
329 };
330
331
332 template< class Derived, class Tag, class BimapType>
333 class non_mutable_data_unique_map_view_access
334 {
335     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
336                           data_type_by<Tag,BimapType>::type      data_type_;
337
338     public:
339
340     template< class CompatibleKey >
341     const data_type_ & at(const CompatibleKey& k) const
342     {
343         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
344                 const_iterator_type_by<Tag,BimapType>::type const_iterator;
345
346         const_iterator iter = derived().find(k);
347         if( iter == derived().end() )
348         {
349             ::boost::throw_exception(
350                 std::out_of_range("bimap<>: invalid key")
351             );
352         }
353         return iter->second;
354     }
355
356     template< class CompatibleKey >
357     data_type_ & operator[](const CompatibleKey& k)
358     {
359         BOOST_BIMAP_STATIC_ERROR( OPERATOR_BRACKET_IS_NOT_SUPPORTED, (Derived));
360     }
361
362     protected:
363
364     typedef non_mutable_data_unique_map_view_access
365                 non_mutable_data_unique_map_view_access_;
366
367     private:
368
369     // Curiously Recurring Template interface.
370
371     Derived& derived()
372     {
373         return *static_cast<Derived*>(this);
374     }
375
376     Derived const& derived() const
377     {
378         return *static_cast<Derived const*>(this);
379     }
380 };
381
382
383 template< class Derived, class Tag, class BimapType>
384 struct unique_map_view_access
385 {
386     private:
387     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
388         value_type_by<Tag,BimapType>::type value_type;
389
390     public:
391     typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_
392     <
393         typename ::boost::is_const<
394             BOOST_DEDUCED_TYPENAME value_type::second_type >::type,
395
396         non_mutable_data_unique_map_view_access<Derived,Tag,BimapType>,
397         mutable_data_unique_map_view_access<Derived,Tag,BimapType>
398
399     >::type type;
400 };
401
402 // Map views specialize the following structs to provide to the bimap class
403 // the extra side typedefs (i.e. left_local_iterator for unordered_maps, 
404 // right_range_type for maps)
405
406 template< class MapView >
407 struct  left_map_view_extra_typedefs {};
408
409 template< class MapView >
410 struct right_map_view_extra_typedefs {};
411
412 } // namespace detail
413
414 // This function is already part of Boost.Lambda.
415 // They may be moved to Boost.Utility.
416
417 template <class T> inline const T&  make_const(const T& t) { return t; }
418
419 } // namespace bimaps
420 } // namespace boost
421
422
423 // The following macros avoids code duplication in map views
424 // Maybe this can be changed in the future using a scheme similar to
425 // the one used with map_view_base.
426
427 /*===========================================================================*/
428 #define BOOST_BIMAP_MAP_VIEW_RANGE_IMPLEMENTATION(BASE)                       \
429                                                                               \
430 typedef std::pair<                                                            \
431     BOOST_DEDUCED_TYPENAME base_::iterator,                                   \
432     BOOST_DEDUCED_TYPENAME base_::iterator> range_type;                       \
433                                                                               \
434 typedef std::pair<                                                            \
435     BOOST_DEDUCED_TYPENAME base_::const_iterator,                             \
436     BOOST_DEDUCED_TYPENAME base_::const_iterator> const_range_type;           \
437                                                                               \
438                                                                               \
439 template< class LowerBounder, class UpperBounder>                             \
440 range_type range(LowerBounder lower,UpperBounder upper)                       \
441 {                                                                             \
442     std::pair<                                                                \
443                                                                               \
444         BOOST_DEDUCED_TYPENAME BASE::base_type::iterator,                     \
445         BOOST_DEDUCED_TYPENAME BASE::base_type::iterator                      \
446                                                                               \
447     > r( this->base().range(lower,upper) );                                   \
448                                                                               \
449     return range_type(                                                        \
450         this->template functor<                                               \
451             BOOST_DEDUCED_TYPENAME BASE::iterator_from_base                   \
452         >()                                         ( r.first ),              \
453         this->template functor<                                               \
454             BOOST_DEDUCED_TYPENAME BASE::iterator_from_base                   \
455         >()                                         ( r.second )              \
456     );                                                                        \
457 }                                                                             \
458                                                                               \
459 template< class LowerBounder, class UpperBounder>                             \
460 const_range_type range(LowerBounder lower,UpperBounder upper) const           \
461 {                                                                             \
462     std::pair<                                                                \
463                                                                               \
464         BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator,               \
465         BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator                \
466                                                                               \
467     > r( this->base().range(lower,upper) );                                   \
468                                                                               \
469     return const_range_type(                                                  \
470         this->template functor<                                               \
471             BOOST_DEDUCED_TYPENAME BASE::iterator_from_base                   \
472         >()                                         ( r.first ),              \
473         this->template functor<                                               \
474             BOOST_DEDUCED_TYPENAME BASE::iterator_from_base                   \
475         >()                                         ( r.second )              \
476     );                                                                        \
477 }
478 /*===========================================================================*/
479
480
481 /*===========================================================================*/
482 #define BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(BASE)                          \
483                                                                               \
484 template< class InputIterator >                                               \
485 void assign(InputIterator first,InputIterator last)                           \
486 {                                                                             \
487     this->clear();                                                            \
488     this->insert(this->end(),first,last);                                     \
489 }                                                                             \
490                                                                               \
491 void assign(BOOST_DEDUCED_TYPENAME BASE::size_type n,                         \
492             const BOOST_DEDUCED_TYPENAME BASE::value_type& v)                 \
493 {                                                                             \
494     this->clear();                                                            \
495     for(BOOST_DEDUCED_TYPENAME BASE::size_type i = 0 ; i < n ; ++n)           \
496     {                                                                         \
497         this->push_back(v);                                                   \
498     }                                                                         \
499 }
500 /*===========================================================================*/
501
502
503 /*===========================================================================*/
504 #define BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(BASE)                      \
505                                                                               \
506 BOOST_DEDUCED_TYPENAME BASE::reference front()                                \
507 {                                                                             \
508     return this->template functor<                                            \
509         BOOST_DEDUCED_TYPENAME base_::value_from_base>()                      \
510     (                                                                         \
511         const_cast                                                            \
512         <                                                                     \
513             BOOST_DEDUCED_TYPENAME BASE::base_type::value_type &              \
514                                                                               \
515         > ( this->base().front() )                                            \
516     );                                                                        \
517 }                                                                             \
518                                                                               \
519 BOOST_DEDUCED_TYPENAME BASE::reference back()                                 \
520 {                                                                             \
521     return this->template functor<                                            \
522         BOOST_DEDUCED_TYPENAME base_::value_from_base>()                      \
523     (                                                                         \
524         const_cast                                                            \
525         <                                                                     \
526             BOOST_DEDUCED_TYPENAME BASE::base_type::value_type &              \
527                                                                               \
528         >( this->base().back() )                                              \
529     );                                                                        \
530 }                                                                             \
531                                                                               \
532 BOOST_DEDUCED_TYPENAME BASE::const_reference front() const                    \
533 {                                                                             \
534     return this->template functor<                                            \
535         BOOST_DEDUCED_TYPENAME BASE::value_from_base>()                       \
536     (                                                                         \
537         this->base().front()                                                  \
538     );                                                                        \
539 }                                                                             \
540                                                                               \
541 BOOST_DEDUCED_TYPENAME BASE::const_reference back() const                     \
542 {                                                                             \
543     return this->template functor<                                            \
544         BOOST_DEDUCED_TYPENAME BASE::value_from_base>()                       \
545     (                                                                         \
546         this->base().back()                                                   \
547     );                                                                        \
548 }
549 /*===========================================================================*/
550
551
552 #endif // BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP