// 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 |