// 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 container_adaptor/container_adaptor.hpp | |
/// \brief Container adaptor to build a type that is compliant to the concept of a container. | |
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP | |
#define BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP | |
#if defined(_MSC_VER) && (_MSC_VER>=1200) | |
#pragma once | |
#endif | |
#include <boost/config.hpp> | |
#include <utility> | |
#include <boost/mpl/if.hpp> | |
#include <boost/mpl/aux_/na.hpp> | |
#include <boost/bimap/container_adaptor/detail/identity_converters.hpp> | |
#include <boost/iterator/iterator_traits.hpp> | |
#include <boost/bimap/container_adaptor/detail/functor_bag.hpp> | |
#include <boost/mpl/vector.hpp> | |
#include <boost/mpl/copy.hpp> | |
#include <boost/mpl/front_inserter.hpp> | |
#include <boost/call_traits.hpp> | |
namespace boost { | |
namespace bimaps { | |
/// \brief Container Adaptor toolbox, easy way to build new containers from existing ones. | |
namespace container_adaptor { | |
/// \brief Container adaptor to build a type that is compliant to the concept of a container. | |
template | |
< | |
class Base, | |
class Iterator, | |
class ConstIterator, | |
class IteratorToBaseConverter = ::boost::mpl::na, | |
class IteratorFromBaseConverter = ::boost::mpl::na, | |
class ValueToBaseConverter = ::boost::mpl::na, | |
class ValueFromBaseConverter = ::boost::mpl::na, | |
class FunctorsFromDerivedClasses = mpl::vector<> | |
> | |
class container_adaptor | |
{ | |
// MetaData ------------------------------------------------------------- | |
public: | |
typedef Iterator iterator; | |
typedef ConstIterator const_iterator; | |
typedef BOOST_DEDUCED_TYPENAME iterator_value < iterator >::type value_type; | |
typedef BOOST_DEDUCED_TYPENAME iterator_pointer < iterator >::type pointer; | |
typedef BOOST_DEDUCED_TYPENAME iterator_reference< iterator >::type reference; | |
typedef BOOST_DEDUCED_TYPENAME iterator_reference< const_iterator >::type const_reference; | |
typedef BOOST_DEDUCED_TYPENAME Base::size_type size_type; | |
typedef BOOST_DEDUCED_TYPENAME Base::difference_type difference_type; | |
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorToBaseConverter>, | |
// { | |
::boost::bimaps::container_adaptor::detail:: | |
iterator_to_base_identity | |
< | |
BOOST_DEDUCED_TYPENAME Base::iterator , iterator, | |
BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator | |
>, | |
// } | |
// else | |
// { | |
IteratorToBaseConverter | |
// } | |
>::type iterator_to_base; | |
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorFromBaseConverter>, | |
// { | |
::boost::bimaps::container_adaptor::detail:: | |
iterator_from_base_identity | |
< | |
BOOST_DEDUCED_TYPENAME Base::iterator , iterator, | |
BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator | |
>, | |
// } | |
// else | |
// { | |
IteratorFromBaseConverter | |
// } | |
>::type iterator_from_base; | |
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueToBaseConverter>, | |
// { | |
::boost::bimaps::container_adaptor::detail:: | |
value_to_base_identity | |
< | |
BOOST_DEDUCED_TYPENAME Base::value_type, | |
value_type | |
>, | |
// } | |
// else | |
// { | |
ValueToBaseConverter | |
// } | |
>::type value_to_base; | |
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueFromBaseConverter>, | |
// { | |
::boost::bimaps::container_adaptor::detail:: | |
value_from_base_identity | |
< | |
BOOST_DEDUCED_TYPENAME Base::value_type, | |
value_type | |
>, | |
// } | |
// else | |
// { | |
ValueFromBaseConverter | |
// } | |
>::type value_from_base; | |
// ACCESS ----------------------------------------------------------------- | |
public: | |
explicit container_adaptor(Base & c) : dwfb(c) {} | |
protected: | |
typedef Base base_type; | |
typedef container_adaptor container_adaptor_; | |
const Base & base() const { return dwfb.data; } | |
Base & base() { return dwfb.data; } | |
// Interface -------------------------------------------------------------- | |
public: | |
size_type size() const { return base().size(); } | |
size_type max_size() const { return base().max_size(); } | |
bool empty() const { return base().empty(); } | |
iterator begin() | |
{ | |
return this->template functor<iterator_from_base>()( base().begin() ); | |
} | |
iterator end() | |
{ | |
return this->template functor<iterator_from_base>()( base().end() ); | |
} | |
const_iterator begin() const | |
{ | |
return this->template functor<iterator_from_base>()( base().begin() ); | |
} | |
const_iterator end() const | |
{ | |
return this->template functor<iterator_from_base>()( base().end() ); | |
} | |
iterator erase(iterator pos) | |
{ | |
return this->template functor<iterator_from_base>()( | |
base().erase(this->template functor<iterator_to_base>()(pos)) | |
); | |
} | |
iterator erase(iterator first, iterator last) | |
{ | |
return this->template functor<iterator_from_base>()( | |
base().erase( | |
this->template functor<iterator_to_base>()(first), | |
this->template functor<iterator_to_base>()(last) | |
) | |
); | |
} | |
void clear() | |
{ | |
base().clear(); | |
} | |
template< class InputIterator > | |
void insert(InputIterator iterBegin, InputIterator iterEnd) | |
{ | |
for( ; iterBegin != iterEnd ; ++iterBegin ) | |
{ | |
base().insert( this->template | |
functor<value_to_base>()( *iterBegin ) | |
); | |
} | |
} | |
std::pair<iterator, bool> insert( | |
BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x) | |
{ | |
std::pair< BOOST_DEDUCED_TYPENAME Base::iterator, bool > r( | |
base().insert( this->template functor<value_to_base>()(x) ) | |
); | |
return std::pair<iterator, bool>( this->template | |
functor<iterator_from_base>()(r.first),r.second | |
); | |
} | |
iterator insert(iterator pos, | |
BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x) | |
{ | |
return this->template functor<iterator_from_base>()( | |
base().insert( | |
this->template functor<iterator_to_base>()(pos), | |
this->template functor<value_to_base>()(x)) | |
); | |
} | |
void swap( container_adaptor & c ) | |
{ | |
base().swap( c.base() ); | |
} | |
// Access to functors ---------------------------------------------------- | |
protected: | |
template< class Functor > | |
Functor & functor() | |
{ | |
return dwfb.template functor<Functor>(); | |
} | |
template< class Functor > | |
Functor const & functor() const | |
{ | |
return dwfb.template functor<Functor>(); | |
} | |
// Data ------------------------------------------------------------------ | |
private: | |
::boost::bimaps::container_adaptor::detail::data_with_functor_bag | |
< | |
Base &, | |
BOOST_DEDUCED_TYPENAME mpl::copy | |
< | |
mpl::vector | |
< | |
iterator_to_base, | |
iterator_from_base, | |
value_to_base, | |
value_from_base | |
>, | |
mpl::front_inserter< FunctorsFromDerivedClasses > | |
>::type | |
> dwfb; | |
}; | |
} // namespace container_adaptor | |
} // namespace bimaps | |
} // namespace boost | |
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP |