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