type.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // Copyright Louis Dionne 2013-2017
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  4. #include <boost/hana.hpp>
  5. #include <boost/hana/ext/std/integral_constant.hpp>
  6. #include <boost/mpl/copy_if.hpp>
  7. #include <boost/mpl/equal.hpp>
  8. #include <boost/mpl/less.hpp>
  9. #include <boost/mpl/min_element.hpp>
  10. #include <boost/mpl/or.hpp>
  11. #include <boost/mpl/placeholders.hpp>
  12. #include <boost/mpl/sizeof.hpp>
  13. #include <boost/mpl/vector.hpp>
  14. #include <boost/fusion/include/at_key.hpp>
  15. #include <boost/fusion/include/equal_to.hpp>
  16. #include <boost/fusion/include/filter_if.hpp>
  17. #include <boost/fusion/include/make_map.hpp>
  18. #include <boost/fusion/include/make_vector.hpp>
  19. #include <string>
  20. #include <type_traits>
  21. #include <vector>
  22. namespace fusion = boost::fusion;
  23. namespace mpl = boost::mpl;
  24. namespace hana = boost::hana;
  25. using namespace hana::literals;
  26. template <int n>
  27. struct storage { char weight[n]; };
  28. int main() {
  29. {
  30. //! [tuple]
  31. auto types = hana::make_tuple(hana::type_c<int*>, hana::type_c<char&>, hana::type_c<void>);
  32. auto char_ref = types[1_c];
  33. BOOST_HANA_CONSTANT_CHECK(char_ref == hana::type_c<char&>);
  34. //! [tuple]
  35. }{
  36. //! [filter.MPL]
  37. using types = mpl::vector<int, char&, void*>;
  38. using ts = mpl::copy_if<types, mpl::or_<std::is_pointer<mpl::_1>,
  39. std::is_reference<mpl::_1>>>::type;
  40. // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  41. // placeholder expression
  42. static_assert(mpl::equal<ts, mpl::vector<char&, void*>>::value, "");
  43. //! [filter.MPL]
  44. }{
  45. using hana::traits::is_pointer; // the traits namespace was not introduced
  46. using hana::traits::is_reference; // yet, so we use unqualified names for now
  47. //! [filter.Hana]
  48. auto types = hana::tuple_t<int*, char&, void>;
  49. auto ts = hana::filter(types, [](auto t) {
  50. return is_pointer(t) || is_reference(t);
  51. });
  52. BOOST_HANA_CONSTANT_CHECK(ts == hana::tuple_t<int*, char&>);
  53. //! [filter.Hana]
  54. }{
  55. //! [single_library.then]
  56. // types (MPL)
  57. using types = mpl::vector<int*, char&, void>;
  58. using ts = mpl::copy_if<types, mpl::or_<std::is_pointer<mpl::_1>,
  59. std::is_reference<mpl::_1>>>::type;
  60. // values (Fusion)
  61. auto values = fusion::make_vector(1, 'c', nullptr, 3.5);
  62. auto vs = fusion::filter_if<std::is_integral<mpl::_1>>(values);
  63. //! [single_library.then]
  64. static_assert(mpl::equal<ts, mpl::vector<int*, char&>>::value, "");
  65. BOOST_HANA_RUNTIME_CHECK(vs == fusion::make_vector(1, 'c'));
  66. }{
  67. using hana::traits::is_pointer;
  68. using hana::traits::is_reference;
  69. using hana::traits::is_integral;
  70. //! [single_library.Hana]
  71. // types
  72. auto types = hana::tuple_t<int*, char&, void>;
  73. auto ts = hana::filter(types, [](auto t) {
  74. return is_pointer(t) || is_reference(t);
  75. });
  76. // values
  77. auto values = hana::make_tuple(1, 'c', nullptr, 3.5);
  78. auto vs = hana::filter(values, [](auto const& t) {
  79. return is_integral(hana::typeid_(t));
  80. });
  81. //! [single_library.Hana]
  82. BOOST_HANA_CONSTANT_CHECK(ts == hana::tuple_t<int*, char&>);
  83. BOOST_HANA_RUNTIME_CHECK(vs == hana::make_tuple(1, 'c'));
  84. }{
  85. //! [make_map.Fusion]
  86. auto map = fusion::make_map<char, int, long, float, double, void>(
  87. "char", "int", "long", "float", "double", "void"
  88. );
  89. std::string Int = fusion::at_key<int>(map);
  90. BOOST_HANA_RUNTIME_CHECK(Int == "int");
  91. //! [make_map.Fusion]
  92. }{
  93. //! [make_map.Hana]
  94. auto map = hana::make_map(
  95. hana::make_pair(hana::type_c<char>, "char"),
  96. hana::make_pair(hana::type_c<int>, "int"),
  97. hana::make_pair(hana::type_c<long>, "long"),
  98. hana::make_pair(hana::type_c<float>, "float"),
  99. hana::make_pair(hana::type_c<double>, "double")
  100. );
  101. std::string Int = map[hana::type_c<int>];
  102. BOOST_HANA_RUNTIME_CHECK(Int == "int");
  103. //! [make_map.Hana]
  104. }{
  105. using hana::traits::add_pointer;
  106. //! [skip_first_step]
  107. auto types = hana::tuple_t<int*, char&, void>; // first step skipped
  108. auto pointers = hana::transform(types, [](auto t) {
  109. return add_pointer(t);
  110. });
  111. //! [skip_first_step]
  112. BOOST_HANA_CONSTANT_CHECK(pointers == hana::tuple_t<int**, char*, void*>);
  113. }{
  114. //! [traits]
  115. BOOST_HANA_CONSTANT_CHECK(hana::traits::add_pointer(hana::type_c<int>) == hana::type_c<int*>);
  116. BOOST_HANA_CONSTANT_CHECK(hana::traits::common_type(hana::type_c<int>, hana::type_c<long>) == hana::type_c<long>);
  117. BOOST_HANA_CONSTANT_CHECK(hana::traits::is_integral(hana::type_c<int>));
  118. auto types = hana::tuple_t<int, char, long>;
  119. BOOST_HANA_CONSTANT_CHECK(hana::all_of(types, hana::traits::is_integral));
  120. //! [traits]
  121. }{
  122. //! [extent]
  123. auto extent = [](auto t, auto n) {
  124. return std::extent<typename decltype(t)::type, hana::value(n)>{};
  125. };
  126. BOOST_HANA_CONSTANT_CHECK(extent(hana::type_c<char>, hana::int_c<1>) == hana::size_c<0>);
  127. BOOST_HANA_CONSTANT_CHECK(extent(hana::type_c<char[1][2]>, hana::int_c<1>) == hana::size_c<2>);
  128. //! [extent]
  129. }
  130. }
  131. namespace mpl_based {
  132. //! [smallest.MPL]
  133. template <typename ...T>
  134. struct smallest
  135. : mpl::deref<
  136. typename mpl::min_element<
  137. mpl::vector<T...>,
  138. mpl::less<mpl::sizeof_<mpl::_1>, mpl::sizeof_<mpl::_2>>
  139. >::type
  140. >
  141. { };
  142. template <typename ...T>
  143. using smallest_t = typename smallest<T...>::type;
  144. static_assert(std::is_same<
  145. smallest_t<char, long, long double>,
  146. char
  147. >::value, "");
  148. //! [smallest.MPL]
  149. static_assert(std::is_same<
  150. smallest_t<storage<3>, storage<1>, storage<2>>,
  151. storage<1>
  152. >::value, "");
  153. } // end namespace mpl_based
  154. namespace hana_based {
  155. //! [smallest.Hana]
  156. template <typename ...T>
  157. auto smallest = hana::minimum(hana::make_tuple(hana::type_c<T>...), [](auto t, auto u) {
  158. return hana::sizeof_(t) < hana::sizeof_(u);
  159. });
  160. template <typename ...T>
  161. using smallest_t = typename decltype(smallest<T...>)::type;
  162. static_assert(std::is_same<
  163. smallest_t<char, long, long double>, char
  164. >::value, "");
  165. //! [smallest.Hana]
  166. static_assert(std::is_same<
  167. smallest_t<storage<3>, storage<1>, storage<2>>,
  168. storage<1>
  169. >::value, "");
  170. } // end namespace hana_based
  171. namespace metafunction1 {
  172. //! [metafunction1]
  173. template <template <typename> class F, typename T>
  174. constexpr auto metafunction(hana::basic_type<T> const&)
  175. { return hana::type_c<typename F<T>::type>; }
  176. auto t = hana::type_c<int>;
  177. BOOST_HANA_CONSTANT_CHECK(metafunction<std::add_pointer>(t) == hana::type_c<int*>);
  178. //! [metafunction1]
  179. }
  180. namespace metafunction2 {
  181. //! [metafunction2]
  182. template <template <typename ...> class F, typename ...T>
  183. constexpr auto metafunction(hana::basic_type<T> const& ...)
  184. { return hana::type_c<typename F<T...>::type>; }
  185. BOOST_HANA_CONSTANT_CHECK(
  186. metafunction<std::common_type>(hana::type_c<int>, hana::type_c<long>) == hana::type_c<long>
  187. );
  188. //! [metafunction2]
  189. }
  190. namespace _template {
  191. //! [template_]
  192. template <template <typename ...> class F, typename ...T>
  193. constexpr auto template_(hana::basic_type<T> const& ...)
  194. { return hana::type_c<F<T...>>; }
  195. BOOST_HANA_CONSTANT_CHECK(
  196. template_<std::vector>(hana::type_c<int>) == hana::type_c<std::vector<int>>
  197. );
  198. //! [template_]
  199. }