Boost C++ Libraries Boost.Bimap Home Libraries People FAQ More

PrevUpHomeNext

container_adaptor.hpp

Go to the documentation of this file.
00001 // Boost.Bimap
00002 //
00003 // Copyright (c) 2006-2007 Matias Capeletto
00004 //
00005 // Distributed under the Boost Software License, Version 1.0.
00006 // (See accompanying file LICENSE_1_0.txt or copy at
00007 // http://www.boost.org/LICENSE_1_0.txt)
00008 
00009 /// \file container_adaptor/container_adaptor.hpp
00010 /// \brief Container adaptor to build a type that is compliant to the concept of a container.
00011 
00012 #ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP
00013 #define BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP
00014 
00015 #if defined(_MSC_VER) && (_MSC_VER>=1200)
00016 #pragma once
00017 #endif
00018 
00019 #include <boost/config.hpp>
00020 
00021 #include <utility>
00022 
00023 #include <boost/mpl/if.hpp>
00024 #include <boost/mpl/aux_/na.hpp>
00025 #include <boost/bimap/container_adaptor/detail/identity_converters.hpp>
00026 #include <boost/iterator/iterator_traits.hpp>
00027 
00028 #include <boost/bimap/container_adaptor/detail/functor_bag.hpp>
00029 #include <boost/mpl/vector.hpp>
00030 #include <boost/mpl/copy.hpp>
00031 #include <boost/mpl/front_inserter.hpp>
00032 #include <boost/call_traits.hpp>
00033 
00034 
00035 
00036 namespace boost {
00037 namespace bimaps {
00038 
00039 /// \brief Container Adaptor toolbox, easy way to build new containers from existing ones.
00040 
00041 namespace container_adaptor {
00042 
00043 /// \brief Container adaptor to build a type that is compliant to the concept of a container.
00044 
00045 template
00046 <
00047     class Base,
00048 
00049     class Iterator,
00050     class ConstIterator,
00051 
00052     class IteratorToBaseConverter   = ::boost::mpl::na,
00053     class IteratorFromBaseConverter = ::boost::mpl::na,
00054     class ValueToBaseConverter      = ::boost::mpl::na,
00055     class ValueFromBaseConverter    = ::boost::mpl::na,
00056 
00057     class FunctorsFromDerivedClasses = mpl::vector<>
00058 >
00059 class container_adaptor
00060 {
00061     // MetaData -------------------------------------------------------------
00062 
00063     public:
00064 
00065     typedef Iterator iterator;
00066     typedef ConstIterator const_iterator;
00067 
00068     typedef BOOST_DEDUCED_TYPENAME iterator_value    <       iterator >::type value_type;
00069     typedef BOOST_DEDUCED_TYPENAME iterator_pointer  <       iterator >::type pointer;
00070     typedef BOOST_DEDUCED_TYPENAME iterator_reference<       iterator >::type reference;
00071     typedef BOOST_DEDUCED_TYPENAME iterator_reference< const_iterator >::type const_reference;
00072 
00073     typedef BOOST_DEDUCED_TYPENAME Base::size_type size_type;
00074     typedef BOOST_DEDUCED_TYPENAME Base::difference_type difference_type;
00075 
00076     typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorToBaseConverter>,
00077         // {
00078                 ::boost::bimaps::container_adaptor::detail::
00079                     iterator_to_base_identity
00080                 <
00081                     BOOST_DEDUCED_TYPENAME Base::iterator                , iterator,
00082                     BOOST_DEDUCED_TYPENAME Base::const_iterator          , const_iterator
00083                 >,
00084         // }
00085         // else
00086         // {
00087                 IteratorToBaseConverter
00088         // }
00089 
00090         >::type iterator_to_base;
00091 
00092     typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorFromBaseConverter>,
00093         // {
00094                 ::boost::bimaps::container_adaptor::detail::
00095                     iterator_from_base_identity
00096                 <
00097                     BOOST_DEDUCED_TYPENAME Base::iterator                , iterator,
00098                     BOOST_DEDUCED_TYPENAME Base::const_iterator          , const_iterator
00099                 >,
00100         // }
00101         // else
00102         // {
00103                 IteratorFromBaseConverter
00104         // }
00105 
00106         >::type iterator_from_base;
00107 
00108     typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueToBaseConverter>,
00109         // {
00110                 ::boost::bimaps::container_adaptor::detail::
00111                     value_to_base_identity
00112                 <
00113                     BOOST_DEDUCED_TYPENAME Base::value_type,
00114                     value_type
00115                 >,
00116         // }
00117         // else
00118         // {
00119                 ValueToBaseConverter
00120         // }
00121 
00122         >::type value_to_base;
00123 
00124     typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueFromBaseConverter>,
00125         // {
00126                 ::boost::bimaps::container_adaptor::detail::
00127                     value_from_base_identity
00128                 <
00129                     BOOST_DEDUCED_TYPENAME Base::value_type,
00130                     value_type
00131                 >,
00132         // }
00133         // else
00134         // {
00135                 ValueFromBaseConverter
00136         // }
00137 
00138         >::type value_from_base;
00139 
00140     // ACCESS -----------------------------------------------------------------
00141 
00142     public:
00143 
00144     explicit container_adaptor(Base & c) : dwfb(c) {}
00145 
00146     protected:
00147 
00148     typedef Base base_type;
00149 
00150     typedef container_adaptor container_adaptor_;
00151 
00152     const Base & base() const { return dwfb.data; }
00153           Base & base()       { return dwfb.data; }
00154 
00155     // Interface --------------------------------------------------------------
00156 
00157     public:
00158 
00159     size_type size() const                    { return base().size();         }
00160     size_type max_size() const                { return base().max_size();     }
00161     bool empty() const                        { return base().empty();        }
00162 
00163     iterator begin()
00164     {
00165         return this->template functor<iterator_from_base>()( base().begin() );
00166     }
00167 
00168     iterator end()
00169     {
00170         return this->template functor<iterator_from_base>()( base().end() );
00171     }
00172 
00173     const_iterator begin() const
00174     {
00175         return this->template functor<iterator_from_base>()( base().begin() );
00176     }
00177 
00178     const_iterator end() const
00179     {
00180         return this->template functor<iterator_from_base>()( base().end() );
00181     }
00182 
00183 
00184     iterator erase(iterator pos)
00185     {
00186         return this->template functor<iterator_from_base>()(
00187             base().erase(this->template functor<iterator_to_base>()(pos))
00188         );
00189     }
00190 
00191     iterator erase(iterator first, iterator last)
00192     {
00193         return this->template functor<iterator_from_base>()(
00194             base().erase(
00195                 this->template functor<iterator_to_base>()(first),
00196                 this->template functor<iterator_to_base>()(last)
00197             )
00198         );
00199     }
00200 
00201     void clear()
00202     {
00203         base().clear();
00204     }
00205 
00206     template< class InputIterator >
00207     void insert(InputIterator iterBegin, InputIterator iterEnd)
00208     {
00209         for( ; iterBegin != iterEnd ; ++iterBegin )
00210         {
00211             base().insert( this->template
00212                 functor<value_to_base>()( *iterBegin )
00213             );
00214         }
00215     }
00216 
00217     std::pair<iterator, bool> insert(
00218         BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x)
00219     {
00220         std::pair< BOOST_DEDUCED_TYPENAME Base::iterator, bool > r(
00221             base().insert( this->template functor<value_to_base>()(x) )
00222         );
00223 
00224         return std::pair<iterator, bool>( this->template
00225                     functor<iterator_from_base>()(r.first),r.second
00226                );
00227     }
00228 
00229     iterator insert(iterator pos,
00230                     BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x)
00231     {
00232         return this->template functor<iterator_from_base>()(
00233             base().insert(
00234                 this->template functor<iterator_to_base>()(pos),
00235                 this->template functor<value_to_base>()(x))
00236         );
00237     }
00238 
00239     // Access to functors ----------------------------------------------------
00240 
00241     protected:
00242 
00243     template< class Functor >
00244     Functor & functor()
00245     {
00246         return dwfb.template functor<Functor>();
00247     }
00248 
00249     template< class Functor >
00250     Functor const & functor() const
00251     {
00252         return dwfb.template functor<Functor>();
00253     }
00254 
00255     // Data ------------------------------------------------------------------
00256 
00257     private:
00258 
00259     ::boost::bimaps::container_adaptor::detail::data_with_functor_bag
00260     <
00261         Base &,
00262 
00263         BOOST_DEDUCED_TYPENAME mpl::copy
00264         <
00265             mpl::vector
00266             <
00267                 iterator_to_base,
00268                 iterator_from_base,
00269                 value_to_base,
00270                 value_from_base
00271             >,
00272 
00273             mpl::front_inserter< FunctorsFromDerivedClasses >
00274 
00275         >::type
00276 
00277     > dwfb;
00278 };
00279 
00280 
00281 } // namespace container_adaptor
00282 } // namespace bimaps
00283 } // namespace boost
00284 
00285 
00286 #endif // BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP
Copyright 2006 Matias Capeletto

PrevUpHomeNext