You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
431 lines
13 KiB
431 lines
13 KiB
// 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
|
|
|