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.
553 lines
23 KiB
553 lines
23 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 detail/map_view_base.hpp |
|
/// \brief Helper base for the construction of the bimap views types. |
|
|
|
#ifndef BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP |
|
#define BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP |
|
|
|
#if defined(_MSC_VER) && (_MSC_VER>=1200) |
|
#pragma once |
|
#endif |
|
|
|
#include <boost/config.hpp> |
|
|
|
#include <stdexcept> |
|
#include <utility> |
|
|
|
#include <boost/throw_exception.hpp> |
|
#include <boost/type_traits/is_const.hpp> |
|
#include <boost/mpl/if.hpp> |
|
|
|
#include <boost/bimap/relation/support/get_pair_functor.hpp> |
|
#include <boost/bimap/relation/detail/to_mutable_relation_functor.hpp> |
|
#include <boost/bimap/container_adaptor/support/iterator_facade_converters.hpp> |
|
#include <boost/bimap/relation/support/data_extractor.hpp> |
|
#include <boost/bimap/relation/support/opposite_tag.hpp> |
|
#include <boost/bimap/relation/support/pair_type_by.hpp> |
|
#include <boost/bimap/support/iterator_type_by.hpp> |
|
#include <boost/bimap/support/key_type_by.hpp> |
|
#include <boost/bimap/support/data_type_by.hpp> |
|
#include <boost/bimap/support/value_type_by.hpp> |
|
#include <boost/bimap/detail/modifier_adaptor.hpp> |
|
#include <boost/bimap/detail/debug/static_error.hpp> |
|
|
|
namespace boost { |
|
namespace bimaps { |
|
|
|
namespace detail { |
|
|
|
|
|
// The next macro can be converted in a metafunctor to gain code robustness. |
|
/*===========================================================================*/ |
|
#define BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( \ |
|
CONTAINER_ADAPTOR, TAG,BIMAP, OTHER_ITER, CONST_OTHER_ITER \ |
|
) \ |
|
::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR \ |
|
< \ |
|
BOOST_DEDUCED_TYPENAME BIMAP::core_type:: \ |
|
BOOST_NESTED_TEMPLATE index<TAG>::type, \ |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ |
|
iterator_type_by<TAG,BIMAP>::type, \ |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ |
|
const_iterator_type_by<TAG,BIMAP>::type, \ |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ |
|
OTHER_ITER<TAG,BIMAP>::type, \ |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ |
|
CONST_OTHER_ITER<TAG,BIMAP>::type, \ |
|
::boost::bimaps::container_adaptor::support::iterator_facade_to_base \ |
|
< \ |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ |
|
iterator_type_by<TAG,BIMAP>::type, \ |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \ |
|
const_iterator_type_by<TAG,BIMAP>::type \ |
|
\ |
|
>, \ |
|
::boost::mpl::na, \ |
|
::boost::mpl::na, \ |
|
::boost::bimaps::relation::detail:: \ |
|
pair_to_relation_functor<TAG,BOOST_DEDUCED_TYPENAME BIMAP::relation>, \ |
|
::boost::bimaps::relation::support:: \ |
|
get_pair_functor<TAG, BOOST_DEDUCED_TYPENAME BIMAP::relation > \ |
|
> |
|
/*===========================================================================*/ |
|
|
|
|
|
#if defined(BOOST_MSVC) |
|
/*===========================================================================*/ |
|
#define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP) \ |
|
typedef ::boost::bimaps::detail::map_view_base< \ |
|
TYPE<TAG,BIMAP>,TAG,BIMAP > friend_map_view_base; \ |
|
friend class friend_map_view_base; |
|
/*===========================================================================*/ |
|
#else |
|
/*===========================================================================*/ |
|
#define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP) \ |
|
friend class ::boost::bimaps::detail::map_view_base< \ |
|
TYPE<TAG,BIMAP>,TAG,BIMAP >; |
|
/*===========================================================================*/ |
|
#endif |
|
|
|
|
|
/// \brief Common base for map views. |
|
|
|
template< class Derived, class Tag, class BimapType> |
|
class map_view_base |
|
{ |
|
typedef ::boost::bimaps::container_adaptor::support:: |
|
iterator_facade_to_base< |
|
|
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
iterator_type_by<Tag,BimapType>::type, |
|
|
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
const_iterator_type_by<Tag,BimapType>::type |
|
|
|
> iterator_to_base_; |
|
|
|
typedef ::boost::bimaps::relation::detail:: |
|
pair_to_relation_functor<Tag, |
|
BOOST_DEDUCED_TYPENAME BimapType::relation> value_to_base_; |
|
|
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
key_type_by<Tag,BimapType>::type key_type_; |
|
|
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
data_type_by<Tag,BimapType>::type data_type_; |
|
|
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: |
|
pair_type_by<Tag, |
|
BOOST_DEDUCED_TYPENAME BimapType::relation>::type value_type_; |
|
|
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
iterator_type_by<Tag,BimapType>::type iterator_; |
|
|
|
public: |
|
|
|
bool replace(iterator_ position, const value_type_ & x) |
|
{ |
|
return derived().base().replace( |
|
derived().template functor<iterator_to_base_>()(position), |
|
derived().template functor<value_to_base_>()(x) |
|
); |
|
} |
|
|
|
template< class CompatibleKey > |
|
bool replace_key(iterator_ position, const CompatibleKey & k) |
|
{ |
|
return derived().base().replace( |
|
derived().template functor<iterator_to_base_>()(position), |
|
derived().template functor<value_to_base_>()( |
|
value_type_(k,position->second) |
|
) |
|
); |
|
} |
|
|
|
template< class CompatibleData > |
|
bool replace_data(iterator_ position, const CompatibleData & d) |
|
{ |
|
return derived().base().replace( |
|
derived().template functor<iterator_to_base_>()(position), |
|
derived().template functor<value_to_base_>()( |
|
value_type_(position->first,d) |
|
) |
|
); |
|
} |
|
|
|
/* This function may be provided in the future |
|
|
|
template< class Modifier > |
|
bool modify(iterator_ position, Modifier mod) |
|
{ |
|
return derived().base().modify( |
|
|
|
derived().template functor<iterator_to_base_>()(position), |
|
|
|
::boost::bimaps::detail::relation_modifier_adaptor |
|
< |
|
Modifier, |
|
BOOST_DEDUCED_TYPENAME BimapType::relation, |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: |
|
data_extractor |
|
< |
|
Tag, BOOST_DEDUCED_TYPENAME BimapType::relation |
|
|
|
>::type, |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: |
|
data_extractor |
|
< |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: |
|
opossite_tag<Tag,BimapType>::type, |
|
BOOST_DEDUCED_TYPENAME BimapType::relation |
|
|
|
>::type |
|
|
|
>(mod) |
|
); |
|
} |
|
*/ |
|
|
|
template< class Modifier > |
|
bool modify_key(iterator_ position, Modifier mod) |
|
{ |
|
return derived().base().modify_key( |
|
derived().template functor<iterator_to_base_>()(position), mod |
|
); |
|
} |
|
|
|
template< class Modifier > |
|
bool modify_data(iterator_ position, Modifier mod) |
|
{ |
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: |
|
data_extractor |
|
< |
|
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: |
|
opossite_tag<Tag,BimapType>::type, |
|
BOOST_DEDUCED_TYPENAME BimapType::relation |
|
|
|
>::type data_extractor_; |
|
|
|
return derived().base().modify( |
|
|
|
derived().template functor<iterator_to_base_>()(position), |
|
|
|
// this may be replaced later by |
|
// ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) ) |
|
|
|
::boost::bimaps::detail::unary_modifier_adaptor |
|
< |
|
Modifier, |
|
BOOST_DEDUCED_TYPENAME BimapType::relation, |
|
data_extractor_ |
|
|
|
>(mod) |
|
); |
|
} |
|
|
|
protected: |
|
|
|
typedef map_view_base map_view_base_; |
|
|
|
private: |
|
|
|
// Curiously Recurring Template interface. |
|
|
|
Derived& derived() |
|
{ |
|
return *static_cast<Derived*>(this); |
|
} |
|
|
|
Derived const& derived() const |
|
{ |
|
return *static_cast<Derived const*>(this); |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
template< class Derived, class Tag, class BimapType> |
|
class mutable_data_unique_map_view_access |
|
{ |
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
data_type_by<Tag,BimapType>::type data_type_; |
|
|
|
public: |
|
|
|
template< class CompatibleKey > |
|
data_type_ & at(const CompatibleKey& k) |
|
{ |
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
iterator_type_by<Tag,BimapType>::type iterator; |
|
|
|
iterator iter = derived().find(k); |
|
if( iter == derived().end() ) |
|
{ |
|
::boost::throw_exception( |
|
std::out_of_range("bimap<>: invalid key") |
|
); |
|
} |
|
return iter->second; |
|
} |
|
|
|
template< class CompatibleKey > |
|
const data_type_ & at(const CompatibleKey& k) const |
|
{ |
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
const_iterator_type_by<Tag,BimapType>::type const_iterator; |
|
|
|
const_iterator iter = derived().find(k); |
|
if( iter == derived().end() ) |
|
{ |
|
::boost::throw_exception( |
|
std::out_of_range("bimap<>: invalid key") |
|
); |
|
} |
|
return iter->second; |
|
} |
|
|
|
template< class CompatibleKey > |
|
data_type_ & operator[](const CompatibleKey& k) |
|
{ |
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
iterator_type_by<Tag,BimapType>::type iterator; |
|
|
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
value_type_by<Tag,BimapType>::type value_type; |
|
|
|
iterator iter = derived().find(k); |
|
if( iter == derived().end() ) |
|
{ |
|
iter = derived().insert( value_type(k,data_type_()) ).first; |
|
} |
|
return iter->second; |
|
} |
|
|
|
protected: |
|
|
|
typedef mutable_data_unique_map_view_access |
|
mutable_data_unique_map_view_access_; |
|
|
|
private: |
|
|
|
// Curiously Recurring Template interface. |
|
|
|
Derived& derived() |
|
{ |
|
return *static_cast<Derived*>(this); |
|
} |
|
|
|
Derived const& derived() const |
|
{ |
|
return *static_cast<Derived const*>(this); |
|
} |
|
}; |
|
|
|
|
|
template< class Derived, class Tag, class BimapType> |
|
class non_mutable_data_unique_map_view_access |
|
{ |
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
data_type_by<Tag,BimapType>::type data_type_; |
|
|
|
public: |
|
|
|
template< class CompatibleKey > |
|
const data_type_ & at(const CompatibleKey& k) const |
|
{ |
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
const_iterator_type_by<Tag,BimapType>::type const_iterator; |
|
|
|
const_iterator iter = derived().find(k); |
|
if( iter == derived().end() ) |
|
{ |
|
::boost::throw_exception( |
|
std::out_of_range("bimap<>: invalid key") |
|
); |
|
} |
|
return iter->second; |
|
} |
|
|
|
template< class CompatibleKey > |
|
data_type_ & operator[](const CompatibleKey& k) |
|
{ |
|
BOOST_BIMAP_STATIC_ERROR( OPERATOR_BRACKET_IS_NOT_SUPPORTED, (Derived)); |
|
} |
|
|
|
protected: |
|
|
|
typedef non_mutable_data_unique_map_view_access |
|
non_mutable_data_unique_map_view_access_; |
|
|
|
private: |
|
|
|
// Curiously Recurring Template interface. |
|
|
|
Derived& derived() |
|
{ |
|
return *static_cast<Derived*>(this); |
|
} |
|
|
|
Derived const& derived() const |
|
{ |
|
return *static_cast<Derived const*>(this); |
|
} |
|
}; |
|
|
|
|
|
template< class Derived, class Tag, class BimapType> |
|
struct unique_map_view_access |
|
{ |
|
private: |
|
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: |
|
value_type_by<Tag,BimapType>::type value_type; |
|
|
|
public: |
|
typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_ |
|
< |
|
typename ::boost::is_const< |
|
BOOST_DEDUCED_TYPENAME value_type::second_type >::type, |
|
|
|
non_mutable_data_unique_map_view_access<Derived,Tag,BimapType>, |
|
mutable_data_unique_map_view_access<Derived,Tag,BimapType> |
|
|
|
>::type type; |
|
}; |
|
|
|
// Map views specialize the following structs to provide to the bimap class |
|
// the extra side typedefs (i.e. left_local_iterator for unordered_maps, |
|
// right_range_type for maps) |
|
|
|
template< class MapView > |
|
struct left_map_view_extra_typedefs {}; |
|
|
|
template< class MapView > |
|
struct right_map_view_extra_typedefs {}; |
|
|
|
} // namespace detail |
|
|
|
// This function is already part of Boost.Lambda. |
|
// They may be moved to Boost.Utility. |
|
|
|
template <class T> inline const T& make_const(const T& t) { return t; } |
|
|
|
} // namespace bimaps |
|
} // namespace boost |
|
|
|
|
|
// The following macros avoids code duplication in map views |
|
// Maybe this can be changed in the future using a scheme similar to |
|
// the one used with map_view_base. |
|
|
|
/*===========================================================================*/ |
|
#define BOOST_BIMAP_MAP_VIEW_RANGE_IMPLEMENTATION(BASE) \ |
|
\ |
|
typedef std::pair< \ |
|
BOOST_DEDUCED_TYPENAME base_::iterator, \ |
|
BOOST_DEDUCED_TYPENAME base_::iterator> range_type; \ |
|
\ |
|
typedef std::pair< \ |
|
BOOST_DEDUCED_TYPENAME base_::const_iterator, \ |
|
BOOST_DEDUCED_TYPENAME base_::const_iterator> const_range_type; \ |
|
\ |
|
\ |
|
template< class LowerBounder, class UpperBounder> \ |
|
range_type range(LowerBounder lower,UpperBounder upper) \ |
|
{ \ |
|
std::pair< \ |
|
\ |
|
BOOST_DEDUCED_TYPENAME BASE::base_type::iterator, \ |
|
BOOST_DEDUCED_TYPENAME BASE::base_type::iterator \ |
|
\ |
|
> r( this->base().range(lower,upper) ); \ |
|
\ |
|
return range_type( \ |
|
this->template functor< \ |
|
BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \ |
|
>() ( r.first ), \ |
|
this->template functor< \ |
|
BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \ |
|
>() ( r.second ) \ |
|
); \ |
|
} \ |
|
\ |
|
template< class LowerBounder, class UpperBounder> \ |
|
const_range_type range(LowerBounder lower,UpperBounder upper) const \ |
|
{ \ |
|
std::pair< \ |
|
\ |
|
BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator, \ |
|
BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator \ |
|
\ |
|
> r( this->base().range(lower,upper) ); \ |
|
\ |
|
return const_range_type( \ |
|
this->template functor< \ |
|
BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \ |
|
>() ( r.first ), \ |
|
this->template functor< \ |
|
BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \ |
|
>() ( r.second ) \ |
|
); \ |
|
} |
|
/*===========================================================================*/ |
|
|
|
|
|
/*===========================================================================*/ |
|
#define BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(BASE) \ |
|
\ |
|
template< class InputIterator > \ |
|
void assign(InputIterator first,InputIterator last) \ |
|
{ \ |
|
this->clear(); \ |
|
this->insert(this->end(),first,last); \ |
|
} \ |
|
\ |
|
void assign(BOOST_DEDUCED_TYPENAME BASE::size_type n, \ |
|
const BOOST_DEDUCED_TYPENAME BASE::value_type& v) \ |
|
{ \ |
|
this->clear(); \ |
|
for(BOOST_DEDUCED_TYPENAME BASE::size_type i = 0 ; i < n ; ++n) \ |
|
{ \ |
|
this->push_back(v); \ |
|
} \ |
|
} |
|
/*===========================================================================*/ |
|
|
|
|
|
/*===========================================================================*/ |
|
#define BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(BASE) \ |
|
\ |
|
BOOST_DEDUCED_TYPENAME BASE::reference front() \ |
|
{ \ |
|
return this->template functor< \ |
|
BOOST_DEDUCED_TYPENAME base_::value_from_base>() \ |
|
( \ |
|
const_cast \ |
|
< \ |
|
BOOST_DEDUCED_TYPENAME BASE::base_type::value_type & \ |
|
\ |
|
> ( this->base().front() ) \ |
|
); \ |
|
} \ |
|
\ |
|
BOOST_DEDUCED_TYPENAME BASE::reference back() \ |
|
{ \ |
|
return this->template functor< \ |
|
BOOST_DEDUCED_TYPENAME base_::value_from_base>() \ |
|
( \ |
|
const_cast \ |
|
< \ |
|
BOOST_DEDUCED_TYPENAME BASE::base_type::value_type & \ |
|
\ |
|
>( this->base().back() ) \ |
|
); \ |
|
} \ |
|
\ |
|
BOOST_DEDUCED_TYPENAME BASE::const_reference front() const \ |
|
{ \ |
|
return this->template functor< \ |
|
BOOST_DEDUCED_TYPENAME BASE::value_from_base>() \ |
|
( \ |
|
this->base().front() \ |
|
); \ |
|
} \ |
|
\ |
|
BOOST_DEDUCED_TYPENAME BASE::const_reference back() const \ |
|
{ \ |
|
return this->template functor< \ |
|
BOOST_DEDUCED_TYPENAME BASE::value_from_base>() \ |
|
( \ |
|
this->base().back() \ |
|
); \ |
|
} |
|
/*===========================================================================*/ |
|
|
|
|
|
#endif // BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
|
|
|