123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- // Copyright Louis Dionne 2013-2017
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
- #include <boost/hana.hpp>
- #include <boost/hana/ext/std/integral_constant.hpp>
- #include <boost/mpl/copy_if.hpp>
- #include <boost/mpl/equal.hpp>
- #include <boost/mpl/less.hpp>
- #include <boost/mpl/min_element.hpp>
- #include <boost/mpl/or.hpp>
- #include <boost/mpl/placeholders.hpp>
- #include <boost/mpl/sizeof.hpp>
- #include <boost/mpl/vector.hpp>
- #include <boost/fusion/include/at_key.hpp>
- #include <boost/fusion/include/equal_to.hpp>
- #include <boost/fusion/include/filter_if.hpp>
- #include <boost/fusion/include/make_map.hpp>
- #include <boost/fusion/include/make_vector.hpp>
- #include <string>
- #include <type_traits>
- #include <vector>
- namespace fusion = boost::fusion;
- namespace mpl = boost::mpl;
- namespace hana = boost::hana;
- using namespace hana::literals;
- template <int n>
- struct storage { char weight[n]; };
- int main() {
- {
- //! [tuple]
- auto types = hana::make_tuple(hana::type_c<int*>, hana::type_c<char&>, hana::type_c<void>);
- auto char_ref = types[1_c];
- BOOST_HANA_CONSTANT_CHECK(char_ref == hana::type_c<char&>);
- //! [tuple]
- }{
- //! [filter.MPL]
- using types = mpl::vector<int, char&, void*>;
- using ts = mpl::copy_if<types, mpl::or_<std::is_pointer<mpl::_1>,
- std::is_reference<mpl::_1>>>::type;
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // placeholder expression
- static_assert(mpl::equal<ts, mpl::vector<char&, void*>>::value, "");
- //! [filter.MPL]
- }{
- using hana::traits::is_pointer; // the traits namespace was not introduced
- using hana::traits::is_reference; // yet, so we use unqualified names for now
- //! [filter.Hana]
- auto types = hana::tuple_t<int*, char&, void>;
- auto ts = hana::filter(types, [](auto t) {
- return is_pointer(t) || is_reference(t);
- });
- BOOST_HANA_CONSTANT_CHECK(ts == hana::tuple_t<int*, char&>);
- //! [filter.Hana]
- }{
- //! [single_library.then]
- // types (MPL)
- using types = mpl::vector<int*, char&, void>;
- using ts = mpl::copy_if<types, mpl::or_<std::is_pointer<mpl::_1>,
- std::is_reference<mpl::_1>>>::type;
- // values (Fusion)
- auto values = fusion::make_vector(1, 'c', nullptr, 3.5);
- auto vs = fusion::filter_if<std::is_integral<mpl::_1>>(values);
- //! [single_library.then]
- static_assert(mpl::equal<ts, mpl::vector<int*, char&>>::value, "");
- BOOST_HANA_RUNTIME_CHECK(vs == fusion::make_vector(1, 'c'));
- }{
- using hana::traits::is_pointer;
- using hana::traits::is_reference;
- using hana::traits::is_integral;
- //! [single_library.Hana]
- // types
- auto types = hana::tuple_t<int*, char&, void>;
- auto ts = hana::filter(types, [](auto t) {
- return is_pointer(t) || is_reference(t);
- });
- // values
- auto values = hana::make_tuple(1, 'c', nullptr, 3.5);
- auto vs = hana::filter(values, [](auto const& t) {
- return is_integral(hana::typeid_(t));
- });
- //! [single_library.Hana]
- BOOST_HANA_CONSTANT_CHECK(ts == hana::tuple_t<int*, char&>);
- BOOST_HANA_RUNTIME_CHECK(vs == hana::make_tuple(1, 'c'));
- }{
- //! [make_map.Fusion]
- auto map = fusion::make_map<char, int, long, float, double, void>(
- "char", "int", "long", "float", "double", "void"
- );
- std::string Int = fusion::at_key<int>(map);
- BOOST_HANA_RUNTIME_CHECK(Int == "int");
- //! [make_map.Fusion]
- }{
- //! [make_map.Hana]
- auto map = hana::make_map(
- hana::make_pair(hana::type_c<char>, "char"),
- hana::make_pair(hana::type_c<int>, "int"),
- hana::make_pair(hana::type_c<long>, "long"),
- hana::make_pair(hana::type_c<float>, "float"),
- hana::make_pair(hana::type_c<double>, "double")
- );
- std::string Int = map[hana::type_c<int>];
- BOOST_HANA_RUNTIME_CHECK(Int == "int");
- //! [make_map.Hana]
- }{
- using hana::traits::add_pointer;
- //! [skip_first_step]
- auto types = hana::tuple_t<int*, char&, void>; // first step skipped
- auto pointers = hana::transform(types, [](auto t) {
- return add_pointer(t);
- });
- //! [skip_first_step]
- BOOST_HANA_CONSTANT_CHECK(pointers == hana::tuple_t<int**, char*, void*>);
- }{
- //! [traits]
- BOOST_HANA_CONSTANT_CHECK(hana::traits::add_pointer(hana::type_c<int>) == hana::type_c<int*>);
- BOOST_HANA_CONSTANT_CHECK(hana::traits::common_type(hana::type_c<int>, hana::type_c<long>) == hana::type_c<long>);
- BOOST_HANA_CONSTANT_CHECK(hana::traits::is_integral(hana::type_c<int>));
- auto types = hana::tuple_t<int, char, long>;
- BOOST_HANA_CONSTANT_CHECK(hana::all_of(types, hana::traits::is_integral));
- //! [traits]
- }{
- //! [extent]
- auto extent = [](auto t, auto n) {
- return std::extent<typename decltype(t)::type, hana::value(n)>{};
- };
- BOOST_HANA_CONSTANT_CHECK(extent(hana::type_c<char>, hana::int_c<1>) == hana::size_c<0>);
- BOOST_HANA_CONSTANT_CHECK(extent(hana::type_c<char[1][2]>, hana::int_c<1>) == hana::size_c<2>);
- //! [extent]
- }
- }
- namespace mpl_based {
- //! [smallest.MPL]
- template <typename ...T>
- struct smallest
- : mpl::deref<
- typename mpl::min_element<
- mpl::vector<T...>,
- mpl::less<mpl::sizeof_<mpl::_1>, mpl::sizeof_<mpl::_2>>
- >::type
- >
- { };
- template <typename ...T>
- using smallest_t = typename smallest<T...>::type;
- static_assert(std::is_same<
- smallest_t<char, long, long double>,
- char
- >::value, "");
- //! [smallest.MPL]
- static_assert(std::is_same<
- smallest_t<storage<3>, storage<1>, storage<2>>,
- storage<1>
- >::value, "");
- } // end namespace mpl_based
- namespace hana_based {
- //! [smallest.Hana]
- template <typename ...T>
- auto smallest = hana::minimum(hana::make_tuple(hana::type_c<T>...), [](auto t, auto u) {
- return hana::sizeof_(t) < hana::sizeof_(u);
- });
- template <typename ...T>
- using smallest_t = typename decltype(smallest<T...>)::type;
- static_assert(std::is_same<
- smallest_t<char, long, long double>, char
- >::value, "");
- //! [smallest.Hana]
- static_assert(std::is_same<
- smallest_t<storage<3>, storage<1>, storage<2>>,
- storage<1>
- >::value, "");
- } // end namespace hana_based
- namespace metafunction1 {
- //! [metafunction1]
- template <template <typename> class F, typename T>
- constexpr auto metafunction(hana::basic_type<T> const&)
- { return hana::type_c<typename F<T>::type>; }
- auto t = hana::type_c<int>;
- BOOST_HANA_CONSTANT_CHECK(metafunction<std::add_pointer>(t) == hana::type_c<int*>);
- //! [metafunction1]
- }
- namespace metafunction2 {
- //! [metafunction2]
- template <template <typename ...> class F, typename ...T>
- constexpr auto metafunction(hana::basic_type<T> const& ...)
- { return hana::type_c<typename F<T...>::type>; }
- BOOST_HANA_CONSTANT_CHECK(
- metafunction<std::common_type>(hana::type_c<int>, hana::type_c<long>) == hana::type_c<long>
- );
- //! [metafunction2]
- }
- namespace _template {
- //! [template_]
- template <template <typename ...> class F, typename ...T>
- constexpr auto template_(hana::basic_type<T> const& ...)
- { return hana::type_c<F<T...>>; }
- BOOST_HANA_CONSTANT_CHECK(
- template_<std::vector>(hana::type_c<int>) == hana::type_c<std::vector<int>>
- );
- //! [template_]
- }
|