]>
Commit | Line | Data |
---|---|---|
b32b8144 | 1 | // Copyright Louis Dionne 2013-2017 |
7c673cae FG |
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 | //! [additional_setup] | |
11 | #include <cassert> | |
12 | #include <iostream> | |
13 | #include <string> | |
14 | ||
15 | struct Fish { std::string name; }; | |
16 | struct Cat { std::string name; }; | |
17 | struct Dog { std::string name; }; | |
18 | //! [additional_setup] | |
19 | ||
20 | //! [includes] | |
21 | #include <boost/hana.hpp> | |
22 | namespace hana = boost::hana; | |
23 | //! [includes] | |
24 | ||
25 | ||
26 | int main() { | |
27 | ||
28 | //! [animals] | |
29 | auto animals = hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"}); | |
30 | //! [animals] | |
31 | ||
32 | //! [algorithms] | |
33 | using namespace hana::literals; | |
34 | ||
35 | // Access tuple elements with operator[] instead of std::get. | |
36 | Cat garfield = animals[1_c]; | |
37 | ||
38 | // Perform high level algorithms on tuples (this is like std::transform) | |
39 | auto names = hana::transform(animals, [](auto a) { | |
40 | return a.name; | |
41 | }); | |
42 | ||
43 | assert(hana::reverse(names) == hana::make_tuple("Snoopy", "Garfield", "Nemo")); | |
44 | //! [algorithms] | |
45 | ||
46 | ||
47 | //! [type-level] | |
48 | auto animal_types = hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Cat&>, hana::type_c<Dog>); | |
49 | ||
50 | auto no_pointers = hana::remove_if(animal_types, [](auto a) { | |
51 | return hana::traits::is_pointer(a); | |
52 | }); | |
53 | ||
54 | static_assert(no_pointers == hana::make_tuple(hana::type_c<Cat&>, hana::type_c<Dog>), ""); | |
55 | //! [type-level] | |
56 | ||
57 | ||
58 | //! [has_name] | |
59 | auto has_name = hana::is_valid([](auto&& x) -> decltype((void)x.name) { }); | |
60 | ||
61 | static_assert(has_name(garfield), ""); | |
62 | static_assert(!has_name(1), ""); | |
63 | //! [has_name] | |
64 | ||
65 | #if 0 | |
66 | //! [screw_up] | |
67 | auto serialize = [](std::ostream& os, auto const& object) { | |
68 | hana::for_each(os, [&](auto member) { | |
69 | // ^^ oopsie daisy! | |
70 | os << member << std::endl; | |
71 | }); | |
72 | }; | |
73 | //! [screw_up] | |
74 | #endif | |
75 | ||
76 | //! [serialization] | |
77 | // 1. Give introspection capabilities to 'Person' | |
78 | struct Person { | |
79 | BOOST_HANA_DEFINE_STRUCT(Person, | |
80 | (std::string, name), | |
81 | (int, age) | |
82 | ); | |
83 | }; | |
84 | ||
85 | // 2. Write a generic serializer (bear with std::ostream for the example) | |
86 | auto serialize = [](std::ostream& os, auto const& object) { | |
87 | hana::for_each(hana::members(object), [&](auto member) { | |
88 | os << member << std::endl; | |
89 | }); | |
90 | }; | |
91 | ||
92 | // 3. Use it | |
93 | Person john{"John", 30}; | |
94 | serialize(std::cout, john); | |
95 | ||
96 | // output: | |
97 | // John | |
98 | // 30 | |
99 | //! [serialization] | |
100 | ||
101 | } |