container_adaptor.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // Boost.Bimap
  2. //
  3. // Copyright (c) 2006-2007 Matias Capeletto
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. /// \file container_adaptor/container_adaptor.hpp
  9. /// \brief Container adaptor to build a type that is compliant to the concept of a container.
  10. #ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP
  11. #define BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP
  12. #if defined(_MSC_VER)
  13. #pragma once
  14. #endif
  15. #include <boost/config.hpp>
  16. #include <utility>
  17. #include <boost/mpl/if.hpp>
  18. #include <boost/mpl/aux_/na.hpp>
  19. #include <boost/bimap/container_adaptor/detail/identity_converters.hpp>
  20. #include <boost/iterator/iterator_traits.hpp>
  21. #include <boost/bimap/container_adaptor/detail/functor_bag.hpp>
  22. #include <boost/mpl/vector.hpp>
  23. #include <boost/mpl/copy.hpp>
  24. #include <boost/mpl/front_inserter.hpp>
  25. #include <boost/call_traits.hpp>
  26. namespace boost {
  27. namespace bimaps {
  28. /// \brief Container Adaptor toolbox, easy way to build new containers from existing ones.
  29. namespace container_adaptor {
  30. /// \brief Container adaptor to build a type that is compliant to the concept of a container.
  31. template
  32. <
  33. class Base,
  34. class Iterator,
  35. class ConstIterator,
  36. class IteratorToBaseConverter = ::boost::mpl::na,
  37. class IteratorFromBaseConverter = ::boost::mpl::na,
  38. class ValueToBaseConverter = ::boost::mpl::na,
  39. class ValueFromBaseConverter = ::boost::mpl::na,
  40. class FunctorsFromDerivedClasses = mpl::vector<>
  41. >
  42. class container_adaptor
  43. {
  44. // MetaData -------------------------------------------------------------
  45. public:
  46. typedef Iterator iterator;
  47. typedef ConstIterator const_iterator;
  48. typedef BOOST_DEDUCED_TYPENAME iterator_value < iterator >::type value_type;
  49. typedef BOOST_DEDUCED_TYPENAME iterator_pointer < iterator >::type pointer;
  50. typedef BOOST_DEDUCED_TYPENAME iterator_reference< iterator >::type reference;
  51. typedef BOOST_DEDUCED_TYPENAME iterator_reference< const_iterator >::type const_reference;
  52. typedef BOOST_DEDUCED_TYPENAME Base::size_type size_type;
  53. typedef BOOST_DEDUCED_TYPENAME Base::difference_type difference_type;
  54. typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorToBaseConverter>,
  55. // {
  56. ::boost::bimaps::container_adaptor::detail::
  57. iterator_to_base_identity
  58. <
  59. BOOST_DEDUCED_TYPENAME Base::iterator , iterator,
  60. BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator
  61. >,
  62. // }
  63. // else
  64. // {
  65. IteratorToBaseConverter
  66. // }
  67. >::type iterator_to_base;
  68. typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorFromBaseConverter>,
  69. // {
  70. ::boost::bimaps::container_adaptor::detail::
  71. iterator_from_base_identity
  72. <
  73. BOOST_DEDUCED_TYPENAME Base::iterator , iterator,
  74. BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator
  75. >,
  76. // }
  77. // else
  78. // {
  79. IteratorFromBaseConverter
  80. // }
  81. >::type iterator_from_base;
  82. typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueToBaseConverter>,
  83. // {
  84. ::boost::bimaps::container_adaptor::detail::
  85. value_to_base_identity
  86. <
  87. BOOST_DEDUCED_TYPENAME Base::value_type,
  88. value_type
  89. >,
  90. // }
  91. // else
  92. // {
  93. ValueToBaseConverter
  94. // }
  95. >::type value_to_base;
  96. typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueFromBaseConverter>,
  97. // {
  98. ::boost::bimaps::container_adaptor::detail::
  99. value_from_base_identity
  100. <
  101. BOOST_DEDUCED_TYPENAME Base::value_type,
  102. value_type
  103. >,
  104. // }
  105. // else
  106. // {
  107. ValueFromBaseConverter
  108. // }
  109. >::type value_from_base;
  110. // ACCESS -----------------------------------------------------------------
  111. public:
  112. explicit container_adaptor(Base & c) : dwfb(c) {}
  113. protected:
  114. typedef Base base_type;
  115. typedef container_adaptor container_adaptor_;
  116. const Base & base() const { return dwfb.data; }
  117. Base & base() { return dwfb.data; }
  118. // Interface --------------------------------------------------------------
  119. public:
  120. size_type size() const { return base().size(); }
  121. size_type max_size() const { return base().max_size(); }
  122. bool empty() const { return base().empty(); }
  123. iterator begin()
  124. {
  125. return this->template functor<iterator_from_base>()( base().begin() );
  126. }
  127. iterator end()
  128. {
  129. return this->template functor<iterator_from_base>()( base().end() );
  130. }
  131. const_iterator begin() const
  132. {
  133. return this->template functor<iterator_from_base>()( base().begin() );
  134. }
  135. const_iterator end() const
  136. {
  137. return this->template functor<iterator_from_base>()( base().end() );
  138. }
  139. iterator erase(iterator pos)
  140. {
  141. return this->template functor<iterator_from_base>()(
  142. base().erase(this->template functor<iterator_to_base>()(pos))
  143. );
  144. }
  145. iterator erase(iterator first, iterator last)
  146. {
  147. return this->template functor<iterator_from_base>()(
  148. base().erase(
  149. this->template functor<iterator_to_base>()(first),
  150. this->template functor<iterator_to_base>()(last)
  151. )
  152. );
  153. }
  154. void clear()
  155. {
  156. base().clear();
  157. }
  158. template< class InputIterator >
  159. void insert(InputIterator iterBegin, InputIterator iterEnd)
  160. {
  161. for( ; iterBegin != iterEnd ; ++iterBegin )
  162. {
  163. base().insert( this->template
  164. functor<value_to_base>()( *iterBegin )
  165. );
  166. }
  167. }
  168. std::pair<iterator, bool> insert(
  169. BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x)
  170. {
  171. std::pair< BOOST_DEDUCED_TYPENAME Base::iterator, bool > r(
  172. base().insert( this->template functor<value_to_base>()(x) )
  173. );
  174. return std::pair<iterator, bool>( this->template
  175. functor<iterator_from_base>()(r.first),r.second
  176. );
  177. }
  178. iterator insert(iterator pos,
  179. BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x)
  180. {
  181. return this->template functor<iterator_from_base>()(
  182. base().insert(
  183. this->template functor<iterator_to_base>()(pos),
  184. this->template functor<value_to_base>()(x))
  185. );
  186. }
  187. void swap( container_adaptor & c )
  188. {
  189. base().swap( c.base() );
  190. }
  191. // Access to functors ----------------------------------------------------
  192. protected:
  193. template< class Functor >
  194. Functor & functor()
  195. {
  196. return dwfb.template functor<Functor>();
  197. }
  198. template< class Functor >
  199. Functor const & functor() const
  200. {
  201. return dwfb.template functor<Functor>();
  202. }
  203. // Data ------------------------------------------------------------------
  204. private:
  205. ::boost::bimaps::container_adaptor::detail::data_with_functor_bag
  206. <
  207. Base &,
  208. BOOST_DEDUCED_TYPENAME mpl::copy
  209. <
  210. mpl::vector
  211. <
  212. iterator_to_base,
  213. iterator_from_base,
  214. value_to_base,
  215. value_from_base
  216. >,
  217. mpl::front_inserter< FunctorsFromDerivedClasses >
  218. >::type
  219. > dwfb;
  220. };
  221. } // namespace container_adaptor
  222. } // namespace bimaps
  223. } // namespace boost
  224. #endif // BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP