Boost C++ Libraries Boost.Bimap Home Libraries People FAQ More

PrevUpHomeNext

map_view_base.hpp

Go to the documentation of this file.
00001 // Boost.Bimap
00002 //
00003 // Copyright (c) 2006-2007 Matias Capeletto
00004 //
00005 // Distributed under the Boost Software License, Version 1.0.
00006 // (See accompanying file LICENSE_1_0.txt or copy at
00007 // http://www.boost.org/LICENSE_1_0.txt)
00008 
00009 /// \file detail/map_view_base.hpp
00010 /// \brief Helper base for the construction of the bimap views types.
00011 
00012 #ifndef BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
00013 #define BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
00014 
00015 #if defined(_MSC_VER) && (_MSC_VER>=1200)
00016 #pragma once
00017 #endif
00018 
00019 #include <boost/config.hpp>
00020 
00021 #include <stdexcept>
00022 
00023 #include <boost/type_traits/is_const.hpp>
00024 #include <boost/mpl/if.hpp>
00025 
00026 #include <boost/bimap/relation/support/get_pair_functor.hpp>
00027 #include <boost/bimap/relation/detail/to_mutable_relation_functor.hpp>
00028 #include <boost/bimap/container_adaptor/support/iterator_facade_converters.hpp>
00029 #include <boost/bimap/relation/support/data_extractor.hpp>
00030 #include <boost/bimap/relation/support/opposite_tag.hpp>
00031 #include <boost/bimap/relation/support/pair_type_by.hpp>
00032 #include <boost/bimap/support/iterator_type_by.hpp>
00033 #include <boost/bimap/support/key_type_by.hpp>
00034 #include <boost/bimap/support/data_type_by.hpp>
00035 #include <boost/bimap/support/value_type_by.hpp>
00036 #include <boost/bimap/detail/modifier_adaptor.hpp>
00037 #include <boost/bimap/detail/debug/static_error.hpp>
00038 
00039 namespace boost {
00040 namespace bimaps {
00041 
00042 namespace detail {
00043 
00044 
00045 // The next macro can be converted in a metafunctor to gain code robustness.
00046 /*===========================================================================*/
00047 #define BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR(                               \
00048     CONTAINER_ADAPTOR, TAG,BIMAP, OTHER_ITER, CONST_OTHER_ITER                \
00049 )                                                                             \
00050 ::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR                         \
00051 <                                                                             \
00052     BOOST_DEDUCED_TYPENAME BIMAP::core_type::                                 \
00053         BOOST_NESTED_TEMPLATE index<TAG>::type,                               \
00054     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                         \
00055         iterator_type_by<TAG,BIMAP>::type,                                    \
00056     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                         \
00057         const_iterator_type_by<TAG,BIMAP>::type,                              \
00058     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                         \
00059         OTHER_ITER<TAG,BIMAP>::type,                                          \
00060     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                         \
00061         CONST_OTHER_ITER<TAG,BIMAP>::type,                                    \
00062     ::boost::bimaps::container_adaptor::support::iterator_facade_to_base      \
00063     <                                                                         \
00064         BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                     \
00065                   iterator_type_by<TAG,BIMAP>::type,                          \
00066         BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::                     \
00067             const_iterator_type_by<TAG,BIMAP>::type                           \
00068                                                                               \
00069     >,                                                                        \
00070     ::boost::mpl::na,                                                         \
00071     ::boost::mpl::na,                                                         \
00072     ::boost::bimaps::relation::detail::                                       \
00073         pair_to_relation_functor<TAG,BOOST_DEDUCED_TYPENAME BIMAP::relation>, \
00074     ::boost::bimaps::relation::support::                                      \
00075         get_pair_functor<TAG, BOOST_DEDUCED_TYPENAME BIMAP::relation >        \
00076 >
00077 /*===========================================================================*/
00078 
00079 
00080 #if defined(BOOST_MSVC)
00081 /*===========================================================================*/
00082 #define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP)                      \
00083     typedef ::boost::bimaps::detail::map_view_base<                           \
00084         TYPE<TAG,BIMAP>,TAG,BIMAP > friend_map_view_base;                     \
00085     friend class friend_map_view_base;
00086 /*===========================================================================*/
00087 #else
00088 /*===========================================================================*/
00089 #define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP)                      \
00090     friend class ::boost::bimaps::detail::map_view_base<                      \
00091         TYPE<TAG,BIMAP>,TAG,BIMAP >;
00092 /*===========================================================================*/
00093 #endif
00094 
00095 
00096 /// \brief Common base for map views.
00097 
00098 template< class Derived, class Tag, class BimapType>
00099 class map_view_base
00100 {
00101     typedef ::boost::bimaps::container_adaptor::support::
00102         iterator_facade_to_base<
00103 
00104             BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00105                 iterator_type_by<Tag,BimapType>::type,
00106 
00107             BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00108                 const_iterator_type_by<Tag,BimapType>::type
00109 
00110         > iterator_to_base_;
00111 
00112     typedef ::boost::bimaps::relation::detail::
00113         pair_to_relation_functor<Tag,
00114             BOOST_DEDUCED_TYPENAME BimapType::relation>      value_to_base_;
00115 
00116     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00117                            key_type_by<Tag,BimapType>::type       key_type_;
00118 
00119     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00120                           data_type_by<Tag,BimapType>::type      data_type_;
00121 
00122     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
00123            pair_type_by<Tag,
00124               BOOST_DEDUCED_TYPENAME BimapType::relation>::type value_type_;
00125 
00126     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00127                     iterator_type_by<Tag,BimapType>::type         iterator_;
00128 
00129     public:
00130 
00131     bool replace(iterator_ position, const value_type_ & x)
00132     {
00133         return derived().base().replace(
00134             derived().template functor<iterator_to_base_>()(position),
00135             derived().template functor<value_to_base_>()(x)
00136         );
00137     }
00138 
00139     template< class CompatibleKey >
00140     bool replace_key(iterator_ position, const CompatibleKey & k)
00141     {
00142         return derived().base().replace(
00143             derived().template functor<iterator_to_base_>()(position),
00144             derived().template functor<value_to_base_>()(
00145                 value_type_(k,position->second)
00146             )
00147         );
00148     }
00149 
00150     template< class CompatibleData >
00151     bool replace_data(iterator_ position, const CompatibleData & d)
00152     {
00153         return derived().base().replace(
00154             derived().template functor<iterator_to_base_>()(position),
00155             derived().template functor<value_to_base_>()(
00156                 value_type_(position->first,d)
00157             )
00158         );
00159     }
00160 
00161     /* This function may be provided in the future
00162 
00163     template< class Modifier >
00164     bool modify(iterator_ position, Modifier mod)
00165     {
00166         return derived().base().modify(
00167 
00168             derived().template functor<iterator_to_base_>()(position),
00169 
00170             ::boost::bimaps::detail::relation_modifier_adaptor
00171             <
00172                 Modifier,
00173                 BOOST_DEDUCED_TYPENAME BimapType::relation,
00174                 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
00175                 data_extractor
00176                 <
00177                     Tag, BOOST_DEDUCED_TYPENAME BimapType::relation
00178 
00179                 >::type,
00180                 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
00181                 data_extractor
00182                 <
00183                     BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
00184                         opossite_tag<Tag,BimapType>::type,
00185                     BOOST_DEDUCED_TYPENAME BimapType::relation
00186 
00187                 >::type
00188 
00189             >(mod)
00190         );
00191     }
00192     */
00193 
00194     template< class Modifier >
00195     bool modify_key(iterator_ position, Modifier mod)
00196     {
00197         return derived().base().modify_key(
00198             derived().template functor<iterator_to_base_>()(position), mod
00199         );
00200     }
00201 
00202     template< class Modifier >
00203     bool modify_data(iterator_ position, Modifier mod)
00204     {
00205         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
00206         data_extractor
00207         <
00208             BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
00209                         opossite_tag<Tag,BimapType>::type,
00210             BOOST_DEDUCED_TYPENAME BimapType::relation
00211 
00212         >::type data_extractor_;
00213 
00214         return derived().base().modify(
00215 
00216             derived().template functor<iterator_to_base_>()(position),
00217 
00218             // this may be replaced later by
00219             // ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) )
00220 
00221             ::boost::bimaps::detail::unary_modifier_adaptor
00222             <
00223                 Modifier,
00224                 BOOST_DEDUCED_TYPENAME BimapType::relation,
00225                 data_extractor_
00226 
00227             >(mod)
00228         );
00229     }
00230 
00231     protected:
00232 
00233     typedef map_view_base map_view_base_;
00234 
00235     private:
00236 
00237     // Curiously Recurring Template interface.
00238 
00239     Derived& derived()
00240     {
00241         return *static_cast<Derived*>(this);
00242     }
00243 
00244     Derived const& derived() const
00245     {
00246         return *static_cast<Derived const*>(this);
00247     }
00248 };
00249 
00250 
00251 
00252 
00253 template< class Derived, class Tag, class BimapType>
00254 class mutable_data_unique_map_view_access
00255 {
00256     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00257                           data_type_by<Tag,BimapType>::type      data_type_;
00258 
00259     public:
00260 
00261     template< class CompatibleKey >
00262     data_type_ & at(const CompatibleKey& k)
00263     {
00264         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00265                             iterator_type_by<Tag,BimapType>::type iterator;
00266 
00267         iterator iter = derived().find(k);
00268         if( iter == derived().end() )
00269         {
00270             ::boost::throw_exception(
00271                 std::out_of_range("bimap<>: invalid key")
00272             );
00273         }
00274         return iter->second;
00275     }
00276 
00277     template< class CompatibleKey >
00278     const data_type_ & at(const CompatibleKey& k) const
00279     {
00280         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00281                 const_iterator_type_by<Tag,BimapType>::type const_iterator;
00282 
00283         const_iterator iter = derived().find(k);
00284         if( iter == derived().end() )
00285         {
00286             ::boost::throw_exception(
00287                 std::out_of_range("bimap<>: invalid key")
00288             );
00289         }
00290         return iter->second;
00291     }
00292 
00293     template< class CompatibleKey >
00294     data_type_ & operator[](const CompatibleKey& k)
00295     {
00296         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00297                       iterator_type_by<Tag,BimapType>::type       iterator;
00298 
00299         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00300                          value_type_by<Tag,BimapType>::type     value_type;
00301 
00302         iterator iter = derived().find(k);
00303         if( iter == derived().end() )
00304         {
00305             iter = derived().insert( value_type(k,data_type_()) ).first;
00306         }
00307         return iter->second;
00308     }
00309 
00310     protected:
00311 
00312     typedef mutable_data_unique_map_view_access
00313                 mutable_data_unique_map_view_access_;
00314 
00315     private:
00316 
00317     // Curiously Recurring Template interface.
00318 
00319     Derived& derived()
00320     {
00321         return *static_cast<Derived*>(this);
00322     }
00323 
00324     Derived const& derived() const
00325     {
00326         return *static_cast<Derived const*>(this);
00327     }
00328 };
00329 
00330 
00331 template< class Derived, class Tag, class BimapType>
00332 class non_mutable_data_unique_map_view_access
00333 {
00334     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00335                           data_type_by<Tag,BimapType>::type      data_type_;
00336 
00337     public:
00338 
00339     template< class CompatibleKey >
00340     const data_type_ & at(const CompatibleKey& k) const
00341     {
00342         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00343                 const_iterator_type_by<Tag,BimapType>::type const_iterator;
00344 
00345         const_iterator iter = derived().find(k);
00346         if( iter == derived().end() )
00347         {
00348             ::boost::throw_exception(
00349                 std::out_of_range("bimap<>: invalid key")
00350             );
00351         }
00352         return iter->second;
00353     }
00354 
00355     template< class CompatibleKey >
00356     data_type_ & operator[](const CompatibleKey& k)
00357     {
00358         BOOST_BIMAP_STATIC_ERROR( OPERATOR_BRACKET_IS_NOT_SUPPORTED, (Derived));
00359     }
00360 
00361     protected:
00362 
00363     typedef non_mutable_data_unique_map_view_access
00364                 non_mutable_data_unique_map_view_access_;
00365 
00366     private:
00367 
00368     // Curiously Recurring Template interface.
00369 
00370     Derived& derived()
00371     {
00372         return *static_cast<Derived*>(this);
00373     }
00374 
00375     Derived const& derived() const
00376     {
00377         return *static_cast<Derived const*>(this);
00378     }
00379 };
00380 
00381 
00382 template< class Derived, class Tag, class BimapType>
00383 struct unique_map_view_access
00384 {
00385     private:
00386     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00387         value_type_by<Tag,BimapType>::type value_type;
00388 
00389     public:
00390     typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_
00391     <
00392         typename ::boost::is_const<
00393             BOOST_DEDUCED_TYPENAME value_type::second_type >::type,
00394 
00395         non_mutable_data_unique_map_view_access<Derived,Tag,BimapType>,
00396         mutable_data_unique_map_view_access<Derived,Tag,BimapType>
00397 
00398     >::type type;
00399 };
00400 
00401 
00402 } // namespace detail
00403 
00404 // This function is already part of Boost.Lambda.
00405 // They may be moved to Boost.Utility.
00406 
00407 template <class T> inline const T&  make_const(const T& t) { return t; }
00408 
00409 } // namespace bimaps
00410 } // namespace boost
00411 
00412 
00413 // The following macros avoids code duplication in map views
00414 // Maybe this can be changed in the future using a scheme similar to
00415 // the one used with map_view_base.
00416 
00417 /*===========================================================================*/
00418 #define BOOST_BIMAP_MAP_VIEW_RANGE_IMPLEMENTATION(BASE)                       \
00419                                                                               \
00420 template< class LowerBounder, class UpperBounder>                             \
00421 std::pair<BOOST_DEDUCED_TYPENAME BASE::iterator,                              \
00422           BOOST_DEDUCED_TYPENAME BASE::iterator>                              \
00423     range(LowerBounder lower,UpperBounder upper)                              \
00424 {                                                                             \
00425     std::pair<                                                                \
00426                                                                               \
00427         BOOST_DEDUCED_TYPENAME BASE::base_type::iterator,                     \
00428         BOOST_DEDUCED_TYPENAME BASE::base_type::iterator                      \
00429                                                                               \
00430     > r( this->base().range(lower,upper) );                                   \
00431                                                                               \
00432     return std::pair                                                          \
00433     <                                                                         \
00434         BOOST_DEDUCED_TYPENAME BASE::iterator,                                \
00435         BOOST_DEDUCED_TYPENAME BASE::iterator                                 \
00436     >(                                                                        \
00437         this->template functor<                                               \
00438             BOOST_DEDUCED_TYPENAME BASE::iterator_from_base                   \
00439         >()                                         ( r.first ),              \
00440         this->template functor<                                               \
00441             BOOST_DEDUCED_TYPENAME BASE::iterator_from_base                   \
00442         >()                                         ( r.second )              \
00443     );                                                                        \
00444 }                                                                             \
00445                                                                               \
00446 template< class LowerBounder, class UpperBounder>                             \
00447 std::pair<BOOST_DEDUCED_TYPENAME BASE::const_iterator,                        \
00448           BOOST_DEDUCED_TYPENAME BASE::const_iterator>                        \
00449     range(LowerBounder lower,UpperBounder upper) const                        \
00450 {                                                                             \
00451     std::pair<                                                                \
00452                                                                               \
00453         BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator,               \
00454         BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator                \
00455                                                                               \
00456     > r( this->base().range(lower,upper) );                                   \
00457                                                                               \
00458     return std::pair                                                          \
00459     <                                                                         \
00460         BOOST_DEDUCED_TYPENAME BASE::const_iterator,                          \
00461         BOOST_DEDUCED_TYPENAME BASE::const_iterator                           \
00462     >(                                                                        \
00463         this->template functor<                                               \
00464             BOOST_DEDUCED_TYPENAME BASE::iterator_from_base                   \
00465         >()                                         ( r.first ),              \
00466         this->template functor<                                               \
00467             BOOST_DEDUCED_TYPENAME BASE::iterator_from_base                   \
00468         >()                                         ( r.second )              \
00469     );                                                                        \
00470 }
00471 /*===========================================================================*/
00472 
00473 
00474 /*===========================================================================*/
00475 #define BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(BASE)                          \
00476                                                                               \
00477 template< class InputIterator >                                               \
00478 void assign(InputIterator first,InputIterator last)                           \
00479 {                                                                             \
00480     this->clear();                                                            \
00481     this->insert(this->end(),first,last);                                     \
00482 }                                                                             \
00483                                                                               \
00484 void assign(BOOST_DEDUCED_TYPENAME BASE::size_type n,                         \
00485             const BOOST_DEDUCED_TYPENAME BASE::value_type& v)                 \
00486 {                                                                             \
00487     this->clear();                                                            \
00488     for(BOOST_DEDUCED_TYPENAME BASE::size_type i = 0 ; i < n ; ++n)           \
00489     {                                                                         \
00490         this->push_back(v);                                                   \
00491     }                                                                         \
00492 }
00493 /*===========================================================================*/
00494 
00495 
00496 /*===========================================================================*/
00497 #define BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(BASE)                      \
00498                                                                               \
00499 BOOST_DEDUCED_TYPENAME BASE::reference front()                                \
00500 {                                                                             \
00501     return this->template functor<                                            \
00502         BOOST_DEDUCED_TYPENAME base_::value_from_base>()                      \
00503     (                                                                         \
00504         const_cast                                                            \
00505         <                                                                     \
00506             BOOST_DEDUCED_TYPENAME BASE::base_type::value_type &              \
00507                                                                               \
00508         > ( this->base().front() )                                            \
00509     );                                                                        \
00510 }                                                                             \
00511                                                                               \
00512 BOOST_DEDUCED_TYPENAME BASE::reference back()                                 \
00513 {                                                                             \
00514     return this->template functor<                                            \
00515         BOOST_DEDUCED_TYPENAME base_::value_from_base>()                      \
00516     (                                                                         \
00517         const_cast                                                            \
00518         <                                                                     \
00519             BOOST_DEDUCED_TYPENAME BASE::base_type::value_type &              \
00520                                                                               \
00521         >( this->base().back() )                                              \
00522     );                                                                        \
00523 }                                                                             \
00524                                                                               \
00525 BOOST_DEDUCED_TYPENAME BASE::const_reference front() const                    \
00526 {                                                                             \
00527     return this->template functor<                                            \
00528         BOOST_DEDUCED_TYPENAME BASE::value_from_base>()                       \
00529     (                                                                         \
00530         this->base().front()                                                  \
00531     );                                                                        \
00532 }                                                                             \
00533                                                                               \
00534 BOOST_DEDUCED_TYPENAME BASE::const_reference back() const                     \
00535 {                                                                             \
00536     return this->template functor<                                            \
00537         BOOST_DEDUCED_TYPENAME BASE::value_from_base>()                       \
00538     (                                                                         \
00539         this->base().back()                                                   \
00540     );                                                                        \
00541 }
00542 /*===========================================================================*/
00543 
00544 
00545 #endif // BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
Copyright 2006 Matias Capeletto

PrevUpHomeNext