--- /dev/null
+// 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/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