| // Boost.Bimap |
| // |
| // Copyright (c) 2006-2007 Matias Capeletto |
| // |
| // Distributed under the Boost Software License, Version 1.0. |
| // (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| |
| /// \file bimap.hpp |
| /// \brief Includes the basic bimap container |
| |
| /** \mainpage notitle |
| \n |
| \image html http://matias.capeletto.googlepages.com/boost.bimap.reference.logo.png |
| |
| \section Introduction |
| |
| This is the complete reference of Boost.Bimap. |
| |
| After getting a good understanding of the library from a user perspective |
| the next step will be: |
| |
| - Understand the tagged idiom. (boost::bimaps::tags) |
| - Understand the internals of the relation class (boost::bimaps::relation) |
| - Read the container_adaptor toolbox docs (boost::bimaps::container_adaptor) |
| - Understand the internals of the bimap class. (boost::bimaps, boost::bimaps::views |
| and boost::bimaps::detail) |
| |
| |
| **/ |
| |
| /** \defgroup mutant_group mutant idiom |
| \brief A safe wrapper around reinterpret_cast |
| **/ |
| |
| /** \defgroup relation_group relation |
| \brief The relation |
| **/ |
| |
| /** \defgroup tags_group tagged idiom |
| \brief The tagged idiom |
| **/ |
| |
| |
| #ifndef BOOST_BIMAP_BIMAP_HPP |
| #define BOOST_BIMAP_BIMAP_HPP |
| |
| #if defined(_MSC_VER) && (_MSC_VER>=1200) |
| #pragma once |
| #endif |
| |
| #include <boost/config.hpp> |
| #include <boost/bimap/detail/user_interface_config.hpp> |
| #include <boost/mpl/aux_/na.hpp> |
| |
| #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION |
| #include <boost/serialization/nvp.hpp> |
| #endif // BOOST_BIMAP_DISABLE_SERIALIZATION |
| |
| // Boost.Bimap |
| #include <boost/bimap/detail/bimap_core.hpp> |
| #include <boost/bimap/detail/map_view_base.hpp> |
| #include <boost/bimap/detail/modifier_adaptor.hpp> |
| #include <boost/bimap/relation/support/data_extractor.hpp> |
| #include <boost/bimap/relation/support/member_with_tag.hpp> |
| |
| #include <boost/bimap/support/map_type_by.hpp> |
| #include <boost/bimap/support/map_by.hpp> |
| #include <boost/bimap/support/iterator_type_by.hpp> |
| |
| /// \brief The namespace where all the boost libraries lives. |
| |
| namespace boost { |
| |
| /// \brief Boost.Bimap library namespace |
| /** |
| All the entities in the library are defined in this namespace. |
| **/ |
| namespace bimaps { |
| |
| /// \brief The bimap class is the entry point to the library. |
| /** |
| This class manages the instantiation of the desired bimap type. |
| As there are several types of bidirectional maps that can be |
| created using it. the main job of it is to find the desired |
| type. This is done using metaprogramming to obtain the relation |
| type that will be stored, the map_view type of each side and |
| the set_view type of the general relationship. The instantiation |
| is kept simple using an extended standard set theory, where a |
| bidirectional map type is defined by the set types it relates. |
| For example, a bidirectional map that has multimap semantics |
| viewed from both sides is defined by specifying that the two |
| keys sets are of \c multiset_of<Key> type. |
| This allows the bimap class to support seamingless N-N, 1-N, |
| ordered/unordered and even vector-list types of mapping. |
| The three last parameters are used to specify the set type of |
| the relation, an inplace hooked data class and the allocator |
| type. As a help to the bimap user, these parameters support |
| default types but use a special idiom that allow them to be |
| specified without interleaving the usual use_default keyword. |
| The possible bimap instantiation are enumerated here: |
| \c {Side}KeyType can be directly a type, this is default to |
| \c set_of<{Side}KeyType>, or can be a \c {SetType}_of<Type> |
| specification. Additionally this two parameters can be tagged |
| to specify others tags instead of the usual \c member_at::{Side} |
| ones. |
| |
| |
| \code |
| |
| typedef bimap |
| < |
| LeftCollectionType, RightCollectionType |
| |
| [ , SetTypeOfRelation ] // Default to left_based |
| [ , info_hook< Info > ] // Default to no info |
| [ , Allocator ] // Default to std::allocator<> |
| |
| > bm; |
| |
| \endcode |
| |
| **/ |
| |
| |
| template |
| < |
| class KeyTypeA, class KeyTypeB, |
| class AP1 = ::boost::mpl::na, |
| class AP2 = ::boost::mpl::na, |
| class AP3 = ::boost::mpl::na |
| > |
| class bimap |
| : |
| // Bimap Core, use mpl magic to find the desired bimap type |
| |
| public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>, |
| |
| // You can use bimap as a collection of relations |
| |
| public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3> |
| ::relation_set, |
| |
| // Include extra typedefs (i.e. left_local_iterator for unordered_map) |
| |
| public ::boost::bimaps::detail:: left_map_view_extra_typedefs< |
| BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::left_map_view_type< |
| ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3> |
| >::type |
| >, |
| public ::boost::bimaps::detail::right_map_view_extra_typedefs< |
| BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::right_map_view_type< |
| ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3> |
| >::type |
| > |
| { |
| typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail:: |
| bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3> base_; |
| |
| BOOST_DEDUCED_TYPENAME base_::core_type core; |
| |
| public: |
| |
| // metadata -------------------------------------------------------- |
| |
| /* |
| // The rest is computed in the core, because it is quite difficult to |
| // expose a nice interface with so many metaprogramming stuff. |
| // Here it is the complete metadat list. |
| |
| // Map by {side} metadata |
| |
| typedef -unspecified- {side}_tag; |
| typedef -unspecified- {side}_data_type; |
| typedef -unspecified- {side}_value_type; |
| typedef -unspecified- {side}_key_type; |
| typedef -unspecified- {side}_iterator; |
| typedef -unspecified- {side}_const_iterator; |
| |
| ------------------------------------------------------------------*/ |
| |
| typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail:: |
| left_map_view_type<base_>::type left_map; |
| typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail:: |
| right_map_view_type<base_>::type right_map; |
| |
| typedef BOOST_DEDUCED_TYPENAME |
| left_map::reference left_reference; |
| typedef BOOST_DEDUCED_TYPENAME |
| left_map::const_reference left_const_reference; |
| |
| typedef BOOST_DEDUCED_TYPENAME |
| right_map::reference right_reference; |
| typedef BOOST_DEDUCED_TYPENAME |
| right_map::const_reference right_const_reference; |
| |
| typedef BOOST_DEDUCED_TYPENAME base_::relation::info_type info_type; |
| |
| typedef BOOST_DEDUCED_TYPENAME base_::core_type::allocator_type allocator_type; |
| |
| /// Left map view |
| left_map left; |
| |
| /// Right map view |
| right_map right; |
| |
| typedef BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag |
| logic_relation_set_tag; |
| typedef BOOST_DEDUCED_TYPENAME base_::logic_left_tag logic_left_tag; |
| typedef BOOST_DEDUCED_TYPENAME base_::logic_right_tag logic_right_tag; |
| typedef BOOST_DEDUCED_TYPENAME base_::core_type::ctor_args_list |
| ctor_args_list; |
| |
| bimap(const allocator_type& al = allocator_type()) : |
| |
| base_::relation_set( |
| ::boost::multi_index::get< |
| logic_relation_set_tag |
| >(core) |
| ), |
| |
| core(al), |
| |
| left ( |
| ::boost::multi_index::get< |
| logic_left_tag |
| >(core) |
| ), |
| right ( |
| ::boost::multi_index::get< |
| logic_right_tag |
| >(core) |
| ) |
| |
| {} |
| |
| template< class InputIterator > |
| bimap(InputIterator first,InputIterator last, |
| const allocator_type& al = allocator_type()) : |
| |
| base_::relation_set( |
| ::boost::multi_index::get<logic_relation_set_tag>(core) |
| ), |
| |
| core(first,last,ctor_args_list(),al), |
| |
| left ( |
| ::boost::multi_index::get<logic_left_tag>(core) |
| ), |
| right ( |
| ::boost::multi_index::get<logic_right_tag>(core) |
| ) |
| |
| {} |
| |
| bimap(const bimap& x) : |
| |
| base_::relation_set( |
| ::boost::multi_index::get<logic_relation_set_tag>(core) |
| ), |
| |
| core(x.core), |
| |
| left ( |
| ::boost::multi_index::get<logic_left_tag>(core) |
| ), |
| right ( |
| ::boost::multi_index::get<logic_right_tag>(core) |
| ) |
| |
| {} |
| |
| bimap& operator=(const bimap& x) |
| { |
| core = x.core; |
| return *this; |
| } |
| |
| // Projection of iterators |
| |
| template< class IteratorType > |
| BOOST_DEDUCED_TYPENAME base_::left_iterator |
| project_left(IteratorType iter) |
| { |
| return core.template project< |
| BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base()); |
| } |
| |
| template< class IteratorType > |
| BOOST_DEDUCED_TYPENAME base_::left_const_iterator |
| project_left(IteratorType iter) const |
| { |
| return core.template project< |
| BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base()); |
| } |
| |
| template< class IteratorType > |
| BOOST_DEDUCED_TYPENAME base_::right_iterator |
| project_right(IteratorType iter) |
| { |
| return core.template project< |
| BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base()); |
| } |
| |
| template< class IteratorType > |
| BOOST_DEDUCED_TYPENAME base_::right_const_iterator |
| project_right(IteratorType iter) const |
| { |
| return core.template project< |
| BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base()); |
| } |
| |
| template< class IteratorType > |
| BOOST_DEDUCED_TYPENAME base_::relation_set::iterator |
| project_up(IteratorType iter) |
| { |
| return core.template project< |
| BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base()); |
| } |
| |
| template< class IteratorType > |
| BOOST_DEDUCED_TYPENAME base_::relation_set::const_iterator |
| project_up(IteratorType iter) const |
| { |
| return core.template project< |
| BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base()); |
| } |
| |
| // Support for tags |
| |
| template< class Tag, class IteratorType > |
| BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
| iterator_type_by<Tag,bimap>::type |
| project(IteratorType iter |
| BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) |
| { |
| return core.template project<Tag>(iter.base()); |
| } |
| |
| template< class Tag, class IteratorType > |
| BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
| const_iterator_type_by<Tag,bimap>::type |
| project(IteratorType iter |
| BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) const |
| { |
| return core.template project<Tag>(iter.base()); |
| } |
| |
| template< class Tag > |
| struct map_by : |
| public ::boost::bimaps::support::map_type_by<Tag,bimap>::type |
| { |
| typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
| map_type_by<Tag,bimap>::type type; |
| |
| private: map_by() {} |
| }; |
| |
| template< class Tag > |
| BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
| map_type_by<Tag,bimap>::type & |
| by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) |
| { |
| return ::boost::bimaps::support::map_by<Tag>(*this); |
| } |
| |
| template< class Tag > |
| const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
| map_type_by<Tag,bimap>::type & |
| by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) const |
| { |
| return ::boost::bimaps::support::map_by<Tag>(*this); |
| } |
| |
| |
| #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION |
| |
| // Serialization support |
| |
| private: |
| |
| friend class boost::serialization::access; |
| |
| template<class Archive> |
| void serialize(Archive & ar, const unsigned int version) |
| { |
| ar & serialization::make_nvp("mi_core",core); |
| } |
| |
| #endif // BOOST_BIMAP_DISABLE_SERIALIZATION |
| }; |
| |
| } // namespace bimaps |
| } // namespace boost |
| |
| |
| /** \namespace boost::bimaps::support |
| \brief Metafunctions to help working with bimaps. |
| **/ |
| |
| /** \namespace boost::bimaps::views |
| \brief Bimap views. |
| **/ |
| |
| /** \namespace boost::bimaps::views::detail |
| \brief Bimap views details. |
| **/ |
| |
| |
| |
| // Include basic tools for user commodity |
| |
| #include <boost/bimap/tags/tagged.hpp> |
| #include <boost/bimap/relation/member_at.hpp> |
| #include <boost/multi_index/detail/unbounded.hpp> |
| |
| // Bring the most used namespaces directly to the user main namespace |
| namespace boost { |
| namespace bimaps { |
| |
| using ::boost::bimaps::tags::tagged; |
| |
| namespace member_at = ::boost::bimaps::relation::member_at; |
| |
| using ::boost::multi_index::unbounded; |
| |
| } // namespace bimaps |
| } // namespace boost |
| |
| |
| #endif // BOOST_BIMAP_BIMAP_HPP |