3 // Copyright (c) 2006-2007 Matias Capeletto
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)
9 /// \file detail/map_view_base.hpp
10 /// \brief Helper base for the construction of the bimap views types.
12 #ifndef BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
13 #define BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
15 #if defined(_MSC_VER) && (_MSC_VER>=1200)
19 #include <boost/config.hpp>
24 #include <boost/type_traits/is_const.hpp>
25 #include <boost/mpl/if.hpp>
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>
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 \
51 ::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR \
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 \
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 \
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 > \
78 /*===========================================================================*/
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 /*===========================================================================*/
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 /*===========================================================================*/
97 /// \brief Common base for map views.
99 template< class Derived, class Tag, class BimapType>
102 typedef ::boost::bimaps::container_adaptor::support::
103 iterator_facade_to_base<
105 BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
106 iterator_type_by<Tag,BimapType>::type,
108 BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
109 const_iterator_type_by<Tag,BimapType>::type
113 typedef ::boost::bimaps::relation::detail::
114 pair_to_relation_functor<Tag,
115 BOOST_DEDUCED_TYPENAME BimapType::relation> value_to_base_;
117 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
118 key_type_by<Tag,BimapType>::type key_type_;
120 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
121 data_type_by<Tag,BimapType>::type data_type_;
123 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
125 BOOST_DEDUCED_TYPENAME BimapType::relation>::type value_type_;
127 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
128 iterator_type_by<Tag,BimapType>::type iterator_;
132 bool replace(iterator_ position, const value_type_ & x)
134 return derived().base().replace(
135 derived().template functor<iterator_to_base_>()(position),
136 derived().template functor<value_to_base_>()(x)
140 template< class CompatibleKey >
141 bool replace_key(iterator_ position, const CompatibleKey & k)
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)
151 template< class CompatibleData >
152 bool replace_data(iterator_ position, const CompatibleData & d)
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)
162 /* This function may be provided in the future
164 template< class Modifier >
165 bool modify(iterator_ position, Modifier mod)
167 return derived().base().modify(
169 derived().template functor<iterator_to_base_>()(position),
171 ::boost::bimaps::detail::relation_modifier_adaptor
174 BOOST_DEDUCED_TYPENAME BimapType::relation,
175 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
178 Tag, BOOST_DEDUCED_TYPENAME BimapType::relation
181 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
184 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
185 opossite_tag<Tag,BimapType>::type,
186 BOOST_DEDUCED_TYPENAME BimapType::relation
195 template< class Modifier >
196 bool modify_key(iterator_ position, Modifier mod)
198 return derived().base().modify_key(
199 derived().template functor<iterator_to_base_>()(position), mod
203 template< class Modifier >
204 bool modify_data(iterator_ position, Modifier mod)
206 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
209 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
210 opossite_tag<Tag,BimapType>::type,
211 BOOST_DEDUCED_TYPENAME BimapType::relation
213 >::type data_extractor_;
215 return derived().base().modify(
217 derived().template functor<iterator_to_base_>()(position),
219 // this may be replaced later by
220 // ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) )
222 ::boost::bimaps::detail::unary_modifier_adaptor
225 BOOST_DEDUCED_TYPENAME BimapType::relation,
234 typedef map_view_base map_view_base_;
238 // Curiously Recurring Template interface.
242 return *static_cast<Derived*>(this);
245 Derived const& derived() const
247 return *static_cast<Derived const*>(this);
254 template< class Derived, class Tag, class BimapType>
255 class mutable_data_unique_map_view_access
257 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
258 data_type_by<Tag,BimapType>::type data_type_;
262 template< class CompatibleKey >
263 data_type_ & at(const CompatibleKey& k)
265 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
266 iterator_type_by<Tag,BimapType>::type iterator;
268 iterator iter = derived().find(k);
269 if( iter == derived().end() )
271 ::boost::throw_exception(
272 std::out_of_range("bimap<>: invalid key")
278 template< class CompatibleKey >
279 const data_type_ & at(const CompatibleKey& k) const
281 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
282 const_iterator_type_by<Tag,BimapType>::type const_iterator;
284 const_iterator iter = derived().find(k);
285 if( iter == derived().end() )
287 ::boost::throw_exception(
288 std::out_of_range("bimap<>: invalid key")
294 template< class CompatibleKey >
295 data_type_ & operator[](const CompatibleKey& k)
297 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
298 iterator_type_by<Tag,BimapType>::type iterator;
300 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
301 value_type_by<Tag,BimapType>::type value_type;
303 iterator iter = derived().find(k);
304 if( iter == derived().end() )
306 iter = derived().insert( value_type(k,data_type_()) ).first;
313 typedef mutable_data_unique_map_view_access
314 mutable_data_unique_map_view_access_;
318 // Curiously Recurring Template interface.
322 return *static_cast<Derived*>(this);
325 Derived const& derived() const
327 return *static_cast<Derived const*>(this);
332 template< class Derived, class Tag, class BimapType>
333 class non_mutable_data_unique_map_view_access
335 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
336 data_type_by<Tag,BimapType>::type data_type_;
340 template< class CompatibleKey >
341 const data_type_ & at(const CompatibleKey& k) const
343 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
344 const_iterator_type_by<Tag,BimapType>::type const_iterator;
346 const_iterator iter = derived().find(k);
347 if( iter == derived().end() )
349 ::boost::throw_exception(
350 std::out_of_range("bimap<>: invalid key")
356 template< class CompatibleKey >
357 data_type_ & operator[](const CompatibleKey& k)
359 BOOST_BIMAP_STATIC_ERROR( OPERATOR_BRACKET_IS_NOT_SUPPORTED, (Derived));
364 typedef non_mutable_data_unique_map_view_access
365 non_mutable_data_unique_map_view_access_;
369 // Curiously Recurring Template interface.
373 return *static_cast<Derived*>(this);
376 Derived const& derived() const
378 return *static_cast<Derived const*>(this);
383 template< class Derived, class Tag, class BimapType>
384 struct unique_map_view_access
387 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
388 value_type_by<Tag,BimapType>::type value_type;
391 typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_
393 typename ::boost::is_const<
394 BOOST_DEDUCED_TYPENAME value_type::second_type >::type,
396 non_mutable_data_unique_map_view_access<Derived,Tag,BimapType>,
397 mutable_data_unique_map_view_access<Derived,Tag,BimapType>
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)
406 template< class MapView >
407 struct left_map_view_extra_typedefs {};
409 template< class MapView >
410 struct right_map_view_extra_typedefs {};
412 } // namespace detail
414 // This function is already part of Boost.Lambda.
415 // They may be moved to Boost.Utility.
417 template <class T> inline const T& make_const(const T& t) { return t; }
419 } // namespace bimaps
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.
427 /*===========================================================================*/
428 #define BOOST_BIMAP_MAP_VIEW_RANGE_IMPLEMENTATION(BASE) \
431 BOOST_DEDUCED_TYPENAME base_::iterator, \
432 BOOST_DEDUCED_TYPENAME base_::iterator> range_type; \
435 BOOST_DEDUCED_TYPENAME base_::const_iterator, \
436 BOOST_DEDUCED_TYPENAME base_::const_iterator> const_range_type; \
439 template< class LowerBounder, class UpperBounder> \
440 range_type range(LowerBounder lower,UpperBounder upper) \
444 BOOST_DEDUCED_TYPENAME BASE::base_type::iterator, \
445 BOOST_DEDUCED_TYPENAME BASE::base_type::iterator \
447 > r( this->base().range(lower,upper) ); \
450 this->template functor< \
451 BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \
453 this->template functor< \
454 BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \
459 template< class LowerBounder, class UpperBounder> \
460 const_range_type range(LowerBounder lower,UpperBounder upper) const \
464 BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator, \
465 BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator \
467 > r( this->base().range(lower,upper) ); \
469 return const_range_type( \
470 this->template functor< \
471 BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \
473 this->template functor< \
474 BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \
478 /*===========================================================================*/
481 /*===========================================================================*/
482 #define BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(BASE) \
484 template< class InputIterator > \
485 void assign(InputIterator first,InputIterator last) \
488 this->insert(this->end(),first,last); \
491 void assign(BOOST_DEDUCED_TYPENAME BASE::size_type n, \
492 const BOOST_DEDUCED_TYPENAME BASE::value_type& v) \
495 for(BOOST_DEDUCED_TYPENAME BASE::size_type i = 0 ; i < n ; ++n) \
497 this->push_back(v); \
500 /*===========================================================================*/
503 /*===========================================================================*/
504 #define BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(BASE) \
506 BOOST_DEDUCED_TYPENAME BASE::reference front() \
508 return this->template functor< \
509 BOOST_DEDUCED_TYPENAME base_::value_from_base>() \
513 BOOST_DEDUCED_TYPENAME BASE::base_type::value_type & \
515 > ( this->base().front() ) \
519 BOOST_DEDUCED_TYPENAME BASE::reference back() \
521 return this->template functor< \
522 BOOST_DEDUCED_TYPENAME base_::value_from_base>() \
526 BOOST_DEDUCED_TYPENAME BASE::base_type::value_type & \
528 >( this->base().back() ) \
532 BOOST_DEDUCED_TYPENAME BASE::const_reference front() const \
534 return this->template functor< \
535 BOOST_DEDUCED_TYPENAME BASE::value_from_base>() \
537 this->base().front() \
541 BOOST_DEDUCED_TYPENAME BASE::const_reference back() const \
543 return this->template functor< \
544 BOOST_DEDUCED_TYPENAME BASE::value_from_base>() \
546 this->base().back() \
549 /*===========================================================================*/
552 #endif // BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP