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

PrevUpHomeNext

bimap.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 bimap.hpp
00010 /// \brief Includes the basic bimap container
00011 
00012 /** \mainpage notitle
00013 \n
00014 \image html http://matias.capeletto.googlepages.com/boost.bimap.reference.logo.png
00015 
00016 \section Introduction
00017 
00018 This is the complete reference of Boost.Bimap.
00019 
00020 After getting a good understanding of the library from a user perspective
00021 the next step will be:
00022 
00023     - Understand the tagged idiom. (boost::bimaps::tags)
00024     - Understand the internals of the relation class (boost::bimaps::relation)
00025     - Read the container_adaptor toolbox docs (boost::bimaps::container_adaptor)
00026     - Understand the internals of the bimap class. (boost::bimaps, boost::bimaps::views
00027       and boost::bimaps::detail)
00028 
00029 
00030                                                                         **/
00031 
00032 /** \defgroup mutant_group mutant idiom
00033 \brief A safe wrapper around reinterpret_cast
00034                                                                         **/
00035 
00036 /** \defgroup relation_group relation
00037 \brief The relation
00038                                                                         **/
00039 
00040 /** \defgroup tags_group tagged idiom
00041 \brief The tagged idiom
00042                                                                         **/
00043 
00044 
00045 #ifndef BOOST_BIMAP_BIMAP_HPP
00046 #define BOOST_BIMAP_BIMAP_HPP
00047 
00048 #if defined(_MSC_VER) && (_MSC_VER>=1200)
00049 #pragma once
00050 #endif
00051 
00052 #include <boost/config.hpp>
00053 #include <boost/bimap/detail/user_interface_config.hpp>
00054 #include <boost/mpl/aux_/na.hpp>
00055 
00056 #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
00057     #include <boost/serialization/nvp.hpp>
00058 #endif // BOOST_BIMAP_DISABLE_SERIALIZATION
00059 
00060 // Boost.Bimap
00061 #include <boost/bimap/detail/bimap_core.hpp>
00062 #include <boost/bimap/detail/modifier_adaptor.hpp>
00063 #include <boost/bimap/relation/support/data_extractor.hpp>
00064 #include <boost/bimap/relation/support/member_with_tag.hpp>
00065 
00066 #include <boost/bimap/support/map_type_by.hpp>
00067 #include <boost/bimap/support/map_by.hpp>
00068 #include <boost/bimap/support/iterator_type_by.hpp>
00069 
00070 /// \brief The namespace where all the boost libraries lives.
00071 
00072 namespace boost {
00073 
00074 /// \brief Boost.Bimap library namespace
00075 /**
00076 All the entities in the library are defined in this namespace.
00077                                                                     **/
00078 namespace bimaps {
00079 
00080 /// \brief The bimap class is the entry point to the library.
00081 /**
00082 This class manages the instantiation of the desired bimap type.
00083 As there are several types of bidirectional maps that can be
00084 created using it, the main job of it is to find the desired
00085 type. This is done using metaprogramming to obtain the relation
00086 type that will be stored, the map_view type of each side and
00087 the set_view type of the general relationship. The instantiation
00088 is kept simple using an extended standard set theory, where a
00089 bidirectional map type is defined by the set types it relates.
00090 For example, a bidirectional map that has multimap semantics
00091 viewed from both sides is defined by specifying that the two
00092 keys sets are of \c multiset_of<Key> type.
00093 This allows the bimap class to support seamingless N-N, 1-N,
00094 ordered/unordered and even vector-list types of mapping.
00095 The three last parameters are used to specify the set type of
00096 the relation, an inplace hooked data class and the allocator
00097 type. As a help to the bimap user, these parameters support
00098 default types but use a special idiom that allow them to be
00099 specified without interleaving the usual use_default keyword.
00100 The possible bimap instantiation are enumerated here:
00101 \c {Side}KeyType can be directly a type, this is default to
00102 \c set_of<{Side}KeyType>, or can be a \c {SetType}_of<Type>
00103 specification. Additionally this two parameters can be tagged
00104 to specify others tags instead of the usual \c member_at::{Side}
00105 ones.
00106 
00107 \code bimap<LeftKeyType,RightKeyType> \endcode
00108        - \b set_of_relation_type: based on the left key type
00109        - \b hook_data:            no additional data
00110        - \b allocator:            default allocator
00111 
00112 \code bimap<LeftKeyType,RightKeyType> \endcode
00113        - \b set_of_relation_type: based on the left key type
00114        - \b hook_data:            no additional data
00115        - \b allocator:            \c Allocator
00116 
00117 \code bimap<LeftKeyType,RightKeyType,SetOfRelationType> \endcode
00118        - \b set_of_relation_type: \c SetOfRelationType
00119        - \b hook_data:            no additional data
00120        - \b allocator:            default allocator
00121 
00122 \code bimap<LeftKeyType,RightKeyType,SetOfRelationType,Allocator> \endcode
00123        - \b set_of_relation_type: \c SetOfRelationType
00124        - \b hook_data:            no additional data
00125        - \b allocator:            \c Allocator
00126 
00127 \code bimap<LeftKeyType,RightKeyType,DataToHook> \endcode
00128        - \b set_of_relation_type: based on the left key type
00129        - \b hook_data:            \c DataToHook
00130        - \b allocator:            default allocator
00131 
00132 \code bimap<LeftKeyType,RightKeyType,DataToHook,Allocator> \endcode
00133        - \b set_type_of_relation: based on the left key type
00134        - \b hook_data:            \c DataToHook
00135        - \b allocator:            \c Allocator
00136 
00137 \code bimap<LeftKeyType,RightKeyType,SetOfRelationType,DataToHook> \endcode
00138        - \b set_of_relation_type: \c SetOfRelationType
00139        - \b hook_data:            \c DataToHook
00140        - \b allocator:            default allocator
00141 
00142 \code bimap<LeftKeyType,RightKeyType,SetOfRelationType,DataToHook,Allocator> \endcode
00143        - \b set_of_relation_type: \c SetOfRelationType
00144        - \b hook_data:            \c DataToHook
00145        - \b allocator:            \c Allocator
00146 
00147                                                                             **/
00148 
00149 template
00150 <
00151     class KeyTypeA, class KeyTypeB,
00152     class AP1 = ::boost::mpl::na,
00153     class AP2 = ::boost::mpl::na,
00154     class AP3 = ::boost::mpl::na
00155 >
00156 class bimap
00157 :
00158     public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>,
00159     public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>
00160                 ::relation_set
00161 
00162 {
00163     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::
00164         bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3> base_;
00165 
00166     BOOST_DEDUCED_TYPENAME base_::core_type core;
00167 
00168     public:
00169 
00170     // metadata --------------------------------------------------------
00171 
00172     /*
00173     // The rest is computed in the core, because it is quite difficult to
00174     // expose a nice interface with so many metaprogramming stuff.
00175     // Here it is the complete metadat list.
00176 
00177     // Map by {side} metadata
00178 
00179     typedef -unspecified- {side}_tag;
00180     typedef -unspecified- {side}_data_type;
00181     typedef -unspecified- {side}_value_type;
00182     typedef -unspecified- {side}_key_type;
00183     typedef -unspecified- {side}_iterator;
00184     typedef -unspecified- {side}_const_iterator;
00185 
00186     ------------------------------------------------------------------*/
00187 
00188     typedef BOOST_DEDUCED_TYPENAME base_::left_set_type left_set_type;
00189     typedef BOOST_DEDUCED_TYPENAME left_set_type::BOOST_NESTED_TEMPLATE map_view_bind
00190     <
00191         BOOST_DEDUCED_TYPENAME base_::left_tag, base_
00192 
00193     >::type left_map;
00194 
00195     typedef BOOST_DEDUCED_TYPENAME base_::right_set_type right_set_type;
00196     typedef BOOST_DEDUCED_TYPENAME right_set_type::BOOST_NESTED_TEMPLATE map_view_bind
00197     <
00198         BOOST_DEDUCED_TYPENAME base_::right_tag, base_
00199 
00200     >::type right_map;
00201 
00202     /// Left map view
00203     left_map  left;
00204 
00205     /// Right map view
00206     right_map right;
00207 
00208     bimap() :
00209 
00210         base_::relation_set(
00211             ::boost::multi_index::get<
00212                 BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag 
00213             >(core) 
00214         ),
00215         left (
00216             ::boost::multi_index::get<
00217                 BOOST_DEDUCED_TYPENAME base_::logic_left_tag
00218             >(core)
00219         ),
00220         right (
00221             ::boost::multi_index::get<
00222                 BOOST_DEDUCED_TYPENAME base_::logic_right_tag 
00223             >(core)
00224         )
00225 
00226     {}
00227 
00228     template< class InputIterator >
00229     bimap(InputIterator first,InputIterator last) :
00230 
00231         base_::relation_set(
00232             ::boost::multi_index::get<
00233                 BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag
00234             >(core) 
00235         ),
00236 
00237         core(first,last),
00238 
00239         left (
00240             ::boost::multi_index::get<
00241                 BOOST_DEDUCED_TYPENAME base_::logic_left_tag
00242             >(core)
00243         ),
00244         right (
00245             ::boost::multi_index::get<
00246                 BOOST_DEDUCED_TYPENAME base_::logic_right_tag
00247             >(core)
00248         )
00249 
00250     {}
00251 
00252     bimap(const bimap& x) :
00253 
00254         base_::relation_set(
00255             ::boost::multi_index::get<
00256                 BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag
00257             >(core) 
00258         ),
00259 
00260         core(x.core),
00261 
00262         left (
00263             ::boost::multi_index::get<
00264                 BOOST_DEDUCED_TYPENAME base_::logic_left_tag
00265             >(core)
00266         ),
00267         right (
00268             ::boost::multi_index::get<
00269                 BOOST_DEDUCED_TYPENAME base_::logic_right_tag
00270             >(core)
00271         )
00272 
00273     {}
00274 
00275     bimap& operator=(const bimap& x)
00276     {
00277         core = x.core;
00278         return *this;
00279     }
00280 
00281     // Projection of iterators
00282 
00283     template< class IteratorType >
00284     BOOST_DEDUCED_TYPENAME base_::left_iterator
00285         project_left(IteratorType iter)
00286     {
00287         return core.template project<
00288             BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base());
00289     }
00290 
00291     template< class IteratorType >
00292     BOOST_DEDUCED_TYPENAME base_::left_const_iterator
00293         project_left(IteratorType iter) const
00294     {
00295         return core.template project<
00296             BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base());
00297     }
00298 
00299     template< class IteratorType >
00300     BOOST_DEDUCED_TYPENAME base_::right_iterator
00301         project_right(IteratorType iter)
00302     {
00303         return core.template project<
00304             BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base());
00305     }
00306 
00307     template< class IteratorType >
00308     BOOST_DEDUCED_TYPENAME base_::right_const_iterator
00309         project_right(IteratorType iter) const
00310     {
00311         return core.template project<
00312             BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base());
00313     }
00314 
00315     template< class IteratorType >
00316     BOOST_DEDUCED_TYPENAME base_::relation_set::iterator
00317         project_up(IteratorType iter)
00318     {
00319         return core.template project<
00320             BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base());
00321     }
00322 
00323     template< class IteratorType >
00324     BOOST_DEDUCED_TYPENAME base_::relation_set::const_iterator
00325         project_up(IteratorType iter) const
00326     {
00327         return core.template project<
00328             BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base());
00329     }
00330 
00331     // Support for tags
00332 
00333     template< class Tag, class IteratorType >
00334     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00335     iterator_type_by<Tag,bimap>::type
00336         project(IteratorType iter
00337                 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
00338     {
00339         return core.template project<Tag>(iter.base());
00340     }
00341 
00342     template< class Tag, class IteratorType >
00343     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00344     const_iterator_type_by<Tag,bimap>::type
00345         project(IteratorType iter
00346                 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) const
00347     {
00348         return core.template project<Tag>(iter.base());
00349     }
00350 
00351     template< class Tag >
00352     struct map_by :
00353         public ::boost::bimaps::support::map_type_by<Tag,bimap>::type
00354     {
00355         typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00356             map_type_by<Tag,bimap>::type type;
00357 
00358         private: map_by() {}
00359     };
00360 
00361     template< class Tag >
00362     BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00363     map_type_by<Tag,bimap>::type &
00364         by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))
00365     {
00366         return ::boost::bimaps::support::map_by<Tag>(*this);
00367     }
00368 
00369     template< class Tag >
00370     const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
00371     map_type_by<Tag,bimap>::type &
00372         by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) const
00373     {
00374         return ::boost::bimaps::support::map_by<Tag>(*this);
00375     }
00376 
00377 
00378     #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
00379 
00380     // Serialization support
00381 
00382     private:
00383 
00384     friend class boost::serialization::access;
00385 
00386     template<class Archive>
00387     void serialize(Archive & ar, const unsigned int version)
00388     {
00389         ar & serialization::make_nvp("mi_core",core);
00390     }
00391 
00392     #endif // BOOST_BIMAP_DISABLE_SERIALIZATION
00393 };
00394 
00395 } // namespace bimaps
00396 } // namespace boost
00397 
00398 
00399 /** \namespace boost::bimaps::support
00400 \brief Metafunctions to help working with bimaps.
00401                                                             **/
00402 
00403 /** \namespace boost::bimaps::views
00404 \brief Bimap views.
00405                                                             **/
00406 
00407 /** \namespace boost::bimaps::views::detail
00408 \brief Bimap views details.
00409                                                             **/
00410 
00411 
00412 
00413 // Include basic tools for user commodity
00414 
00415 #include <boost/bimap/tags/tagged.hpp>
00416 #include <boost/bimap/relation/member_at.hpp>
00417 #include <boost/multi_index/detail/unbounded.hpp>
00418 
00419 // Bring the most used namespaces directly to the user main namespace
00420 namespace boost {
00421 namespace bimaps {
00422 
00423 using ::boost::bimaps::tags::tagged;
00424 
00425 namespace member_at = ::boost::bimaps::relation::member_at;
00426 
00427 using ::boost::multi_index::unbounded;
00428 
00429 } // namespace bimaps
00430 } // namespace boost
00431 
00432 
00433 #endif // BOOST_BIMAP_BIMAP_HPP
Copyright 2006 Matias Capeletto

PrevUpHomeNext