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 
5 // Make sure assert always triggers an assertion
6 #ifdef NDEBUG
7 #   undef NDEBUG
8 #endif
9 
10 //////////////////////////////////////////////////////////////////////////////
11 // Important: Keep this file in sync with the Overview in the README
12 //////////////////////////////////////////////////////////////////////////////
13 #include <boost/hana.hpp>
14 #include <cassert>
15 #include <string>
16 namespace hana = boost::hana;
17 using namespace hana::literals;
18 
19 struct Fish { std::string name; };
20 struct Cat  { std::string name; };
21 struct Dog  { std::string name; };
22 
main()23 int main() {
24   // Sequences capable of holding heterogeneous objects, and algorithms
25   // to manipulate them.
26   auto animals = hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});
27   auto names = hana::transform(animals, [](auto a) {
28     return a.name;
29   });
30   assert(hana::reverse(names) == hana::make_tuple("Snoopy", "Garfield", "Nemo"));
31 
32   // No compile-time information is lost: even if `animals` can't be a
33   // constant expression because it contains strings, its length is constexpr.
34   static_assert(hana::length(animals) == 3u, "");
35 
36   // Computations on types can be performed with the same syntax as that of
37   // normal C++. Believe it or not, everything is done at compile-time.
38   auto animal_types = hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Cat&>, hana::type_c<Dog*>);
39   auto animal_ptrs = hana::filter(animal_types, [](auto a) {
40     return hana::traits::is_pointer(a);
41   });
42   static_assert(animal_ptrs == hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Dog*>), "");
43 
44   // And many other goodies to make your life easier, including:
45   // 1. Access to elements in a tuple with a sane syntax.
46   static_assert(animal_ptrs[0_c] == hana::type_c<Fish*>, "");
47   static_assert(animal_ptrs[1_c] == hana::type_c<Dog*>, "");
48 
49   // 2. Unroll loops at compile-time without hassle.
50   std::string s;
51   hana::int_c<10>.times([&]{ s += "x"; });
52   // equivalent to s += "x"; s += "x"; ... s += "x";
53 
54   // 3. Easily check whether an expression is valid.
55   //    This is usually achieved with complex SFINAE-based tricks.
56   auto has_name = hana::is_valid([](auto&& x) -> decltype((void)x.name) { });
57   static_assert(has_name(animals[0_c]), "");
58   static_assert(!has_name(1), "");
59 }
60