123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- // 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)
- #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>
- #include <boost/bimap/detail/map_view_iterator.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::bimaps::detail:: map_view_iterator<TAG,BIMAP>, \
- ::boost::bimaps::detail::const_map_view_iterator<TAG,BIMAP>, \
- ::boost::bimaps::detail:: OTHER_ITER<TAG,BIMAP>, \
- ::boost::bimaps::detail::CONST_OTHER_ITER<TAG,BIMAP>, \
- ::boost::bimaps::container_adaptor::support::iterator_facade_to_base \
- < \
- ::boost::bimaps::detail:: map_view_iterator<TAG,BIMAP>, \
- ::boost::bimaps::detail::const_map_view_iterator<TAG,BIMAP> \
- >, \
- ::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::bimaps::detail:: map_view_iterator<Tag,BimapType>,
- ::boost::bimaps::detail::const_map_view_iterator<Tag,BimapType>
- > 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::bimaps::detail::map_view_iterator<Tag,BimapType> 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_>()(
- ::boost::bimaps::relation::detail::
- copy_with_first_replaced(*position,k)
- )
- );
- }
- 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_>()(
- ::boost::bimaps::relation::detail::
- copy_with_second_replaced(*position,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::bimaps::detail::
- map_view_iterator<Tag,BimapType> 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::bimaps::detail::
- const_map_view_iterator<Tag,BimapType> 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::bimaps::detail::
- map_view_iterator<Tag,BimapType> 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::bimaps::detail::
- const_map_view_iterator<Tag,BimapType> 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&)
- {
- 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 ; ++i) \
- { \
- 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
|