container.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*=============================================================================
  2. Copyright (c) 2004 Angus Leeming
  3. Copyright (c) 2004 Joel de Guzman
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #ifndef BOOST_PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP
  8. #define BOOST_PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP
  9. #include <utility>
  10. #include <boost/mpl/eval_if.hpp>
  11. #include <boost/type_traits/is_same.hpp>
  12. #include <boost/type_traits/is_const.hpp>
  13. namespace boost { namespace phoenix { namespace stl
  14. {
  15. ///////////////////////////////////////////////////////////////////////////////
  16. //
  17. // Metafunctions "value_type_of", "key_type_of" etc.
  18. //
  19. // These metafunctions define a typedef "type" that returns the nested
  20. // type if it exists. If not then the typedef returns void.
  21. //
  22. // For example, "value_type_of<std::vector<int> >::type" is "int" whilst
  23. // "value_type_of<double>::type" is "void".
  24. //
  25. // I use a macro to define structs "value_type_of" etc simply to cut
  26. // down on the amount of code. The macro is #undef-ed immediately after
  27. // its final use.
  28. //
  29. /////////////////////////////////////////////////////////////////c//////////////
  30. #define MEMBER_TYPE_OF(MEMBER_TYPE) \
  31. template <typename C> \
  32. struct BOOST_PP_CAT(MEMBER_TYPE, _of) \
  33. { \
  34. typedef typename C::MEMBER_TYPE type; \
  35. }
  36. MEMBER_TYPE_OF(allocator_type);
  37. MEMBER_TYPE_OF(const_iterator);
  38. MEMBER_TYPE_OF(const_reference);
  39. MEMBER_TYPE_OF(const_reverse_iterator);
  40. MEMBER_TYPE_OF(container_type);
  41. MEMBER_TYPE_OF(data_type);
  42. MEMBER_TYPE_OF(iterator);
  43. MEMBER_TYPE_OF(key_compare);
  44. MEMBER_TYPE_OF(key_type);
  45. MEMBER_TYPE_OF(reference);
  46. MEMBER_TYPE_OF(reverse_iterator);
  47. MEMBER_TYPE_OF(size_type);
  48. MEMBER_TYPE_OF(value_compare);
  49. MEMBER_TYPE_OF(value_type);
  50. #undef MEMBER_TYPE_OF
  51. ///////////////////////////////////////////////////////////////////////////////
  52. //
  53. // Const-Qualified types.
  54. //
  55. // Many of the stl member functions have const and non-const
  56. // overloaded versions that return distinct types. For example:
  57. //
  58. // iterator begin();
  59. // const_iterator begin() const;
  60. //
  61. // The three class templates defined below,
  62. // const_qualified_reference_of, const_qualified_iterator_of
  63. // and const_qualified_reverse_iterator_of provide a means to extract
  64. // this return type automatically.
  65. //
  66. ///////////////////////////////////////////////////////////////////////////////
  67. template <typename C>
  68. struct const_qualified_reference_of
  69. {
  70. typedef typename
  71. boost::mpl::eval_if_c<
  72. boost::is_const<C>::value
  73. , const_reference_of<C>
  74. , reference_of<C>
  75. >::type
  76. type;
  77. };
  78. template <typename C>
  79. struct const_qualified_iterator_of
  80. {
  81. typedef typename
  82. boost::mpl::eval_if_c<
  83. boost::is_const<C>::value
  84. , const_iterator_of<C>
  85. , iterator_of<C>
  86. >::type
  87. type;
  88. };
  89. template <typename C>
  90. struct const_qualified_reverse_iterator_of
  91. {
  92. typedef typename
  93. boost::mpl::eval_if_c<
  94. boost::is_const<C>::value
  95. , const_reverse_iterator_of<C>
  96. , reverse_iterator_of<C>
  97. >::type
  98. type;
  99. };
  100. ///////////////////////////////////////////////////////////////////////////////
  101. //
  102. // has_mapped_type<C>
  103. //
  104. // Given a container C, determine if it is a map or multimap
  105. // by checking if it has a member type named "mapped_type".
  106. //
  107. ///////////////////////////////////////////////////////////////////////////////
  108. namespace stl_impl
  109. {
  110. struct one { char a[1]; };
  111. struct two { char a[2]; };
  112. template <typename C>
  113. one has_mapped_type(typename C::mapped_type(*)());
  114. template <typename C>
  115. two has_mapped_type(...);
  116. template<typename T>
  117. struct enable_if_is_void
  118. {};
  119. template<>
  120. struct enable_if_is_void<void>
  121. {
  122. typedef void type;
  123. };
  124. template<typename T>
  125. struct disable_if_is_void
  126. {
  127. typedef T type;
  128. };
  129. template<>
  130. struct disable_if_is_void<void>
  131. {};
  132. }
  133. template <typename C>
  134. struct has_mapped_type
  135. : boost::mpl::bool_<
  136. sizeof(stl_impl::has_mapped_type<C>(0)) == sizeof(stl_impl::one)
  137. >
  138. {};
  139. ///////////////////////////////////////////////////////////////////////////////
  140. //
  141. // map_insert_returns_pair<C>
  142. //
  143. // Distinguish a map from a multimap by checking the return type
  144. // of its "insert" member function. A map returns a pair while
  145. // a multimap returns an iterator.
  146. //
  147. ///////////////////////////////////////////////////////////////////////////////
  148. namespace stl_impl
  149. {
  150. // Cool implementation of map_insert_returns_pair by Daniel Wallin.
  151. // Thanks Daniel!!! I owe you a Pizza!
  152. template<class A, class B>
  153. one map_insert_returns_pair_check(std::pair<A,B> const&);
  154. template <typename T>
  155. two map_insert_returns_pair_check(T const&);
  156. template <typename C>
  157. struct map_insert_returns_pair
  158. {
  159. static typename C::value_type const& get;
  160. BOOST_STATIC_CONSTANT(int,
  161. value = sizeof(
  162. map_insert_returns_pair_check(((C*)0)->insert(get))));
  163. typedef boost::mpl::bool_<value == sizeof(one)> type;
  164. };
  165. }
  166. template <typename C>
  167. struct map_insert_returns_pair
  168. : stl_impl::map_insert_returns_pair<C>::type {};
  169. }}} // namespace boost::phoenix::stl
  170. #endif // BOOST_PHOENIX_STL_CONTAINER_TRAITS_HPP