summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/example/tutorial/type.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/example/tutorial/type.cpp')
-rw-r--r--src/boost/libs/hana/example/tutorial/type.cpp260
1 files changed, 260 insertions, 0 deletions
diff --git a/src/boost/libs/hana/example/tutorial/type.cpp b/src/boost/libs/hana/example/tutorial/type.cpp
new file mode 100644
index 000000000..92010d499
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/type.cpp
@@ -0,0 +1,260 @@
+// 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_]
+}