]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/doc/tutorial.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / doc / tutorial.hpp
1 // Copyright Louis Dionne 2013-2016
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 /*!
6
7 @mainpage User Manual
8
9 @tableofcontents
10
11
12
13
14
15
16
17
18
19
20 @section tutorial-description Description
21
22 ------------------------------------------------------------------------------
23 Hana is a header-only library for C++ metaprogramming suited for computations
24 on both types and values. The functionality it provides is a superset of what
25 is provided by the well established [Boost.MPL][] and [Boost.Fusion][]
26 libraries. By leveraging C++11/14 implementation techniques and idioms,
27 Hana boasts faster compilation times and runtime performance on par or better
28 than previous metaprogramming libraries, while noticeably increasing the level
29 of expressiveness in the process. Hana is easy to extend in a ad-hoc manner
30 and it provides out-of-the-box inter-operation with Boost.Fusion, Boost.MPL
31 and the standard library.
32
33
34
35
36
37
38
39
40
41
42 @section tutorial-installation Prerequisites and installation
43
44 ------------------------------------------------------------------------------
45 Hana is a header-only library without external dependencies (not even the rest
46 of Boost). Hence, using Hana in your own project is very easy. Basically, just
47 add the `include/` directory to your compiler's header search path and you are
48 done. However, if you want to cleanly install Hana on your system, you have a
49 couple of options. First, you can install Boost 1.61.0 or later, since Hana is
50 included in Boost starting with that release. If you do not want to install all
51 of Boost, it is also possible to install Hana only. To do so, you can download
52 the code from the official GitHub [repository][Hana.repository] and install the
53 library manually by issuing the following commands from the root of the project
54 (requires [CMake][]):
55
56 @code{.sh}
57 mkdir build && cd build
58 cmake ..
59 cmake --build . --target install
60 @endcode
61
62 This will install Hana to the default install-directory for your platform
63 (`/usr/local` for Unix, `C:/Program Files` for Windows). If you want to
64 install Hana in a custom location, you can use
65
66 @code{.sh}
67 cmake .. -DCMAKE_INSTALL_PREFIX=/custom/install/prefix
68 @endcode
69
70 @note
71 - The manual installation will also install a `hana.pc` file for use
72 with [pkg-config][].
73
74 - Do not install Hana as shown above if you already have an installation of
75 Boost, because the new installation will overwrite the one that comes with
76 Boost.
77
78 If you use CMake in a project, you can use the provided [FindHana.cmake][Hana.findmodule]
79 module to setup Hana as an external CMake project. The module also allows
80 installing Hana locally to that project, without needing to install Hana on
81 the system per the above instructions. Finally, if you want to contribute to
82 Hana, you can see how to best setup your environment for development in the
83 [README][Hana.hacking].
84
85 @subsection tutorial-installation-requirements Compiler requirements
86
87 The library relies on a C++14 compiler and standard library, but nothing else
88 is required. Here is a table of the current C++14 compilers/toolchains with
89 comments regarding support for Hana:
90
91 Compiler/Toolchain | Status
92 ------------------ | ------
93 Clang >= 3.5.0 | Fully working; tested on each push to GitHub
94 Xcode >= 6.3 | Fully working; tested on each push to GitHub
95 GCC >= 6.0.0 | Fully working; tested on each push to GitHub
96
97 More specifically, Hana requires a compiler/standard library supporting the
98 following C++14 features (non-exhaustively):
99 - Generic lambdas
100 - Generalized `constexpr`
101 - Variable templates
102 - Automatically deduced return type
103 - All the C++14 type traits from the `<type_traits>` header
104
105 More information for specific platforms is available on [the wiki][Hana.wiki].
106
107
108
109
110
111
112
113
114
115
116 @section tutorial-support Support
117
118 ------------------------------------------------------------------------------
119
120 If you have a problem, please review the [FAQ](@ref tutorial-rationales) and
121 [the wiki][Hana.wiki]. Searching [the issues][Hana.issues] for your problem is
122 also a good idea. If that doesn't help, feel free to chat with us in [Gitter][Hana.chat],
123 or open a new issue. [StackOverflow][] with the [boost-hana][Hana.StackOverflow]
124 tag is the preferred place to ask questions on usage. If you are encountering
125 what you think is a bug, please open an issue.
126
127
128
129
130
131
132
133
134
135
136 @section tutorial-introduction Introduction
137
138 ------------------------------------------------------------------------------
139 When Boost.MPL first appeared, it provided C++ programmers with a huge relief
140 by abstracting tons of template hackery behind a workable interface. This
141 breakthrough greatly contributed to making C++ template metaprogramming more
142 mainstream, and today the discipline is deeply rooted in many serious projects.
143 Recently, C++11 and C++14 brought many major changes to the language, some of
144 which make metaprogramming much easier, while others drastically widen the
145 design space for libraries. A natural question then arises: is it still
146 desirable to have abstractions for metaprogramming, and if so, which ones?
147 After investigating different options like the [MPL11][], the answer eventually
148 came by itself in the form of a library; Hana. The key insight to Hana is that
149 the manipulation of types and values are nothing but two sides of the same
150 coin. By unifying both concepts, metaprogramming becomes easier and new
151 exciting possibilities open before us.
152
153
154 @subsection tutorial-introduction-quadrants C++ computational quadrants
155
156 But to really understand what is Hana all about, it is essential to understand
157 the different types of computations in C++. We will focus our attention on
158 four different kinds of computations, even though a finer grained separation
159 would be possible. First, we have runtime computations, which are the usual
160 computations we use in C++. In that world, we have runtime containers,
161 runtime functions and runtime algorithms:
162
163 @snippet example/tutorial/introduction.cpp runtime
164
165 The usual toolbox for programming within this quadrant is the C++ standard
166 library, which provides reusable algorithms and containers operating at
167 runtime. Since C++11, a second kind of computation is possible: `constexpr`
168 computations. There, we have `constexpr` containers, `constexpr` functions
169 and `constexpr` algorithms:
170
171 @code{cpp}
172 constexpr int factorial(int n) {
173 return n == 0 ? 1 : n * factorial(n - 1);
174 }
175
176 template <typename T, std::size_t N, typename F>
177 constexpr std::array<std::result_of_t<F(T)>, N>
178 transform(std::array<T, N> array, F f) {
179 // ...
180 }
181
182 constexpr std::array<int, 4> ints{{1, 2, 3, 4}};
183 constexpr std::array<int, 4> facts = transform(ints, factorial);
184 static_assert(facts == std::array<int, 4>{{1, 2, 6, 24}}, "");
185 @endcode
186
187 @note
188 For the above code to actually work, `std::array`'s `operator==` would have to
189 be marked `constexpr`, which is not the case (even in C++14).
190
191 Basically, a `constexpr` computation is different from a runtime computation
192 in that it is simple enough to be evaluated (interpreted, really) by the
193 compiler. In general, any function that does not perform anything too
194 _unfriendly_ to the compiler's evaluator (like throwing or allocating memory)
195 can be marked `constexpr` without any further change. This makes `constexpr`
196 computations very similar to runtime computations, except `constexpr`
197 computations are more restricted and they gain the ability to be evaluated
198 at compile-time. Unfortunately, there is no commonly used toolbox for
199 `constexpr`-programming, i.e. there is no widely adopted "standard library"
200 for `constexpr` programming. However, the [Sprout][] library may be worth
201 checking out for those with some interest in `constexpr` computations.
202
203 The third kind of computations are heterogeneous computations. Heterogeneous
204 computations differ from normal computations in that instead of having
205 containers holding homogeneous objects (all objects having the same type),
206 the containers may hold objects with different types. Furthermore, functions
207 in this quadrant of computation are _heterogeneous_ functions, which is a
208 complicated way of talking about template functions. Similarly, we have
209 heterogeneous algorithms that manipulate heterogeneous containers and
210 functions:
211
212 @snippet example/tutorial/introduction.cpp heterogeneous
213
214 If manipulating heterogeneous containers seems overly weird to you, just think
215 of it as glorified `std::tuple` manipulation. In a C++03 world, the go-to
216 library for doing this kind of computation is [Boost.Fusion][], which provides
217 several data structures and algorithms to manipulate heterogeneous collections
218 of data. The fourth and last quadrant of computation that we'll be considering
219 here is the quadrant of type-level computations. In this quadrant, we have
220 type-level containers, type-level functions (usually called metafunctions)
221 and type-level algorithms. Here, everything operates on types: containers hold
222 types and metafunctions take types as arguments and return types as results.
223
224 @snippet example/tutorial/introduction.cpp type-level
225
226 The realm of type-level computations has been explored quite extensively, and
227 the de-facto solution for type-level computations in C++03 is a library named
228 [Boost.MPL][], which provides type-level containers and algorithms. For
229 low-level type transformations, the metafunctions provided by the
230 `<type_traits>` standard header can also be used since C++11.
231
232
233 @subsection tutorial-quadrants-about What is this library about?
234
235 So all is good, but what is this library actually about? Now that we have set
236 the table by clarifying the kinds of computations available to us in C++, the
237 answer might strike you as very simple. __The purpose of Hana is to merge the
238 3rd and the 4th quadrants of computation__. More specifically, Hana is a
239 (long-winded) constructive proof that heterogeneous computations are strictly
240 more powerful than type-level computations, and that we can therefore express
241 any type-level computation by an equivalent heterogeneous computation. This
242 construction is done in two steps. First, Hana is a fully featured library of
243 heterogeneous algorithms and containers, a bit like a modernized Boost.Fusion.
244 Secondly, Hana provides a way of translating any type-level computation into its
245 equivalent heterogeneous computation and back, which allows the full machinery
246 of heterogeneous computations to be reused for type-level computations without
247 any code duplication. Of course, the biggest advantage of this unification is
248 seen by the user, as you will witness by yourself.
249
250
251
252
253
254
255
256
257
258
259 @section tutorial-quickstart Quick start
260
261 ------------------------------------------------------------------------------
262 The goal of this section is to introduce the main concepts of the library
263 from a very high level and at a fairly rapid pace; don't worry if you don't
264 understand everything that's about to be thrown at you. However, this tutorial
265 assumes the reader is already at least _familiar_ with basic metaprogramming
266 and the [C++14 standard][C++14]. First, let's include the library:
267
268 @snippet example/tutorial/quickstart.cpp includes
269
270 Unless specified otherwise, the documentation assumes the above lines to be
271 present before examples and code snippets. Also note that finer grained
272 headers are provided and will be explained in the [Header organization]
273 (@ref tutorial-header_organization) section. For the purpose of the
274 quickstart, let's now include some additional headers and define some
275 lovely animal types that we'll need below:
276
277 @snippet example/tutorial/quickstart.cpp additional_setup
278
279 If you are reading this documentation, chances are you already know
280 `std::tuple` and `std::make_tuple`. Hana provides its own tuple and
281 `make_tuple`:
282
283 @snippet example/tutorial/quickstart.cpp animals
284
285 This creates a tuple, which is like an array, except that it can hold elements
286 with different types. Containers that can hold elements with different types
287 such as this are called heterogeneous containers. While the standard library
288 provides very few operations to manipulate `std::tuple`s, Hana provides several
289 operations and algorithms to manipulate its own tuples:
290
291 @snippet example/tutorial/quickstart.cpp algorithms
292
293 @note
294 `1_c` is a [C++14 user-defined literal][C++14.udl] creating a
295 [compile-time number](@ref tutorial-integral). These user-defined
296 literals are contained in the `boost::hana::literals` namespace,
297 hence the `using` directive.
298
299 Notice how we pass a [C++14 generic lambda][C++14.glambda] to `transform`;
300 this is required because the lambda will first be called with a `Fish`, then
301 a `Cat`, and finally a `Dog`, which all have different types. Hana provides
302 most of the algorithms provided by the C++ standard library, except they work
303 on tuples and related heterogeneous containers instead of `std::vector` &
304 friends. In addition to working with heterogeneous values, Hana makes it
305 possible to perform type-level computations with a natural syntax, all at
306 compile-time and with no overhead whatsoever. This compiles and does just
307 what you would expect:
308
309 @snippet example/tutorial/quickstart.cpp type-level
310
311 @note
312 `type_c<...>` is not a type! It is a [C++14 variable template][C++14.vtemplate]
313 yielding an object representing a type for Hana. This is explained in the
314 section on [type computations](@ref tutorial-type).
315
316 In addition to heterogeneous and compile-time sequences, Hana provides several
317 features to make your metaprogramming nightmares a thing of the past. For
318 example, one can check for the existence of a struct member with one easy
319 line instead of relying on [clunky SFINAE hacks][SO.sfinae]:
320
321 @snippet example/tutorial/quickstart.cpp has_name
322
323 Writing a serialization library? Stop crying, we've got you covered.
324 Reflection can be added to user-defined types very easily. This allows
325 iterating over the members of a user-defined type, querying members with
326 a programmatic interface and much more, without any runtime overhead:
327
328 @snippet example/tutorial/quickstart.cpp serialization
329
330 That's cool, but I can already hear you complaining about incomprehensible
331 error messages. However, it turns out Hana was built for humans, not
332 professional template metaprogrammers, and this shows. Let's intentionally
333 screw up and see what kind of mess is thrown at us. First, the mistake:
334
335 @snippet example/tutorial/quickstart.cpp screw_up
336
337 Now, the punishment:
338
339 @code{cpp}
340 error: static_assert failed "hana::for_each(xs, f) requires 'xs' to be Foldable"
341 static_assert(Foldable<S>::value,
342 ^ ~~~~~~~~~~~~~~~~~~
343 note: in instantiation of function template specialization
344 'boost::hana::for_each_t::operator()<
345 std::__1::basic_ostream<char> &, (lambda at [snip])>' requested here
346 hana::for_each(os, [&](auto member) {
347 ^
348 note: in instantiation of function template specialization
349 'main()::(anonymous class)::operator()<Person>' requested here
350 serialize(std::cout, john);
351 ^
352 @endcode
353
354 Not that bad, right? However, since small examples are very good to show off
355 without actually doing something useful, let's examine a real world example.
356
357
358 @subsection tutorial-quickstart-any A real world example
359
360 In this section our goal will be to implement a kind of `switch` statement
361 able to process `boost::any`s. Given a `boost::any`, the goal is to dispatch
362 to the function associated to the dynamic type of the `any`:
363
364 @snippet example/tutorial/quickstart.switchAny.cpp usage
365
366 @note
367 In the documentation, we will often use the `s` suffix on string literals to
368 create `std::string`s without syntactic overhead. This is a standard-defined
369 [C++14 user-defined literal][C++14.udl].
370
371 Since the any holds a `char`, the second function is called with the `char`
372 inside it. If the `any` had held an `int` instead, the first function would
373 have been called with the `int` inside it. When the dynamic type of the `any`
374 does not match any of the covered cases, the `%default_` function is called
375 instead. Finally, the result of the `switch` is the result of calling the
376 function associated to the `any`'s dynamic type. The type of that result is
377 inferred to be the common type of the result of all the provided functions:
378
379 @snippet example/tutorial/quickstart.switchAny.cpp result_inference
380
381 We'll now look at how this utility can be implemented using Hana. The first
382 step is to associate each type to a function. To do so, we represent each
383 `case_` as a `hana::pair` whose first element is a type and whose second
384 element is a function. Furthermore, we (arbitrarily) decide to represent the
385 `%default_` case as a `hana::pair` mapping a dummy type to a function:
386
387 @snippet example/tutorial/quickstart.switchAny.cpp cases
388
389 To provide the interface we showed above, `switch_` will have to return a
390 function taking the cases. In other words, `switch_(a)` must be a function
391 taking any number of cases (which are `hana::pair`s), and performing the logic
392 to dispatch `a` to the right function. This can easily be achieved by having
393 `switch_` return a C++14 generic lambda:
394
395 @code{cpp}
396 template <typename Any>
397 auto switch_(Any& a) {
398 return [&a](auto ...cases_) {
399 // ...
400 };
401 }
402 @endcode
403
404 However, since parameter packs are not very flexible, we'll put the cases
405 into a tuple so we can manipulate them:
406
407 @code{cpp}
408 template <typename Any>
409 auto switch_(Any& a) {
410 return [&a](auto ...cases_) {
411 auto cases = hana::make_tuple(cases_...);
412 // ...
413 };
414 }
415 @endcode
416
417 Notice how the `auto` keyword is used when defining `cases`; it is often
418 easier to let the compiler deduce the type of the tuple and use `make_tuple`
419 instead of working out the types manually. The next step is to separate the
420 default case from the rest of the cases. This is where things start to get
421 interesting. To do so, we use Hana's `find_if` algorithm, which works a bit
422 like `std::find_if`:
423
424 @code{cpp}
425 template <typename Any>
426 auto switch_(Any& a) {
427 return [&a](auto ...cases_) {
428 auto cases = hana::make_tuple(cases_...);
429
430 auto default_ = hana::find_if(cases, [](auto const& c) {
431 return hana::first(c) == hana::type_c<default_t>;
432 });
433
434 // ...
435 };
436 }
437 @endcode
438
439 `find_if` takes a `tuple` and a predicate, and returns the first element of
440 the tuple which satisfies the predicate. The result is returned as a
441 `hana::optional`, which is very similar to a `std::optional`, except
442 whether that optional value is empty or not is known at compile-time. If the
443 predicate is not satisfied for any element of the `tuple`, `find_if` returns
444 `nothing` (an empty value). Otherwise, it returns `just(x)` (a non-empty value),
445 where `x` is the first element satisfying the predicate. Unlike predicates
446 used in STL algorithms, the predicate used here must be generic because the
447 tuple's elements are heterogeneous. Furthermore, that predicate must return
448 what Hana calls an `IntegralConstant`, which means that the predicate's result
449 must be known at compile-time. These details are explained in the section on
450 [cross-phase algorithms](@ref tutorial-algorithms-cross_phase). Inside the
451 predicate, we simply compare the type of the case's first element to
452 `type_c<default_t>`. If you recall that we were using `hana::pair`s to encode
453 cases, this simply means that we're finding the default case among all of the
454 provided cases. But what if no default case was provided? We should fail at
455 compile-time, of course!
456
457 @code{cpp}
458 template <typename Any>
459 auto switch_(Any& a) {
460 return [&a](auto ...cases_) {
461 auto cases = hana::make_tuple(cases_...);
462
463 auto default_ = hana::find_if(cases, [](auto const& c) {
464 return hana::first(c) == hana::type_c<default_t>;
465 });
466 static_assert(default_ != hana::nothing,
467 "switch is missing a default_ case");
468
469 // ...
470 };
471 }
472 @endcode
473
474 Notice how we can use `static_assert` on the result of the comparison with
475 `nothing`, even though `%default_` is a non-`constexpr` object? Boldly, Hana
476 makes sure that no information that's known at compile-time is lost to the
477 runtime, which is clearly the case of the presence of a `%default_` case.
478 The next step is to gather the set of non-default cases. To achieve this, we
479 use the `filter` algorithm, which keeps only the elements of the sequence
480 satisfying the predicate:
481
482 @code{cpp}
483 template <typename Any>
484 auto switch_(Any& a) {
485 return [&a](auto ...cases_) {
486 auto cases = hana::make_tuple(cases_...);
487
488 auto default_ = hana::find_if(cases, [](auto const& c) {
489 return hana::first(c) == hana::type_c<default_t>;
490 });
491 static_assert(default_ != hana::nothing,
492 "switch is missing a default_ case");
493
494 auto rest = hana::filter(cases, [](auto const& c) {
495 return hana::first(c) != hana::type_c<default_t>;
496 });
497
498 // ...
499 };
500 }
501 @endcode
502
503 The next step is to find the first case matching the dynamic type of the `any`,
504 and then call the function associated to that case. The simplest way to do this
505 is to use classic recursion with variadic parameter packs. Of course, we could
506 probably intertwine Hana algorithms in a convoluted way to achieve this, but
507 sometimes the best way to do something is to write it from scratch using basic
508 techniques. To do so, we'll call an implementation function with the contents
509 of the `rest` tuple by using the `unpack` function:
510
511 @snippet example/tutorial/quickstart.switchAny.cpp switch_
512
513 `unpack` takes a `tuple` and a function, and calls the function with the content
514 of the `tuple` as arguments. The result of `unpack` is the result of calling that
515 function. In our case, the function is a generic lambda which in turn calls the
516 `process` function. Our reason for using `unpack` here was to turn the `rest`
517 tuple into a parameter pack of arguments, which are easier to process recursively
518 than tuples. Before we move on to the `process` function, it is worthwhile to
519 explain what `second(*%default_)` is all about. As we explained earlier,
520 `%default_` is an optional value. Like `std::optional`, this optional value
521 overloads the dereference operator (and the arrow operator) to allow accessing
522 the value inside the `optional`. If the optional is empty (`nothing`), a
523 compile-time error is triggered. Since we know `%default_` is not empty (we
524 checked that just above), what we're doing is simply pass the function
525 associated to the default case to the `process` function. We're now ready
526 for the final step, which is the implementation of the `process` function:
527
528 @snippet example/tutorial/quickstart.switchAny.cpp process
529
530 There are two overloads of this function: an overload for when there is at least
531 one case to process, and the base case overload for when there's only the default
532 case. As we would expect, the base case simply calls the default function and
533 returns that result. The other overload is slightly more interesting. First,
534 we retrieve the type associated to that case and store it in `T`. This
535 `decltype(...)::%type` dance might seem convoluted, but it is actually quite
536 simple. Roughly speaking, this takes a type represented as an object (a `type<T>`)
537 and pulls it back down to the type level (a `T`). The details are explained in
538 the section on [type-level computations](@ref tutorial-type). Then, we compare
539 whether the dynamic type of the `any` matches this case, and if so we call the
540 function associated to this case with the `any` casted to the proper type.
541 Otherwise, we simply call `process` recursively with the rest of the cases.
542 Pretty simple, wasn't it? Here's the final solution:
543
544 @snippet example/tutorial/quickstart.switchAny.cpp full
545
546 That's it for the quick start! This example only introduced a couple of useful
547 algorithms (`find_if`, `filter`, `unpack`) and heterogeneous containers
548 (`tuple`, `optional`), but rest assured that there is much more. The next
549 sections of the tutorial gradually introduce general concepts pertaining to
550 Hana in a friendly way, but you may use the following cheatsheet for quick
551 reference if you want to start coding right away. This cheatsheet contains
552 the most frequently used algorithms and containers, along with a short
553 description of what each of them does.
554
555
556 @subsection tutorial-quickstart-cheatsheet Cheatsheet
557
558 ### Remarks
559 - Most algorithms work on both types and values (see the section on
560 [type computations](@ref tutorial-type))
561 - Algorithms always return their result as a new container; no in-place
562 mutation is ever performed (see the section on [algorithms]
563 (@ref tutorial-algorithms))
564 - All algorithms are `constexpr` function objects
565
566
567 container | description
568 :----------------- | :----------
569 <code>[tuple](@ref boost::hana::tuple)</code> | General purpose index-based heterogeneous sequence with a fixed length. Use this as a `std::vector` for heterogeneous objects.
570 <code>[optional](@ref boost::hana::optional)</code> | Represents an optional value, i.e. a value that can be empty. This is a bit like `std::optional`, except that the emptiness is known at compile-time.
571 <code>[map](@ref boost::hana::map)</code> | Unordered associative array mapping (unique) compile-time entities to arbitrary objects. This is like `std::unordered_map` for heterogeneous objects.
572 <code>[set](@ref boost::hana::set)</code> | Unordered container holding unique keys that must be compile-time entities. This is like `std::unordered_set` for heterogeneous objects.
573 <code>[range](@ref boost::hana::range)</code> | Represents an interval of compile-time numbers. This is like `std::integer_sequence`, but better.
574 <code>[pair](@ref boost::hana::pair)</code> | Container holding two heterogeneous objects. Like `std::pair`, but compresses the storage of empty types.
575 <code>[string](@ref boost::hana::string)</code> | Compile-time string.
576 <code>[type](@ref boost::hana::type)</code> | Container representing a C++ type. This is the root of the unification between types and values, and is of interest for MPL-style computations (type-level computations).
577 <code>[integral_constant](@ref boost::hana::integral_constant)</code> | Represents a compile-time number. This is very similar to `std::integral_constant`, except that `hana::integral_constant` also defines operators and more syntactic sugar.
578 <code>[lazy](@ref boost::hana::lazy)</code> | Encapsulates a lazy value or computation.
579 <code>[basic_tuple](@ref boost::hana::basic_tuple)</code> | Stripped-down version of `hana::tuple`. Not standards conforming, but more compile-time efficient.
580
581
582 function | description
583 :------------------------------------------ | :----------
584 <code>[adjust](@ref ::boost::hana::adjust)(sequence, value, f)</code> | Apply a function to each element of a sequence that compares equal to some value and return the result.
585 <code>[adjust_if](@ref ::boost::hana::adjust_if)(sequence, predicate, f)</code> | Apply a function to each element of a sequence satisfying some predicate and return the result.
586 <code>{[all](@ref ::boost::hana::all),[any](@ref ::boost::hana::any),[none](@ref ::boost::hana::none)}(sequence)</code> | Returns whether all/any/none of the elements of a sequence are true-valued.
587 <code>{[all](@ref ::boost::hana::all_of),[any](@ref ::boost::hana::any_of),[none](@ref ::boost::hana::none_of)}_of(sequence, predicate)</code> | Returns whether all/any/none of the elements of the sequence satisfy some predicate.
588 <code>[append](@ref ::boost::hana::append)(sequence, value)</code> | Append an element to a sequence.
589 <code>[at](@ref ::boost::hana::at)(sequence, index)</code> | Returns the n-th element of a sequence. The index must be an `IntegralConstant`.
590 <code>[back](@ref ::boost::hana::back)(sequence)</code> | Returns the last element of a non-empty sequence.
591 <code>[concat](@ref ::boost::hana::concat)(sequence1, sequence2)</code> | Concatenate two sequences.
592 <code>[contains](@ref ::boost::hana::contains)(sequence, value)</code> | Returns whether a sequence contains the given object.
593 <code>[count](@ref ::boost::hana::count)(sequence, value)</code> | Returns the number of elements that compare equal to the given value.
594 <code>[count_if](@ref ::boost::hana::count_if)(sequence, predicate)</code> | Returns the number of elements that satisfy the predicate.
595 <code>[drop_front](@ref ::boost::hana::drop_front)(sequence[, n])</code> | Drop the first `n` elements from a sequence, or the whole sequence if `length(sequence) <= n`. `n` must be an `IntegralConstant`. When not provided, `n` defaults to 1.
596 <code>[drop_front_exactly](@ref ::boost::hana::drop_front_exactly)(sequence[, n])</code> | Drop the first `n` elements from a sequence. `n` must be an `IntegralConstant` and the sequence must have at least `n` elements. When not provided, `n` defaults to 1.
597 <code>[drop_back](@ref ::boost::hana::drop_back)(sequence[, n])</code> | Drop the last `n` elements from a sequence, or the whole sequence if `length(sequence) <= n`. `n` must be an `IntegralConstant`. When not provided, `n` defaults to 1.
598 <code>[drop_while](@ref ::boost::hana::drop_while)(sequence, predicate)</code> | Drops elements from a sequence while a predicate is satisfied. The predicate must return an `IntegralConstant`.
599 <code>[fill](@ref ::boost::hana::fill)(sequence, value)</code> | Replace all the elements of a sequence with some value.
600 <code>[filter](@ref ::boost::hana::filter)(sequence, predicate)</code> | Remove all the elements that do not satisfy a predicate. The predicate must return an `IntegralConstant`.
601 <code>[find](@ref ::boost::hana::find)(sequence, value)</code> | Find the first element of a sequence which compares equal to some value and return `just` it, or return `nothing`. See `hana::optional`.
602 <code>[find_if](@ref ::boost::hana::find_if)(sequence, predicate)</code> | Find the first element of a sequence satisfying the predicate and return `just` it, or return `nothing`. See `hana::optional`.
603 <code>[flatten](@ref ::boost::hana::flatten)(sequence)</code> | Flatten a sequence of sequences, a bit like `std::tuple_cat`.
604 <code>[fold_left](@ref ::boost::hana::fold_left)(sequence[, state], f)</code> | Accumulates the elements of a sequence from the left, optionally with a provided initial state.
605 <code>[fold_right](@ref ::boost::hana::fold_right)(sequence[, state], f)</code> | Accumulates the elements of a sequence from the right, optionally with a provided initial state.
606 <code>[fold](@ref ::boost::hana::fold)(sequence[, state], f)</code> | Equivalent to `fold_left`; provided for consistency with Boost.MPL and Boost.Fusion.
607 <code>[for_each](@ref ::boost::hana::for_each)(sequence, f)</code> | Call a function on each element of a sequence. Returns `void`.
608 <code>[front](@ref ::boost::hana::front)(sequence)</code> | Returns the first element of a non-empty sequence.
609 <code>[group](@ref ::boost::hana::group)(sequence[, predicate])</code> | %Group adjacent elements of a sequence which all satisfy (or all do not satisfy) some predicate. The predicate defaults to equality, in which case the elements must be `Comparable`.
610 <code>[insert](@ref ::boost::hana::insert)(sequence, index, element)</code> | Insert an element at a given index. The index must be an `IntegralConstant`.
611 <code>[insert_range](@ref ::boost::hana::insert_range)(sequence, index, elements)</code> | Insert a sequence of elements at a given index. The index must be an `IntegralConstant`.
612 <code>[is_empty](@ref ::boost::hana::is_empty)(sequence)</code> | Returns whether a sequence is empty as an `IntegralConstant`.
613 <code>[length](@ref ::boost::hana::length)(sequence)</code> | Returns the length of a sequence as an `IntegralConstant`.
614 <code>[lexicographical_compare](@ref ::boost::hana::lexicographical_compare)(sequence1, sequence2[, predicate])</code> | Performs a lexicographical comparison of two sequences, optionally with a custom predicate, by default with `hana::less`.
615 <code>[maximum](@ref ::boost::hana::maximum)(sequence[, predicate])</code> | Returns the greatest element of a sequence, optionally according to a predicate. The elements must be `Orderable` if no predicate is provided.
616 <code>[minimum](@ref ::boost::hana::minimum)(sequence[, predicate])</code> | Returns the smallest element of a sequence, optionally according to a predicate. The elements must be `Orderable` if no predicate is provided.
617 <code>[partition](@ref ::boost::hana::partition)(sequence, predicate)</code> | Partition a sequence into a pair of elements that satisfy some predicate, and elements that do not satisfy it.
618 <code>[prepend](@ref ::boost::hana::prepend)(sequence, value)</code> | Prepend an element to a sequence.
619 <code>[remove](@ref ::boost::hana::remove)(sequence, value)</code> | Remove all the elements that are equal to a given value.
620 <code>[remove_at](@ref ::boost::hana::remove_at)(sequence, index)</code> | Remove the element at the given index. The index must be an `IntegralConstant`.
621 <code>[remove_if](@ref ::boost::hana::remove_if)(sequence, predicate)</code> | Remove all the elements that satisfy a predicate. The predicate must return an `IntegralConstant`.
622 <code>[remove_range](@ref ::boost::hana::remove_range)(sequence, from, to)</code> | Remove the elements at indices in the given `[from, to)` half-open interval. The indices must be `IntegralConstant`s.
623 <code>[replace](@ref ::boost::hana::replace)(sequence, oldval, newval)</code> | Replace the elements of a sequence that compare equal to some value by some other value.
624 <code>[replace_if](@ref ::boost::hana::replace_if)(sequence, predicate, newval)</code> | Replace the elements of a sequence that satisfy some predicate by some value.
625 <code>[reverse](@ref ::boost::hana::reverse)(sequence)</code> | Reverse the order of the elements in a sequence.
626 <code>[reverse_fold](@ref ::boost::hana::reverse_fold)(sequence[, state], f)</code> | Equivalent to `fold_right`; provided for consistency with Boost.MPL and Boost.Fusion.
627 <code>[size](@ref ::boost::hana::size)(sequence)</code> | Equivalent to `length`; provided for consistency with the C++ standard library.
628 <code>[slice](@ref ::boost::hana::slice)(sequence, indices)</code> | Returns a new sequence containing the elements at the given indices of the original sequence.
629 <code>[slice_c](@ref ::boost::hana::slice_c)<from, to>(sequence)</code> | Returns a new sequence containing the elements at indices contained in `[from, to)` of the original sequence.
630 <code>[sort](@ref ::boost::hana::sort)(sequence[, predicate])</code> | Sort (stably) the elements of a sequence, optionally according to a predicate. The elements must be `Orderable` if no predicate is provided.
631 <code>[take_back](@ref ::boost::hana::take_back)(sequence, number)</code> | Take the last n elements of a sequence, or the whole sequence if `length(sequence) <= n`. n must be an `IntegralConstant`.
632 <code>[take_front](@ref ::boost::hana::take_front)(sequence, number)</code> | Take the first n elements of a sequence, or the whole sequence if `length(sequence) <= n`. n must be an `IntegralConstant`.
633 <code>[take_while](@ref ::boost::hana::take_while)(sequence, predicate)</code> | Take elements of a sequence while some predicate is satisfied, and return that.
634 <code>[transform](@ref ::boost::hana::transform)(sequence, f)</code> | Apply a function to each element of a sequence and return the result.
635 <code>[unique](@ref ::boost::hana::unique)(sequence[, predicate])</code> | Removes all consecutive duplicates from a sequence. The predicate defaults to equality, in which case the elements must be `Comparable`.
636 <code>[unpack](@ref ::boost::hana::unpack)(sequence, f)</code> | Calls a function with the contents of a sequence. Equivalent to `f(x1, ..., xN)`.
637 <code>[zip](@ref ::boost::hana::zip)(s1, ..., sN)</code> | Zip `N` sequences into a sequence of tuples. All the sequences must have the same length.
638 <code>[zip_shortest](@ref ::boost::hana::zip_shortest)(s1, ..., sN)</code> | Zip `N` sequences into a sequence of tuples. The resulting sequence has the length of the shortest input sequence.
639 <code>[zip_with](@ref ::boost::hana::zip_with)(f, s1, ..., sN)</code> | Zip `N` sequences with a `N`-ary function. All the sequences must have the same length.
640 <code>[zip_shortest_with](@ref ::boost::hana::zip_shortest_with)(f, s1, ..., sN)</code> | Zip `N` sequences with a `N`-ary function. The resulting sequence has the length of the shortest input sequence.
641
642
643
644
645
646
647
648
649
650
651 @section tutorial-assert Assertions
652
653 ------------------------------------------------------------------------------
654 In the rest of this tutorial, you will come across code snippets where different
655 kinds of assertions like `BOOST_HANA_RUNTIME_CHECK` and `BOOST_HANA_CONSTANT_CHECK`
656 are used. Like any sensible `assert` macro, they basically check that the
657 condition they are given is satisfied. However, in the context of heterogeneous
658 programming, some informations are known at compile-time, while others are known
659 only at runtime. The exact type of assertion that's used in a context tells you
660 whether the condition that's asserted upon can be known at compile-time or if it
661 must be computed at runtime, which is a very precious piece of information. Here
662 are the different kinds of assertions used in the tutorial, with a small
663 description of their particularities. For more details, you should check
664 the [reference on assertions](@ref group-assertions).
665
666 assertion | description
667 :--------------------------- | :----------
668 `BOOST_HANA_RUNTIME_CHECK` | Assertion on a condition that is not known until runtime. This assertion provides the weakest form of guarantee.
669 `BOOST_HANA_CONSTEXPR_CHECK` | Assertion on a condition that would be `constexpr` if lambdas were allowed inside constant expressions. In other words, the only reason for it not being a `static_assert` is the language limitation that lambdas can't appear in constant expressions, which [might be lifted][N4487] in C++17.
670 `static_assert` | Assertion on a `constexpr` condition. This is stronger than `BOOST_HANA_CONSTEXPR_CHECK` in that it requires the condition to be a constant expression, and it hence assures that the algorithms used in the expression are `constexpr`-friendly.
671 `BOOST_HANA_CONSTANT_CHECK` | Assertion on a boolean `IntegralConstant`. This assertion provides the strongest form of guarantee, because an `IntegralConstant` can be converted to a `constexpr` value even if it is not `constexpr` itself.
672
673
674
675
676
677
678
679
680
681
682 @section tutorial-integral Compile-time numbers
683
684 ------------------------------------------------------------------------------
685 This section introduces the important notion of `IntegralConstant` and the
686 philosophy behind Hana's metaprogramming paradigm. Let's start with a rather
687 odd question. What is an `integral_constant`?
688
689 @code{cpp}
690 template<class T, T v>
691 struct integral_constant {
692 static constexpr T value = v;
693 typedef T value_type;
694 typedef integral_constant type;
695 constexpr operator value_type() const noexcept { return value; }
696 constexpr value_type operator()() const noexcept { return value; }
697 };
698 @endcode
699
700 @note
701 If this is totally new to you, you might want to take a look at the
702 [documentation][C++14.ice] for `std::integral_constant`.
703
704 One valid answer is that `integral_constant` represents a type-level
705 encoding of a number, or more generally any object of an integral type.
706 For illustration, we could define a successor function on numbers in that
707 representation very easily by using a template alias:
708
709 @code{cpp}
710 template <typename N>
711 using succ = integral_constant<int, N::value + 1>;
712
713 using one = integral_constant<int, 1>;
714 using two = succ<one>;
715 using three = succ<two>;
716 // ...
717 @endcode
718
719 This is the way `integral_constant`s are usually thought of; as _type-level_
720 entities that can be used for template metaprogramming. Another way to see
721 an `integral_constant` is as a runtime object representing a `constexpr` value
722 of an integral type:
723
724 @code{cpp}
725 auto one = integral_constant<int, 1>{};
726 @endcode
727
728 Here, while `one` is not marked as `constexpr`, the abstract value it holds
729 (a `constexpr 1`) is still available at compile-time, because that value is
730 encoded in the type of `one`. Indeed, even if `one` is not `constexpr`, we
731 can use `decltype` to retrieve the compile-time value it represents:
732
733 @code{cpp}
734 auto one = integral_constant<int, 1>{};
735 constexpr int one_constexpr = decltype(one)::value;
736 @endcode
737
738 But why on earth would we want to consider `integral_constant`s as objects
739 instead of type-level entities? To see why, consider how we could now
740 implement the same successor function as before:
741
742 @code{cpp}
743 template <typename N>
744 auto succ(N) {
745 return integral_constant<int, N::value + 1>{};
746 }
747
748 auto one = integral_constant<int, 1>{};
749 auto two = succ(one);
750 auto three = succ(two);
751 // ...
752 @endcode
753
754 Did you notice anything new? The difference is that instead of implementing
755 `succ` at the type-level with a template alias, we're now implementing it at
756 the value-level with a template function. Furthermore, we can now perform
757 compile-time arithmetic using the same syntax as that of normal C++. This
758 way of seeing compile-time entities as objects instead of types is the key
759 to Hana's expressive power.
760
761
762 @subsection tutorial-integral-arithmetic Compile-time arithmetic
763
764 The MPL defines [arithmetic operators][MPL.arithmetic] that can be used to do
765 compile-time computations with `integral_constant`s. A typical example of such
766 an operation is `plus`, which is implemented roughly as:
767
768 @code{cpp}
769 template <typename X, typename Y>
770 struct plus {
771 using type = integral_constant<
772 decltype(X::value + Y::value),
773 X::value + Y::value
774 >;
775 };
776
777 using three = plus<integral_constant<int, 1>,
778 integral_constant<int, 2>>::type;
779 @endcode
780
781 By viewing `integral_constant`s as objects instead of types, the translation
782 from a metafunction to a function is very straightforward:
783
784 @code{cpp}
785 template <typename V, V v, typename U, U u>
786 constexpr auto
787 operator+(integral_constant<V, v>, integral_constant<U, u>)
788 { return integral_constant<decltype(v + u), v + u>{}; }
789
790 auto three = integral_constant<int, 1>{} + integral_constant<int, 2>{};
791 @endcode
792
793 It is very important to emphasize the fact that this operator does not return
794 a normal integer. Instead, it returns a value-initialized object whose type
795 contains the result of the addition. The only useful information contained in
796 that object is actually in its type, and we're creating an object because it
797 allows us to use this nice value-level syntax. It turns out that we can make
798 this syntax even better by using a [C++14 variable template][C++14.vtemplate]
799 to simplify the creation of an `integral_constant`:
800
801 @code{cpp}
802 template <int i>
803 constexpr integral_constant<int, i> int_c{};
804
805 auto three = int_c<1> + int_c<2>;
806 @endcode
807
808 Now we're talking about a visible gain in expressiveness over the initial
809 type-level approach, aren't we? But there's more; we can also use
810 [C++14 user defined literals][C++14.udl] to make this process even simpler:
811
812 @code{cpp}
813 template <char ...digits>
814 constexpr auto operator"" _c() {
815 // parse the digits and return an integral_constant
816 }
817
818 auto three = 1_c + 3_c;
819 @endcode
820
821 Hana provides its own `integral_constant`s, which define arithmetic operators
822 just like we showed above. Hana also provides variable templates to easily
823 create different kinds of `integral_constant`s: `int_c`, `long_c`, `bool_c`,
824 etc... This allows you to omit the trailing `{}` braces otherwise required to
825 value-initialize these objects. Of course, the `_c` suffix is also provided;
826 it is part of the `hana::literals` namespace, and you must import it into
827 your namespace before using it:
828
829 @code{cpp}
830 using namespace hana::literals;
831
832 auto three = 1_c + 3_c;
833 @endcode
834
835 This way, you may do compile-time arithmetic without having to struggle with
836 awkward type-level idiosyncrasies, and your coworkers will now be able to
837 understand what's going on.
838
839
840 @subsection tutorial-integral-distance Example: Euclidean distance
841
842 To illustrate how good it gets, let's implement a function computing a 2-D
843 euclidean distance at compile-time. As a reminder, the euclidean distance of
844 two points in the 2-D plane is given by
845
846 @f[
847 \mathrm{distance}\left((x_1, y_1), (x_2, y_2)\right)
848 := \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}
849 @f]
850
851 First, here's how it looks like with a type-level approach (using the MPL):
852
853 @snippet example/tutorial/integral.cpp distance-mpl
854
855 Yeah... Now, let's implement it with the value-level approach presented above:
856
857 @snippet example/tutorial/integral.cpp distance-hana
858
859 This version looks arguably cleaner. However, this is not all. Notice how the
860 `distance` function looks exactly as the one you would have written for
861 computing the euclidean distance on dynamic values? Indeed, because we're
862 using the same syntax for dynamic and compile-time arithmetic, generic
863 functions written for one will work for both!
864
865 @snippet example/tutorial/integral.cpp distance-dynamic
866
867 __Without changing any code__, we can use our `distance` function on runtime
868 values and everything just works. Now that's DRY.
869
870
871 @subsection tutorial-integral-branching Compile-time branching
872
873 Once we have compile-time arithmetic, the next thing that might come to mind
874 is compile-time branching. When metaprogramming, it is often useful to have
875 one piece of code be compiled if some condition is true, and a different one
876 otherwise. If you have heard of [static_if][N4461], this should sound very
877 familiar, and indeed it is exactly what we are talking about. Otherwise, if
878 you don't know why we might want to branch at compile-time, consider the
879 following code (adapted from [N4461][]):
880
881 @code{cpp}
882 template <typename T, typename ...Args>
883 std::enable_if_t<std::is_constructible<T, Args...>::value,
884 std::unique_ptr<T>> make_unique(Args&&... args) {
885 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
886 }
887
888 template <typename T, typename ...Args>
889 std::enable_if_t<!std::is_constructible<T, Args...>::value,
890 std::unique_ptr<T>> make_unique(Args&&... args) {
891 return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
892 }
893 @endcode
894
895 This code creates a `std::unique_ptr` using the correct form of syntax for the
896 constructor. To achieve this, it uses [SFINAE][] and requires two different
897 overloads. Now, anyone sane seeing this for the first time would ask why it
898 is not possible to simply write:
899
900 @code{cpp}
901 template <typename T, typename ...Args>
902 std::unique_ptr<T> make_unique(Args&&... args) {
903 if (std::is_constructible<T, Args...>::value)
904 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
905 else
906 return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
907 }
908 @endcode
909
910 The reason is that the compiler is required to compile both branches of the
911 `if` statement, regardless of the condition (even though it is known at
912 compile-time). But when `T` is _not_ constructible from `Args...`, the second
913 branch will fail to compile, which will cause a hard compilation error. What
914 we need really is a way to tell the compiler __not to compile__ the second
915 branch when the condition is true, and the first branch when the condition is
916 false.
917
918 To emulate this, Hana provides an `if_` function that works a bit like a
919 normal `if` statement, except except it takes a condition that can be an
920 `IntegralConstant` and returns the one of two values (which may have
921 different types) chosen by the condition. If the condition is true, the
922 first value is returned, and otherwise the second value is returned. A
923 somewhat vain example is the following:
924
925 @code{cpp}
926 auto one_two_three = hana::if_(hana::true_c, 123, "hello");
927 auto hello = hana::if_(hana::false_c, 123, "hello");
928 @endcode
929
930 @note
931 `hana::true_c` and `hana::false_c` are just boolean `IntegralConstant`s
932 representing a compile-time true value and a compile-time false value,
933 respectively.
934
935 Here, `one_two_three` is equal to `123`, and `hello` is equal to `"hello"`.
936 In other words, `if_` is a little bit like the ternary conditional operator
937 `? :`, except that both sides of the `:` can have different types:
938
939 @code{cpp}
940 // fails in both cases because both branches have incompatible types
941 auto one_two_three = hana::true_c ? 123 : "hello";
942 auto hello = hana::false_c ? 123 : "hello";
943 @endcode
944
945 Ok, so this is neat, but how can it actually help us write complete branches
946 that are lazily instantiated by the compiler? The answer is to represent both
947 branches of the `if` statement we'd like to write as generic lambdas, and to
948 use `hana::if_` to return the branch that we'd like to execute. Here's how we
949 could rewrite `make_unique`:
950
951 @snippet example/tutorial/integral-branching.cpp make_unique.if_
952
953 Here, the first value given to `hana::if_` is a generic lambda representing
954 the branch we want to execute if the condition is true, and the second value
955 is the branch we want to execute otherwise. `hana::if_` simply returns the
956 branch chosen by the condition, and we call that branch (which is a generic
957 lambda) immediately with `std::forward<Args>(args)...`. Hence, the proper
958 generic lambda ends up being called, with `x...` being `args...`, and we
959 return the result of that call.
960
961 The reason why this approach works is because the body of each branch can only
962 be instantiated when the types of all `x...` are known. Indeed, since the
963 branch is a generic lambda, the type of the argument is not known until the
964 lambda is called, and the compiler must wait for the types of `x...` to be
965 known before type-checking the lambda's body. Since the erroneous lambda is
966 never called when the condition is not satisfied (`hana::if_` takes care of
967 that), the body of the lambda that would fail is never type-checked and no
968 compilation error happens.
969
970 @note
971 The branches inside the `if_` are lambdas. As such, they really are different
972 functions from the `make_unique` function. The variables appearing inside
973 those branches have to be either captured by the lambdas or passed to them as
974 arguments, and so they are affected by the way they are captured or passed
975 (by value, by reference, etc..).
976
977 Since this pattern of expressing branches as lambdas and then calling them
978 is very common, Hana provides a `eval_if` function whose purpose is to make
979 compile-time branching easier. `eval_if` comes from the fact that in a lambda,
980 one can either receive input data as arguments or capture it from the context.
981 However, for the purpose of emulating a language level `if` statement,
982 implicitly capturing variables from the enclosing scope is usually more
983 natural. Hence, what we would prefer writing is
984
985 @code{cpp}
986 template <typename T, typename ...Args>
987 std::unique_ptr<T> make_unique(Args&&... args) {
988 return hana::if_(std::is_constructible<T, Args...>{},
989 [&] { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); },
990 [&] { return std::unique_ptr<T>(new T{std::forward<Args>(args)...}); }
991 );
992 }
993 @endcode
994
995 Here, we're capturing the `args...` variables from the enclosing scope, which
996 prevents us from having to introduce the new `x...` variables and passing them
997 as arguments to the branches. However, this has two problems. First, this will
998 not achieve the right result, since `hana::if_` will end up returning a lambda
999 instead of returning the result of calling that lambda. To fix this, we can use
1000 `hana::eval_if` instead of `hana::if_`:
1001
1002 @code{cpp}
1003 template <typename T, typename ...Args>
1004 std::unique_ptr<T> make_unique(Args&&... args) {
1005 return hana::eval_if(std::is_constructible<T, Args...>{},
1006 [&] { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); },
1007 [&] { return std::unique_ptr<T>(new T{std::forward<Args>(args)...}); }
1008 );
1009 }
1010 @endcode
1011
1012 Here, we capture the enclosing `args...` by reference using `[&]`, and we do
1013 not need to receive any arguments. Also, `hana::eval_if` assumes that its
1014 arguments are branches that can be called, and it will take care of calling
1015 the branch that is selected by the condition. However, this will still cause
1016 a compilation failure, because the bodies of the lambdas are not dependent
1017 anymore, and semantic analysis will be done for both branches even though
1018 only one would end up being used. The solution to this problem is to make
1019 the bodies of the lambdas artificially dependent on something, to prevent the
1020 compiler from being able to perform semantic analysis before the lambda is
1021 actually used. To make this possible, `hana::eval_if` will call the selected
1022 branch with an identity function (a function that returns its argument
1023 unchanged), if the branch accepts such an argument:
1024
1025 @snippet example/tutorial/integral-branching.cpp make_unique.eval_if
1026
1027 Here, the bodies of the branches take an additional argument called `_` by
1028 convention. This argument will be provided by `hana::eval_if` to the branch
1029 that was selected. Then, we use `_` as a function on the variables that we
1030 want to make dependent within the body of each branch. What happens is that
1031 `_` will always be a function that returns its argument unchanged. However,
1032 the compiler can't possibly know it before the lambda has actually been called,
1033 so it can't know the type of `_(args)`. This prevents the compiler from being
1034 able to perform semantic analysis, and no compilation error happens. Plus,
1035 since `_(x)` is guaranteed to be equivalent to `x`, we know that we're not
1036 actually changing the semantics of the branches by using this trick.
1037
1038 While using this trick may seem cumbersome, it can be very useful when dealing
1039 with many variables inside a branch. Furthermore, it is not required to wrap
1040 all variables with `_`; only variables that are involved in an expression whose
1041 type-checking has to be delayed must be wrapped, but the other ones are not
1042 required. There are still a few things to know about compile-time branching
1043 in Hana, but you can dig deeper by looking at the reference for `hana::eval_if`,
1044 `hana::if_` and `hana::lazy`.
1045
1046
1047 @subsection tutorial-integral-more Why stop here?
1048
1049 Why should we limit ourselves to arithmetic operations and branching? When you
1050 start considering `IntegralConstant`s as objects, it becomes sensible to augment
1051 their interface with more functions that are generally useful. For example,
1052 Hana's `IntegralConstant`s define a `times` member function that can be used
1053 to invoke a function a certain number of times, which is especially useful
1054 for loop unrolling:
1055
1056 @code{cpp}
1057 __attribute__((noinline)) void f() { }
1058
1059 int main() {
1060 hana::int_c<10>.times(f);
1061 }
1062 @endcode
1063
1064 In the above code, the 10 calls to `f` are expanded at compile-time. In other
1065 words, this is equivalent to writing
1066
1067 @code{cpp}
1068 f(); f(); ... f(); // 10 times
1069 @endcode
1070
1071 @note
1072 Always [be careful][Chandler.MeetingC++] about manually unrolling loops or
1073 doing other such optimizations manually. In most cases, your compiler is
1074 probably better than you at optimizing. When in doubt, benchmark.
1075
1076 Another nice use of `IntegralConstant`s is to define good-looking operators
1077 for indexing heterogeneous sequences. Whereas `std::tuple` must be accessed
1078 with `std::get`, `hana::tuple` can be accessed using the familiar `operator[]`
1079 used for standard library containers:
1080
1081 @code{cpp}
1082 auto values = hana::make_tuple(1, 'x', 3.4f);
1083 char x = values[1_c];
1084 @endcode
1085
1086 How this works is very simple. Basically, `hana::tuple` defines an `operator[]`
1087 taking an `IntegralConstant` instead of a normal integer, in a way similar to
1088
1089 @code{cpp}
1090 template <typename N>
1091 constexpr decltype(auto) operator[](N const&) {
1092 return std::get<N::value>(*this);
1093 }
1094 @endcode
1095
1096 This is the end of the section on `IntegralConstant`s. This section introduced
1097 the feel behind Hana's new way of metaprogramming; if you liked what you've
1098 seen so far, the rest of this tutorial should feel just like home.
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 @section tutorial-type Type computations
1110
1111 ------------------------------------------------------------------------------
1112 At this point, if you are interested in doing type-level computations as with
1113 the MPL, you might be wondering how is Hana going to help you. Do not despair.
1114 Hana provides a way to perform type-level computations with a great deal of
1115 expressiveness by representing types as values, just like we represented
1116 compile-time numbers as values. This is a completely new way of approaching
1117 metaprogramming, and you should try to set your old MPL habits aside for a bit
1118 if you want to become proficient with Hana.
1119
1120 However, please be aware that modern C++ features like [auto-deduced return type]
1121 [C++14.auto_rt] remove the need for type computations in many cases. Hence,
1122 before even considering to do a type computation, you should ask yourself
1123 whether there's a simpler way to achieve what you're trying to achieve. In
1124 most cases, the answer will be yes. However, when the answer is no, Hana will
1125 provide you with nuclear-strength facilities to do what needs to be done.
1126
1127
1128 @subsection tutorial-type-objects Types as objects
1129
1130 The key behind Hana's approach to type-level computations is essentially the
1131 same as the approach to compile-time arithmetic. Basically, the idea is to
1132 represent compile-time entities as objects by wrapping them into some kind of
1133 container. For `IntegralConstant`s, the compile-time entities were constant
1134 expressions of an integral type and the wrapper we used was `integral_constant`.
1135 In this section, the compile-time entities will be types and the wrapper we'll
1136 be using is called `type`. Just like we did for `IntegralConstant`s, let's
1137 start by defining a dummy template that could be used to represent a type:
1138
1139 @code{cpp}
1140 template <typename T>
1141 struct basic_type {
1142 // empty (for now)
1143 };
1144
1145 basic_type<int> Int{};
1146 basic_type<char> Char{};
1147 // ...
1148 @endcode
1149
1150 @note
1151 We're using the name `basic_type` here because we're only building a naive
1152 version of the actual functionality provided by Hana.
1153
1154 While this may seem completely useless, it is actually enough to start writing
1155 metafunctions that look like functions. Indeed, consider the following
1156 alternate implementations of `std::add_pointer` and `std::is_pointer`:
1157
1158 @code{cpp}
1159 template <typename T>
1160 constexpr basic_type<T*> add_pointer(basic_type<T> const&)
1161 { return {}; }
1162
1163 template <typename T>
1164 constexpr auto is_pointer(basic_type<T> const&)
1165 { return hana::bool_c<false>; }
1166
1167 template <typename T>
1168 constexpr auto is_pointer(basic_type<T*> const&)
1169 { return hana::bool_c<true>; }
1170 @endcode
1171
1172 We've just written metafunctions that look like functions, just like we wrote
1173 compile-time arithmetic metafunctions as heterogeneous C++ operators in the
1174 previous section. Here's how we can use them:
1175
1176 @code{cpp}
1177 basic_type<int> t{};
1178 auto p = add_pointer(t);
1179 BOOST_HANA_CONSTANT_CHECK(is_pointer(p));
1180 @endcode
1181
1182 Notice how we can now use a normal function call syntax to perform type-level
1183 computations? This is analogous to how using values for compile-time numbers
1184 allowed us to use normal C++ operators to perform compile-time computations.
1185 Like we did for `integral_constant`, we can also go one step further and use
1186 C++14 variable templates to provide syntactic sugar for creating types:
1187
1188 @code{cpp}
1189 template <typename T>
1190 constexpr basic_type<T> type_c{};
1191
1192 auto t = type_c<int>;
1193 auto p = add_pointer(t);
1194 BOOST_HANA_CONSTANT_CHECK(is_pointer(p));
1195 @endcode
1196
1197 @note
1198 This is not exactly how the `hana::type_c` variable template is implemented
1199 because of some subtleties; things were dumbed down here for the sake of the
1200 explanation. Please check the reference for `hana::type` to know exactly
1201 what you can expect from a `hana::type_c<...>`.
1202
1203
1204 @subsection tutorial-type-benefits Benefits of this representation
1205
1206 But what does that buy us? Well, since a `type_c<...>` is just an object, we
1207 can store it in a heterogeneous sequence like a tuple, we can move it around
1208 and pass it to (or return it from) functions, and we can do basically anything
1209 else that requires an object:
1210
1211 @snippet example/tutorial/type.cpp tuple
1212
1213 @note
1214 Writing `make_tuple(type_c<T>...)` can be annoying when there are several types.
1215 For this reason, Hana provides the `tuple_t<T...>` variable template, which is
1216 syntactic sugar for `make_tuple(type_c<T>...)`.
1217
1218 Also, notice that since the above tuple is really just a normal heterogeneous
1219 sequence, we can apply heterogeneous algorithms on that sequence just like we
1220 could on a tuple of `int`s, for example. Furthermore, since we're just
1221 manipulating objects, we can now use the full language instead of just the
1222 small subset available at the type-level. For example, consider the task of
1223 removing all the types that are not a reference or a pointer from a sequence
1224 of types. With the MPL, we would have to use a placeholder expression to
1225 express the predicate, which is clunky:
1226
1227 @snippet example/tutorial/type.cpp filter.MPL
1228
1229 Now, since we're manipulating objects, we can use the full language and use a
1230 generic lambda instead, which leads to much more readable code:
1231
1232 @snippet example/tutorial/type.cpp filter.Hana
1233
1234 Since Hana handles all heterogeneous containers uniformly, this approach of
1235 representing types as values also has the benefit that a single library is
1236 now needed for both heterogeneous computations and type level computations.
1237 Indeed, whereas we would normally need two different libraries to perform
1238 almost identical tasks, we now need a single library. Again, consider the
1239 task of filtering a sequence with a predicate. With MPL and Fusion, this
1240 is what we must do:
1241
1242 @snippet example/tutorial/type.cpp single_library.then
1243
1244 With Hana, a single library is required. Notice how we use the same `filter`
1245 algorithm and the same container, and only tweak the predicate so it can
1246 operate on values:
1247
1248 @snippet example/tutorial/type.cpp single_library.Hana
1249
1250 But that is not all. Indeed, having a unified syntax for type-level and
1251 value-level computations allows us to achieve greater consistency in the
1252 interface of heterogeneous containers. For example, consider the simple
1253 task of creating a heterogeneous map associating types to values, and then
1254 accessing an element of it. With Fusion, what's happening is far from obvious
1255 to the untrained eye:
1256
1257 @snippet example/tutorial/type.cpp make_map.Fusion
1258
1259 However, with a unified syntax for types and values, the same thing becomes
1260 much clearer:
1261
1262 @snippet example/tutorial/type.cpp make_map.Hana
1263
1264 While Hana's way takes more lines of codes, it is also arguably more readable
1265 and closer to how someone would expect to initialize a map.
1266
1267
1268 @subsection tutorial-type-working Working with this representation
1269
1270 So far, we can represent types as values and perform type-level computations
1271 on those objects using the usual C++ syntax. This is nice, but it is not very
1272 useful because we have no way to get back a normal C++ type from an object
1273 representation. For example, how could we declare a variable whose type is the
1274 result of a type computation?
1275
1276 @code{cpp}
1277 auto t = add_pointer(hana::type_c<int>); // could be a complex type computation
1278 using T = the-type-represented-by-t;
1279
1280 T var = ...;
1281 @endcode
1282
1283 Right now, there is no easy way to do it. To make this easier to achieve, we
1284 enrich the interface of the `basic_type` container that we defined above.
1285 Instead of being an empty `struct`, we now define it as
1286
1287 @code{cpp}
1288 template <typename T>
1289 struct basic_type {
1290 using type = T;
1291 };
1292 @endcode
1293
1294 @note
1295 This is equivalent to making `basic_type` a metafunction in the MPL sense.
1296
1297 This way, we can use `decltype` to easily access the actual C++ type
1298 represented by a `type_c<...>` object:
1299
1300 @code{cpp}
1301 auto t = add_pointer(hana::type_c<int>);
1302 using T = decltype(t)::type; // fetches basic_type<T>::type
1303
1304 T var = ...;
1305 @endcode
1306
1307 In general, doing type-level metaprogramming with Hana is a three step process:
1308
1309 1. Represent types as objects by wrapping them with `hana::type_c<...>`
1310 2. Perform type transformations with value syntax
1311 3. Unwrap the result with `decltype(...)::%type`
1312
1313 Now, you must be thinking that this is incredibly cumbersome. In reality, it
1314 is very manageable for several reasons. First, this wrapping and unwrapping
1315 only needs to happen at some very thin boundaries.
1316
1317 @code{cpp}
1318 auto t = hana::type_c<T>;
1319 auto result = huge_type_computation(t);
1320 using Result = decltype(result)::type;
1321 @endcode
1322
1323 Furthermore, since you get the advantage of working with objects (without
1324 having to wrap/unwrap) inside the computation, the cost of wrapping and
1325 unwrapping is amortized on the whole computation. Hence, for complex type
1326 computations, the syntactic noise of this three step process quickly becomes
1327 negligible in light of the expressiveness gain of working with values inside
1328 that computation. Also, using values instead of types means that we can avoid
1329 typing `typename` and `template` all around the place, which accounted for a
1330 lot of syntactic noise in classic metaprogramming.
1331
1332 Another point is that the three full steps are not always required. Indeed,
1333 sometimes one just needs to do a type-level computation and query something
1334 about the result, without necessarily fetching the result as a normal C++ type:
1335
1336 @code{cpp}
1337 auto t = hana::type_c<T>;
1338 auto result = type_computation(t);
1339 BOOST_HANA_CONSTANT_CHECK(is_pointer(result)); // third step skipped
1340 @endcode
1341
1342 In this case, we were able to skip the third step because we did not need to
1343 access the actual type represented by `result`. In other cases, the first step
1344 can be avoided, like when using `tuple_t`, which has no more syntactic noise
1345 than any other pure type-level approach:
1346
1347 @snippet example/tutorial/type.cpp skip_first_step
1348
1349 For skeptical readers, let's consider the task of finding the smallest type
1350 in a sequence of types. This is a very good example of a short type-only
1351 computation, which is where we would expect the new paradigm to suffer the
1352 most. As you will see, things stay manageable even for small computations.
1353 First, let's implement it with the MPL:
1354
1355 @snippet example/tutorial/type.cpp smallest.MPL
1356
1357 The result is quite readable (for anyone familiar with the MPL). Let's now
1358 implement the same thing using Hana:
1359
1360 @snippet example/tutorial/type.cpp smallest.Hana
1361
1362 As you can witness, the syntactic noise of the 3-step process is almost
1363 completely hidden by the rest of the computation.
1364
1365
1366 @subsection tutorial-type-lifting The generic lifting process
1367
1368 The first type-level computation that we introduced in the form of a function
1369 looked like:
1370
1371 @code{cpp}
1372 template <typename T>
1373 constexpr auto add_pointer(hana::basic_type<T> const&) {
1374 return hana::type<T*>;
1375 }
1376 @endcode
1377
1378 While it looks more complicated, we could also write it as:
1379
1380 @code{cpp}
1381 template <typename T>
1382 constexpr auto add_pointer(hana::basic_type<T> const&) {
1383 return hana::type_c<typename std::add_pointer<T>::type>;
1384 }
1385 @endcode
1386
1387 However, this implementation emphasizes the fact that we're really emulating
1388 an existing metafunction and simply representing it as a function. In other
1389 words, we're _lifting_ a metafunction (`std::add_pointer`) to the world of
1390 values by creating our own `add_pointer` function. It turns out that this
1391 lifting process is a generic one. Indeed, given any metafunction, we could
1392 write almost the same thing:
1393
1394 @code{cpp}
1395 template <typename T>
1396 constexpr auto add_const(hana::basic_type<T> const&)
1397 { return hana::type_c<typename std::add_const<T>::type>; }
1398
1399 template <typename T>
1400 constexpr auto add_volatile(hana::basic_type<T> const&)
1401 { return hana::type_c<typename std::add_volatile<T>::type>; }
1402
1403 template <typename T>
1404 constexpr auto add_lvalue_reference(hana::basic_type<T> const&)
1405 { return hana::type_c<typename std::add_lvalue_reference<T>::type>; }
1406
1407 // etc...
1408 @endcode
1409
1410 This mechanical transformation is easy to abstract into a generic lifter
1411 that can handle any [MPL Metafunction][MPL.metafunction] as follows:
1412
1413 @snippet example/tutorial/type.cpp metafunction1
1414
1415 More generally, we'll want to allow metafunctions with any number of
1416 arguments, which brings us to the following less naive implementation:
1417
1418 @snippet example/tutorial/type.cpp metafunction2
1419
1420 Hana provides a similar generic metafunction lifter called `hana::metafunction`.
1421 One small improvement is that `hana::metafunction<F>` is a function object
1422 instead of an overloaded function, so one can pass it to higher-order
1423 algorithms. It is also a model of the slightly more powerful concept of
1424 `Metafunction`, but this can safely be ignored for now. The process we
1425 explored in this section does not only apply to metafunctions; it also
1426 applies to templates. Indeed, we could define:
1427
1428 @snippet example/tutorial/type.cpp template_
1429
1430 Hana provides a generic lifter for templates named `hana::template_`, and it
1431 also provides a generic lifter for [MPL MetafunctionClasses][MPL.mfc] named
1432 `hana::metafunction_class`. This gives us a way to uniformly represent "legacy"
1433 type-level computations as functions, so that any code written using a classic
1434 type-level metaprogramming library can almost trivially be used with Hana. For
1435 example, say you have a large chunk of MPL-based code and you'd like to
1436 interface with Hana. The process of doing so is no harder than wrapping your
1437 metafunctions with the lifter provided by Hana:
1438
1439 @code{cpp}
1440 template <typename T>
1441 struct legacy {
1442 using type = ...; // something you really don't want to mess with
1443 };
1444
1445 auto types = hana::make_tuple(...);
1446 auto use = hana::transform(types, hana::metafunction<legacy>);
1447 @endcode
1448
1449 However, note that not all type-level computations can be lifted as-is with
1450 the tools provided by Hana. For example, `std::extent` can't be lifted because
1451 it requires non-type template parameters. Since there is no way to deal with
1452 non-type template parameters uniformly in C++, one must resort to using a
1453 hand-written function object specific to that type-level computation:
1454
1455 @snippet example/tutorial/type.cpp extent
1456
1457 @note
1458 Do not forget to include the bridge header for `std::integral_constant`s
1459 (`<boost/hana/ext/std/integral_constant.hpp>`) when using type traits from
1460 `<type_traits>` directly.
1461
1462 In practice, however, this should not be a problem since the vast majority
1463 of type-level computations can be lifted easily. Finally, since metafunctions
1464 provided by the `<type_traits>` header are used so frequently, Hana provides
1465 a lifted version for every one of them. Those lifted traits are in the
1466 `hana::traits` namespace, and they live in the `<boost/hana/traits.hpp>` header:
1467
1468 @snippet example/tutorial/type.cpp traits
1469
1470 This is the end of the section on type computations. While this new paradigm
1471 for type level programming might be difficult to grok at first, it will make
1472 more sense as you use it more and more. You will also come to appreciate how
1473 it blurs the line between types and values, opening new exciting possibilities
1474 and simplifying many tasks.
1475
1476 @note
1477 Curious or skeptical readers should consider checking the minimal
1478 reimplementation of the MPL presented in the [appendices]
1479 (@ref tutorial-appendix-MPL).
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490 @section tutorial-introspection Introspection
1491
1492 ------------------------------------------------------------------------------
1493 Static introspection, as we will discuss it here, is the ability of a program
1494 to examine the type of an object at compile-time. In other words, it is a
1495 programmatic interface to interact with types at compile-time. For example,
1496 have you ever wanted to check whether some unknown type has a member named
1497 `foo`? Or perhaps at some point you have needed to iterate on the members
1498 of a `struct`?
1499
1500 @code{cpp}
1501 struct Person {
1502 std::string name;
1503 int age;
1504 };
1505
1506 Person john{"John", 30};
1507 for (auto& member : john)
1508 std::cout << member.name << ": " << member.value << std::endl;
1509
1510 // name: John
1511 // age: 30
1512 @endcode
1513
1514 If you have written a bit of templates in your life, chances are very high
1515 that you came across the first problem of checking for a member. Also, anyone
1516 having tried to implement object serialization or even just pretty printing
1517 has come across the second problem. In most dynamic languages like Python,
1518 Ruby or JavaScript, these problems are completely solved and introspection is
1519 used every day by programmers to make a lot of tasks simpler. However, as a
1520 C++ programmer, we do not have language support for those things, which makes
1521 several tasks much harder than they should be. While language support would
1522 likely be needed to properly tackle this problem, Hana makes some common
1523 introspection patterns much more accessible.
1524
1525
1526 @subsection tutorial-introspection-is_valid Checking expression validity
1527
1528 Given an object of an unknown type, it is sometimes desirable to check
1529 whether this object has a member (or member function) with some name.
1530 This can be used to perform sophisticated flavors of overloading. For
1531 example, consider the problem of calling a `toString` method on objects
1532 that support it, but providing another default implementation for objects
1533 that do not support it:
1534
1535 @code{cpp}
1536 template <typename T>
1537 std::string optionalToString(T const& obj) {
1538 if (obj.toString() is a valid expression)
1539 return obj.toString();
1540 else
1541 return "toString not defined";
1542 }
1543 @endcode
1544
1545 @note
1546 While most use cases for this technique will be addressed by [concepts lite]
1547 [C++17.clite] in future revisions of the standard, there will still be cases
1548 where a quick and dirty check is more convenient than creating a full blown
1549 concept.
1550
1551 How could we implement a check for the validity of `obj.toString()` as above
1552 in a generic fashion (so it can be reused in other functions, for example)?
1553 Normally, we would be stuck writing some kind of SFINAE-based detection:
1554
1555 @snippet example/tutorial/introspection.cpp has_toString.then
1556
1557 This works, but the intent is not very clear and most people without a deep
1558 knowledge of template metaprogramming would think this is black magic. Then,
1559 we could implement `optionalToString` as
1560
1561 @code{cpp}
1562 template <typename T>
1563 std::string optionalToString(T const& obj) {
1564 if (has_toString<T>::value)
1565 return obj.toString();
1566 else
1567 return "toString not defined";
1568 }
1569 @endcode
1570
1571 @note
1572 Of course, this implementation won't actually work because both branches of
1573 the `if` statement will be compiled. If `obj` does not have a `toString`
1574 method, the compilation of the `if` branch will fail. We will address
1575 this issue in a moment.
1576
1577 Instead of the above SFINAE trick, Hana provides a `is_valid` function that
1578 can be combined with [C++14 generic lambdas][C++14.glambda] to obtain a much
1579 cleaner implementation of the same thing:
1580
1581 @snippet example/tutorial/introspection.cpp has_toString.now
1582
1583 This leaves us with a function object `has_toString` which returns whether the
1584 given expression is valid on the argument we pass to it. The result is returned
1585 as an `IntegralConstant`, so `constexpr`-ness is not an issue here because the
1586 result of the function is represented as a type anyway. Now, in addition to
1587 being less verbose (that's a one liner!), the intent is much clearer. Other
1588 benefits are the fact that `has_toString` can be passed to higher order
1589 algorithms and it can also be defined at function scope, so there is no need
1590 to pollute the namespace scope with implementation details. Here is how we
1591 would now write `optionalToString`:
1592
1593 @code{cpp}
1594 template <typename T>
1595 std::string optionalToString(T const& obj) {
1596 if (has_toString(obj))
1597 return obj.toString();
1598 else
1599 return "toString not defined";
1600 }
1601 @endcode
1602
1603 Much cleaner, right? However, as we said earlier, this implementation won't
1604 actually work because both branches of the `if` always have to be compiled,
1605 regardless of whether `obj` has a `toString` method. There are several
1606 possible options, but the most classical one is to use `std::enable_if`:
1607
1608 @snippet example/tutorial/introspection.cpp optionalToString.then
1609
1610 @note
1611 We're using the fact that `has_toString` returns an `IntegralConstant` to
1612 write `decltype(...)::%value`, which is a constant expression. For some
1613 reason, `has_toString(obj)` is not considered a constant expression, even
1614 though I think it should be one because we never read from `obj` (see the
1615 section on [advanced constexpr](@ref tutorial-appendix-constexpr)).
1616
1617 While this implementation is perfectly valid, it is still pretty cumbersome
1618 because it requires writing two different functions and going through the
1619 hoops of SFINAE explicitly by using `std::enable_if`. However, as you might
1620 remember from the section on [compile-time branching](@ref tutorial-integral-branching),
1621 Hana provides an `if_` function that can be used to emulate the functionality
1622 of [static_if][N4461]. Here is how we could write `optionalToString` with
1623 `hana::if_`:
1624
1625 @snippet example/tutorial/introspection.cpp optionalToString
1626
1627 Now, the previous example covered only the specific case of checking for the
1628 presence of a non-static member function. However, `is_valid` can be used to
1629 detect the validity of almost any kind of expression. For completeness, we
1630 now present a list of common use cases for validity checking along with how
1631 to use `is_valid` to implement them.
1632
1633
1634 @subsubsection tutorial-introspection-is_valid-non_static Non-static members
1635
1636 The first idiom we'll look at is checking for the presence of a non-static
1637 member. We can do it in a similar way as we did for the previous example:
1638
1639 @snippet example/tutorial/introspection.cpp non_static_member_from_object
1640
1641 Notice how we cast the result of `x.member` to `void`? This is to make sure
1642 that our detection also works for types that can't be returned from functions,
1643 like array types. Also, it is important to use a reference as the parameter to
1644 our generic lambda, because that would otherwise require `x` to be
1645 [CopyConstructible][], which is not what we're trying to check. This approach
1646 is simple and the most convenient when an object is available. However, when
1647 the checker is intended to be used with no object around, the following
1648 alternate implementation can be better suited:
1649
1650 @snippet example/tutorial/introspection.cpp non_static_member_from_type
1651
1652 This validity checker is different from what we saw earlier because the
1653 generic lambda is not expecting an usual object anymore; it is now expecting
1654 a `type` (which is an object, but still represents a type). We then use the
1655 `hana::traits::declval` _lifted metafunction_ from the `<boost/hana/traits.hpp>`
1656 header to create an rvalue of the type represented by `t`, which we can then
1657 use to check for a non-static member. Finally, instead of passing an actual
1658 object to `has_member` (like `Foo{}` or `Bar{}`), we now pass a `type_c<...>`.
1659 This implementation is ideal for when no object is lying around.
1660
1661
1662 @subsubsection tutorial-introspection-is_valid-static Static members
1663
1664 Checking for a static member is easy, and it is provided for completeness:
1665
1666 @snippet example/tutorial/introspection.cpp static_member
1667
1668 Again, we expect a `type` to be passed to the checker. Inside the generic
1669 lambda, we use `decltype(t)::%type` to fetch the actual C++ type represented
1670 by the `t` object, as explained in the section on [type computations]
1671 (@ref tutorial-type-working). Then, we fetch the static member inside
1672 that type and cast it to `void`, for the same reason as we did for non-static
1673 members.
1674
1675
1676 @subsubsection tutorial-introspection-is_valid-typename Nested type names
1677
1678 Checking for a nested type name is not hard, but it is slightly more
1679 convoluted than the previous cases:
1680
1681 @snippet example/tutorial/introspection.cpp nested_type_name
1682
1683 One might wonder why we use `-> hana::type<typename-expression>` instead
1684 of simply `-> typename-expression`. Again, the reason is that we want to
1685 support types that can't be returned from functions, like array types or
1686 incomplete types.
1687
1688
1689 @subsubsection tutorial-introspection-is_valid-template Nested templates
1690
1691 Checking for a nested template name is similar to checking for a nested type
1692 name, except we use the `template_<...>` variable template instead of
1693 `type<...>` in the generic lambda:
1694
1695 @snippet example/tutorial/introspection.cpp nested_template
1696
1697
1698 @subsection tutorial-introspection-sfinae Taking control of SFINAE
1699
1700 Doing something only if an expression is well-formed is a very common pattern
1701 in C++. Indeed, the `optionalToString` function is just one instance of the
1702 following pattern, which is very general:
1703
1704 @code{cpp}
1705 template <typename T>
1706 auto f(T x) {
1707 if (some expression involving x is well-formed)
1708 return something involving x;
1709 else
1710 return something else;
1711 }
1712 @endcode
1713
1714 To encapsulate this pattern, Hana provides the `sfinae` function, which allows
1715 executing an expression, but only if it is well-formed:
1716
1717 @snippet example/tutorial/introspection.sfinae.cpp maybe_add
1718
1719 Here, we create a `maybe_add` function, which is simply a generic lambda
1720 wrapped with Hana's `sfinae` function. `maybe_add` is a function which takes
1721 two inputs and returns `just` the result of the generic lambda if that call
1722 is well-formed, and `nothing` otherwise. `just(...)` and `nothing` both belong
1723 to a type of container called `hana::optional`, which is essentially a
1724 compile-time `std::optional`. All in all, `maybe_add` is morally equivalent
1725 to the following function returning a `std::optional`, except that the check
1726 is done at compile-time:
1727
1728 @code{cpp}
1729 auto maybe_add = [](auto x, auto y) {
1730 if (x + y is well formed)
1731 return std::optional<decltype(x + y)>{x + y};
1732 else
1733 return std::optional<???>{};
1734 };
1735 @endcode
1736
1737 It turns out that we can take advantage of `sfinae` and `optional` to
1738 implement the `optionalToString` function as follows:
1739
1740 @snippet example/tutorial/introspection.sfinae.cpp optionalToString.sfinae
1741
1742 First, we wrap `toString` with the `sfinae` function. Hence, `maybe_toString`
1743 is a function which either returns `just(x.toString())` if that is well-formed,
1744 or `nothing` otherwise. Secondly, we use the `.value_or()` function to extract
1745 the optional value from the container. If the optional value is `nothing`,
1746 `.value_or()` returns the default value given to it; otherwise, it returns the
1747 value inside the `just` (here `x.toString()`). This way of seeing SFINAE as a
1748 special case of computations that might fail is very clean and powerful,
1749 especially since `sfinae`'d functions can be combined through the
1750 `hana::optional` `Monad`, which is left to the reference documentation.
1751
1752
1753 @subsection tutorial-introspection-adapting Introspecting user-defined types
1754
1755 Have you ever wanted to iterate over the members of a user-defined type? The
1756 goal of this section is to show you how Hana can be used to do it quite easily.
1757 To allow working with user-defined types, Hana defines the `Struct` concept.
1758 Once a user-defined type is a model of that concept, one can iterate over the
1759 members of an object of that type and query other useful information. To turn
1760 a user-defined type into a `Struct`, a couple of options are available. First,
1761 you may define the members of your user-defined type with the
1762 `BOOST_HANA_DEFINE_STRUCT` macro:
1763
1764 @snippet example/tutorial/introspection.adapt.cpp BOOST_HANA_DEFINE_STRUCT
1765
1766 This macro defines two members (`name` and `age`) with the given types. Then,
1767 it defines some boilerplate inside a `Person::hana` nested `struct`, which is
1768 required to make `Person` a model of the `Struct` concept. No constructors are
1769 defined (so [POD-ness][POD] is retained), the members are defined in the same
1770 order as they appear here and the macro can be used with template `struct`s
1771 just as well, and at any scope. Also note that you are free to add more
1772 members to the `Person` type after or before you use the macro. However,
1773 only members defined with the macro will be picked up when introspecting the
1774 `Person` type. Easy enough? Now, a `Person` can be accessed programmatically:
1775
1776 @snippet example/tutorial/introspection.adapt.cpp for_each
1777
1778 Iteration over a `Struct` is done as if the `Struct` was a sequence of pairs,
1779 where the first element of a pair is the key associated to a member, and the
1780 second element is the member itself. When a `Struct` is defined through the
1781 `BOOST_HANA_DEFINE_STRUCT` macro, the key associated to any member is a
1782 compile-time `hana::string` representing the name of that member. This is why
1783 the function used with `for_each` takes a single argument `pair`, and then
1784 uses `first` and `second` to access the subparts of the pair. Also, notice
1785 how the `to<char const*>` function is used on the name of the member? This
1786 converts the compile-time string to a `constexpr char const*` so it can
1787 `cout`ed. Since it can be annoying to always use `first` and `second` to
1788 fetch the subparts of the pair, we can also use the `fuse` function to wrap
1789 our lambda and make it a binary lambda instead:
1790
1791 @snippet example/tutorial/introspection.adapt.cpp for_each.fuse
1792
1793 Now, it looks much cleaner. As we just mentioned, `Struct`s are seen as a kind
1794 of sequence of pairs for the purpose of iteration. In fact, a `Struct` can
1795 even be searched like an associative data structure whose keys are the names
1796 of the members, and whose values are the members themselves:
1797
1798 @snippet example/tutorial/introspection.adapt.cpp at_key
1799
1800 @note
1801 The `_s` user-defined literal creates a compile-time `hana::string`. It is
1802 located in the `boost::hana::literals` namespace. Note that it is not part
1803 of the standard yet, but it is supported by Clang and GCC. If you want to
1804 stay 100% standard, you can use the `BOOST_HANA_STRING` macro instead.
1805
1806 The main difference between a `Struct` and a `hana::map` is that a map can be
1807 modified (keys can be added and removed), while a `Struct` is immutable.
1808 However, you can easily convert a `Struct` into a `hana::map` with `to<map_tag>`,
1809 and then you can manipulate it in a more flexible way.
1810
1811 @snippet example/tutorial/introspection.adapt.cpp to<map_tag>
1812
1813 Using the `BOOST_HANA_DEFINE_STRUCT` macro to adapt a `struct` is convenient,
1814 but sometimes one can't modify the type that needs to be adapted. In these
1815 cases, the `BOOST_HANA_ADAPT_STRUCT` macro can be used to adapt a `struct` in
1816 a ad-hoc manner:
1817
1818 @snippet example/tutorial/introspection.adapt.cpp BOOST_HANA_ADAPT_STRUCT
1819
1820 @note
1821 The `BOOST_HANA_ADAPT_STRUCT` macro must be used at global scope.
1822
1823 The effect is exactly the same as with the `BOOST_HANA_DEFINE_STRUCT` macro,
1824 except you do not need to modify the type you want to adapt, which is
1825 sometimes useful. Finally, it is also possible to define custom accessors
1826 by using the `BOOST_HANA_ADAPT_ADT` macro:
1827
1828 @snippet example/tutorial/introspection.adapt.cpp BOOST_HANA_ADAPT_ADT
1829
1830 This way, the names used to access the members of the `Struct` will be those
1831 specified, and the associated function will be called on the `Struct` when
1832 retrieving that member. Before we move on to a concrete example of using these
1833 introspection features, it should also be mentioned that `struct`s can be
1834 adapted without using macros. This advanced interface for defining `Struct`s
1835 can be used for example to specify keys that are not compile-time strings.
1836 The advanced interface is described in the documentation of the `Struct`
1837 concept.
1838
1839
1840 @subsection tutorial-introspection-json Example: generating JSON
1841
1842 Let's now move on with a concrete example of using the introspection
1843 capabilities we just presented for printing custom objects as JSON.
1844 Our end goal is to have something like this:
1845
1846 @snippet example/tutorial/introspection.json.cpp usage
1847
1848 And the output, after passing it through a JSON pretty-printer,
1849 should look like
1850
1851 @code{.json}
1852 [
1853 {
1854 "name": "John",
1855 "last_name": "Doe",
1856 "age": 30
1857 },
1858 {
1859 "brand": "Audi",
1860 "model": "A4"
1861 },
1862 {
1863 "brand": "BMW",
1864 "model": "Z3"
1865 }
1866 ]
1867 @endcode
1868
1869 First, let's define a couple of utility functions to make string manipulation
1870 easier:
1871
1872 @snippet example/tutorial/introspection.json.cpp utilities
1873
1874 The `quote` and the `to_json` overloads are pretty self-explanatory. The
1875 `join` function, however, might need a bit of explanation. Basically, the
1876 `intersperse` function takes a sequence and a separator, and returns a new
1877 sequence with the separator in between each pair of elements of the original
1878 sequence. In other words, we take a sequence of the form `[x1, ..., xn]` and
1879 turn it into a sequence of the form `[x1, sep, x2, sep, ..., sep, xn]`.
1880 Finally, we fold the resulting sequence with the `_ + _` function object,
1881 which is equivalent to `std::plus<>{}`. Since our sequence contains
1882 `std::string`s (we assume it does), this has the effect of concatenating
1883 all the strings of the sequence into one big string. Now, let's define
1884 how to print a `Sequence`:
1885
1886 @snippet example/tutorial/introspection.json.cpp Sequence
1887
1888 First, we use the `transform` algorithm to turn our sequence of objects into
1889 a sequence of `std::string`s in JSON format. Then, we join that sequence with
1890 commas and we enclose it with `[]` to denote a sequence in JSON notation.
1891 Simple enough? Let's now take a look at how to print user-defined types:
1892
1893 @snippet example/tutorial/introspection.json.cpp Struct
1894
1895 Here, we use the `keys` method to retrieve a `tuple` containing the names of
1896 the members of the user-defined type. Then, we `transform` that sequence into
1897 a sequence of `"name" : member` strings, which we then `join` and enclose with
1898 `{}`, which is used to denote objects in JSON notation. And that's it!
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909 @section tutorial-containers Generalities on containers
1910
1911 ------------------------------------------------------------------------------
1912 This section explains several important notions about Hana's containers: how
1913 to create them, the lifetime of their elements and other concerns.
1914
1915
1916 @subsection tutorial-containers-creating Container creation
1917
1918 While the usual way of creating an object in C++ is to use its constructor,
1919 heterogeneous programming makes things a bit more complicated. Indeed, in
1920 most cases, one is not interested in (or even aware of) the actual type of
1921 the heterogeneous container to be created. At other times, one could write
1922 out that type explicitly, but it would be redundant or cumbersome to do so.
1923 For this reason, Hana uses a different approach borrowed from `std::make_tuple`
1924 to create new containers. Much like one can create a `std::tuple` with
1925 `std::make_tuple`, a `hana::tuple` can be created with `hana::make_tuple`.
1926 However, more generally, containers in Hana may be created with the `make`
1927 function:
1928
1929 @snippet example/tutorial/containers.cpp make<tuple_tag>
1930
1931 In fact, `make_tuple` is just a shortcut for `make<tuple_tag>` so you don't
1932 have to type `boost::hana::make<boost::hana::tuple_tag>` when you are out of
1933 Hana's namespace. Simply put, `make<...>` is is used all around the library
1934 to create different types of objects, thus generalizing the `std::make_xxx`
1935 family of functions. For example, one can create a `hana::range` of
1936 compile-time integers with `make<range_tag>`:
1937
1938 @snippet example/tutorial/containers.cpp make<range_tag>
1939
1940 > These types with a trailing `_tag` are dummy types __representing__ a family
1941 > of heterogeneous containers (`hana::tuple`, `hana::map`, etc..). Tags are
1942 > documented in the section on [Hana's core](@ref tutorial-core-tags).
1943
1944 For convenience, whenever a component of Hana provides a `make<xxx_tag>`
1945 function, it also provides the `make_xxx` shortcut to reduce typing. Also, an
1946 interesting point that can be raised in this example is the fact that `r` is
1947 `constexpr`. In general, whenever a container is initialized with constant
1948 expressions only (which is the case for `r`), that container may be marked
1949 as `constexpr`.
1950
1951 So far, we have only created containers with the `make_xxx` family of
1952 functions. However, some containers do provide constructors as part of
1953 their interface. For example, one can create a `hana::tuple` just like
1954 one would create a `std::tuple`:
1955
1956 @snippet example/tutorial/containers.cpp tuple_constructor
1957
1958 When constructors (or any member function really) are part of the public
1959 interface, they will be documented on a per-container basis. However,
1960 in the general case, one should not take for granted that a container
1961 can be constructed as the tuple was constructed above. For example,
1962 trying to create a `hana::range` that way will __not__ work:
1963
1964 @code{.cpp}
1965 hana::range<???> xs{hana::int_c<3>, hana::int_c<10>};
1966 @endcode
1967
1968 In fact, we can't even specify the type of the object we'd like to create in
1969 that case, because the exact type of a `hana::range` is implementation-defined,
1970 which brings us to the next section.
1971
1972
1973 @subsection tutorial-containers-types Container types
1974
1975 The goal of this section is to clarify what can be expected from the types of
1976 Hana's containers. Indeed, so far, we always let the compiler deduce the
1977 actual type of containers by using the `make_xxx` family of functions along
1978 with `auto`. But in general, what can we say about the type of a container?
1979
1980 @snippet example/tutorial/containers.cpp types
1981
1982 The answer is that it depends. Some containers have well defined types, while
1983 others do not specify their representation. In this example, the type of the
1984 object returned by `make_tuple` is well-defined, while the type returned by
1985 `make_range` is implementation-defined:
1986
1987 @snippet example/tutorial/containers.cpp types_maximally_specified
1988
1989 This is documented on a per-container basis; when a container has an
1990 implementation-defined representation, a note explaining exactly what
1991 can be expected from that representation is included in the container's
1992 description. There are several reasons for leaving the representation of
1993 a container unspecified; they are explained in the
1994 [rationales](@ref tutorial-rationales-container_representation).
1995 When the representation of a container is implementation-defined, one must
1996 be careful not to make any assumptions about it, unless those assumption
1997 are explicitly allowed in the documentation of the container.
1998
1999
2000 @subsubsection tutorial-containers-types-overloading Overloading on container types
2001
2002 While necessary, leaving the type of some containers unspecified makes some
2003 things very difficult to achieve, like overloading functions on heterogeneous
2004 containers:
2005
2006 @code{cpp}
2007 template <typename T>
2008 void f(std::vector<T> xs) {
2009 // ...
2010 }
2011
2012 template <typename ...???>
2013 void f(unspecified-range-type<???> r) {
2014 // ...
2015 }
2016 @endcode
2017
2018 The `is_a` utility is provided for this reason (and others). `is_a` allows
2019 checking whether a type is a precise kind of container using its tag,
2020 regardless of the actual type of the container. For example, the above
2021 example could be rewritten as
2022
2023 @snippet example/tutorial/containers.cpp overloading
2024
2025 This way, the second overload of `f` will only match when `R` is a type whose
2026 tag is `range_tag`, regardless of the exact representation of that range. Of
2027 course, `is_a` can be used with any kind of container: `tuple`, `map`, `set`
2028 and so on.
2029
2030
2031 @subsection tutorial-containers-elements Container elements
2032
2033 In Hana, containers own their elements. When a container is created, it makes
2034 a _copy_ of the elements used to initialize it and stores them inside the
2035 container. Of course, unnecessary copies are avoided by using move semantics.
2036 Because of those owning semantics, the lifetime of the objects inside the
2037 container is the same as that of the container.
2038
2039 @snippet example/tutorial/containers.cpp lifetime
2040
2041 Much like containers in the standard library, containers in Hana expect their
2042 elements to be objects. For this reason, references _may not_ be stored in
2043 them. When references must be stored inside a container, one should use a
2044 `std::reference_wrapper` instead:
2045
2046 @snippet example/tutorial/containers.cpp reference_wrapper
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057 @section tutorial-algorithms Generalities on algorithms
2058
2059 ------------------------------------------------------------------------------
2060 Much like the previous section introduced general but important notions about
2061 heterogeneous containers, this section introduces general notions about
2062 heterogeneous algorithms.
2063
2064
2065 @subsection tutorial-algorithms-value By-value semantics
2066
2067 Algorithms in Hana always return a new container holding the result. This
2068 allows one to easily chain algorithms by simply using the result of the first
2069 as the input of the second. For example, to apply a function to every element
2070 of a tuple and then reverse the result, one simply has to connect the `reverse`
2071 and `transform` algorithms:
2072
2073 @snippet example/tutorial/algorithms.cpp reverse_transform
2074
2075 This is different from the algorithms of the standard library, where one has
2076 to provide iterators to the underlying sequence. For reasons documented in the
2077 [rationales](@ref tutorial-rationales-iterators), an iterator-based design was
2078 considered but was quickly dismissed in favor of composable and efficient
2079 abstractions better suited to the very particular context of heterogeneous
2080 programming.
2081
2082 One might also think that returning full sequences that own their elements
2083 from an algorithm would lead to tons of undesirable copies. For example, when
2084 using `reverse` and `transform`, one could think that an intermediate copy is
2085 made after the call to `transform`:
2086
2087 @snippet example/tutorial/algorithms.cpp reverse_transform_copy
2088
2089 To make sure this does not happen, Hana uses perfect forwarding and move
2090 semantics heavily so it can provide an almost optimal runtime performance.
2091 So instead of doing a copy, a move occurs between `reverse` and `transform`:
2092
2093 @snippet example/tutorial/algorithms.cpp reverse_transform_move
2094
2095 Ultimately, the goal is that code written using Hana should be equivalent to
2096 clever hand-written code, except it should be enjoyable to write. Performance
2097 considerations are explained in depth in their own [section]
2098 (@ref tutorial-performance).
2099
2100
2101 @subsection tutorial-algorithms-laziness (Non-)Laziness
2102
2103 Algorithms in Hana are not lazy. When an algorithm is called, it does its
2104 job and returns a new sequence containing the result, end of the story.
2105 For example, calling the `permutations` algorithm on a large sequence is
2106 a stupid idea, because Hana will actually compute all the permutations:
2107
2108 @code{cpp}
2109 auto perms = hana::permutations(hana::make_tuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
2110 // perms has 3 628 800 elements, and your compiler just crashed
2111 @endcode
2112
2113 To contrast, algorithms in Boost.Fusion return views which hold the original
2114 sequence by reference and apply the algorithm on demand, as the elements of
2115 the sequence are accessed. This leads to subtle lifetime issues, like having
2116 a view that refers to a sequence that was destroyed. Hana's design assumes
2117 that most of the time, we want to access all or almost all the elements in a
2118 sequence anyway, and hence performance is not a big argument in favor of
2119 laziness.
2120
2121
2122 @subsection tutorial-algorithms-codegen What is generated?
2123
2124 Algorithms in Hana are a bit special with respect to the runtime code they are
2125 expanded into. The goal of this subsection is not to explain exactly what code
2126 is generated, which depends on the compiler anyway, but to give a feel for
2127 things. Basically, a Hana algorithm is like an unrolled version of an
2128 equivalent classical algorithm. Indeed, since the bounds of the processed
2129 sequence are known at compile-time, it makes sense that we can unroll the
2130 loop over the sequence. For example, let's consider the `for_each` algorithm:
2131
2132 @code{cpp}
2133 auto xs = hana::make_tuple(0, 1, 2, 3);
2134 hana::for_each(xs, f);
2135 @endcode
2136
2137 If `xs` was a runtime sequence instead of a tuple, its length would only be
2138 known at runtime and the above code would have to be implemented as a loop:
2139
2140 @code{cpp}
2141 for (int i = 0; i < xs.size(); ++i) {
2142 f(xs[i]);
2143 }
2144 @endcode
2145
2146 However, in our case, the length of the sequence is known at compile-time and
2147 so we don't have to check the index at each iteration. Hence, we can just
2148 write:
2149
2150 @code{cpp}
2151 f(xs[0_c]);
2152 f(xs[1_c]);
2153 f(xs[2_c]);
2154 f(xs[3_c]);
2155 @endcode
2156
2157 The main difference here is that no bound checking and index increment is done
2158 at each step, because there is no index anymore; the loop was effectively
2159 unrolled. In some cases, this can be desirable for performance reasons. In
2160 other cases, this can be detrimental to performance because it causes the
2161 code size to grow. As always, performance is a tricky subject and whether
2162 you actually want loop unrolling to happen should be tackled on a case-by-case
2163 basis. As a rule of thumb, algorithms processing all (or a subset) of the
2164 elements of a container are unrolled. In fact, if you think about it, this
2165 unrolling is the only way to go for heterogeneous sequences, because different
2166 elements of the sequence may have different types. As you might have noticed,
2167 we're not using normal indices into the tuple, but compile-time indices, which
2168 can't be generated by a normal `for` loop. In other words, the following does
2169 not make sense:
2170
2171 @code{cpp}
2172 for (??? i = 0_c; i < xs.size(); ++i) {
2173 f(xs[i]);
2174 }
2175 @endcode
2176
2177
2178 @subsection tutorial-algorithms-effects Side effects and purity
2179
2180 By default, Hana assumes functions to be pure. A pure function is a function
2181 that has no side-effects at all. In other words, it is a function whose effect
2182 on the program is solely determined by its return value. In particular, such a
2183 function may not access any state that outlives a single invocation of the
2184 function. These functions have very nice properties, like the ability to
2185 reason mathematically about them, to reorder or even eliminate calls, and
2186 so on. Except where specified otherwise, all functions used with Hana (i.e.
2187 used in higher order algorithms) should be pure. In particular, functions
2188 passed to higher order algorithms are not guaranteed to be called any
2189 specific number of times. Furthermore, the order of execution is generally
2190 not specified and should therefore not be taken for granted. If this lack of
2191 guarantees about function invocations seems crazy, consider the following use
2192 of the `any_of` algorithm:
2193
2194 @snippet example/tutorial/algorithms.cpp effects
2195
2196 @note
2197 For this to work, the external adapters for `std::integral_constant` contained
2198 in `<boost/hana/ext/std/integral_constant.hpp>` must be included.
2199
2200 According to the previous section on unrolling, this algorithm should be
2201 expanded into something like:
2202
2203 @code{cpp}
2204 auto xs = hana::make_tuple("hello"s, 1.2, 3);
2205 auto pred = [](auto x) { return std::is_integral<decltype(x)>{}; };
2206
2207 auto r = hana::bool_c<
2208 pred(xs[0_c]) ? true :
2209 pred(xs[1_c]) ? true :
2210 pred(xs[2_c]) ? true :
2211 false
2212 >;
2213
2214 BOOST_HANA_CONSTANT_CHECK(r);
2215 @endcode
2216
2217 Of course, the above code can't work as-is, because we're calling `pred` inside
2218 something that would have to be a constant expression, but `pred` is a lambda
2219 (and lambdas can't be called in constant expressions). However, whether any of
2220 these objects has an integral type is clearly known at compile-time, and hence
2221 we would expect that computing the answer only involves compile-time
2222 computations. In fact, this is exactly what Hana does, and the above
2223 algorithm is expanded into something like:
2224
2225 @snippet example/tutorial/algorithms.cpp effects.codegen
2226
2227 @note
2228 As you will be able to deduce from the next section on cross-phase computations,
2229 the implementation of `any_of` must actually be more general than this. However,
2230 this [lie-to-children][] is perfect for educational purposes.
2231
2232 As you can see, the predicate is never even executed; only its result type on
2233 a particular object is used. Regarding the order of evaluation, consider the
2234 `transform` algorithm, which is specified (for tuples) as:
2235
2236 @code{cpp}
2237 hana::transform(hana::make_tuple(x1, ..., xn), f) == hana::make_tuple(f(x1), ..., f(xn))
2238 @endcode
2239
2240 Since `make_tuple` is a function, and since the evaluation order for the
2241 arguments of a function is unspecified, the order in which `f` is called
2242 on each element of the tuple is unspecified too. If one sticks to pure
2243 functions, everything works fine and the resulting code is often easier
2244 to understand. However, some exceptional algorithms like `for_each` do
2245 expect impure functions, and they guarantee an order of evaluation. Indeed,
2246 a `for_each` algorithm that would only take pure functions would be pretty
2247 much useless. When an algorithm can accept an impure function or guarantees
2248 some order of evaluation, the documentation for that algorithm will mention
2249 it explicitly. However, by default, no guarantees may be taken for granted.
2250
2251
2252 @subsection tutorial-algorithms-cross_phase Cross-phase algorithms
2253
2254 This section introduces the notion of cross-phase computations and algorithms.
2255 In fact, we have already used cross-phase algorithms in the [quick start]
2256 (@ref tutorial-quickstart), for example with `filter`, but we did not explain
2257 exactly what was happening at that time. But before we introduce cross-phase
2258 algorithms, let's define what we mean by _cross-phase_. The phases we're
2259 referring to here are the compilation and the execution of a program. In C++
2260 as in most statically typed languages, there is a clear distinction between
2261 compile-time and runtime; this is called phase distinction. When we speak of
2262 a cross-phase computation, we mean a computation that is somehow performed
2263 across those phases; i.e. that is partly executed at compile-time and partly
2264 executed at runtime.
2265
2266 Like we saw in earlier examples, some functions are able to return something
2267 that can be used at compile-time even when they are called on a runtime value.
2268 For example, let's consider the `length` function applied to a non-`constexpr`
2269 container:
2270
2271 @snippet example/tutorial/algorithms.cpp cross_phase.setup
2272
2273 Obviously, the tuple can't be made `constexpr`, since it contains runtime
2274 `std::string`s. Still, even though it is not called on a constant expression,
2275 `length` returns something that can be used at compile-time. If you think of
2276 it, the size of the tuple is known at compile-time regardless of its content,
2277 and hence it would only make sense for this information to be available to us
2278 at compile-time. If that seems surprising, think about `std::tuple` and
2279 `std::tuple_size`:
2280
2281 @snippet example/tutorial/algorithms.cpp cross_phase.std::tuple_size
2282
2283 Since the size of the tuple is encoded in its type, it is always available
2284 at compile-time regardless of whether the tuple is `constexpr` or not. In Hana,
2285 this is implemented by having `length` return an `IntegralConstant`. Since an
2286 `IntegralConstant`'s value is encoded in its type, the result of `length` is
2287 contained in the type of the object it returns, and the length is therefore
2288 known at compile-time. Because `length` goes from a runtime value (the
2289 container) to a compile-time value (the `IntegralConstant`), `length` is a
2290 trivial example of a cross-phase algorithm (trivial because it does not really
2291 manipulate the tuple). Another algorithm that is very similar to `length` is
2292 the `is_empty` algorithm, which returns whether a container is empty:
2293
2294 @snippet example/tutorial/algorithms.cpp cross_phase.is_empty
2295
2296 More generally, any algorithm that takes a container whose value is known at
2297 runtime but queries something that can be known at compile-time should be able
2298 to return an `IntegralConstant` or another similar compile-time value. Let's
2299 make things slightly more complicated by considering the `any_of` algorithm,
2300 which we already encountered in the previous section:
2301
2302 @snippet example/tutorial/algorithms.cpp cross_phase.any_of_runtime
2303
2304 In this example, the result can't be known at compile-time, because the
2305 predicate returns a `bool` that is the result of comparing two `std::string`s.
2306 Since `std::string`s can't be compared at compile-time, the predicate must
2307 operate at runtime, and the overall result of the algorithm can then only be
2308 known at runtime too. However, let's say we used `any_of` with the following
2309 predicate instead:
2310
2311 @snippet example/tutorial/algorithms.cpp cross_phase.any_of_compile_time
2312
2313 @note
2314 For this to work, the external adapters for `std::integral_constant` contained
2315 in `<boost/hana/ext/std/integral_constant.hpp>` must be included.
2316
2317 First, since the predicate is only querying information about the type of each
2318 element of the tuple, it is clear that its result can be known at compile-time.
2319 Since the number of elements in the tuple is also known at compile-time, the
2320 overall result of the algorithm can, in theory, be known at compile-time. More
2321 precisely, what happens is that the predicate returns a value initialized
2322 `std::is_same<...>`, which inherits from `std::integral_constant`. Hana
2323 recognizes these objects, and the algorithm is written in such a way that it
2324 preserves the `compile-time`ness of the predicate's result. In the end,
2325 `any_of` hence returns an `IntegralConstant` holding the result of the
2326 algorithm, and we use the compiler's type deduction in a clever way to make
2327 it look easy. Hence, it would be equivalent to write (but then you would need
2328 to already know the result of the algorithm!):
2329
2330 @snippet example/tutorial/algorithms.cpp cross_phase.any_of_explicit
2331
2332 Ok, so some algorithms are able to return compile-time values when their input
2333 satisfies some constraints with respect to `compile-time`ness. However, other
2334 algorithms are more restrictive and they _require_ their inputs to satisfy some
2335 constraints regarding `compile-time`ness, without which they are not able to
2336 operate at all. An example of this is `filter`, which takes a sequence and a
2337 predicate, and returns a new sequence containing only those elements for which
2338 the predicate is satisfied. `filter` requires the predicate to return an
2339 `IntegralConstant`. While this requirement may seem stringent, it really makes
2340 sense if you think about it. Indeed, since we're removing some elements from
2341 the heterogeneous sequence, the type of the resulting sequence depends on the
2342 result of the predicate. Hence, the result of the predicate has to be known at
2343 compile-time for the compiler to be able to assign a type to the returned
2344 sequence. For example, consider what happens when we try to filter a
2345 heterogeneous sequence as follows:
2346
2347 @code{cpp}
2348 auto animals = hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});
2349
2350 auto no_garfield = hana::filter(animals, [](auto animal) {
2351 return animal.name != "Garfield"s;
2352 });
2353 @endcode
2354
2355 Clearly, we know that the predicate will only return false on the second
2356 element, and hence the result _should be_ a `[Fish, Dog]` tuple. However,
2357 the compiler has no way of knowing this since the predicate's result is the
2358 result of a runtime computation, which happens way after the compiler has
2359 finished its job. Hence, the compiler does not have enough information to
2360 determine the return type of the algorithm. However, we could `filter` the
2361 same sequence with any predicate whose result is available at compile-time:
2362
2363 @snippet example/tutorial/algorithms.cpp cross_phase.filter
2364
2365 Since the predicate returns an `IntegralConstant`, we know which elements
2366 of the heterogeneous sequence we'll be keeping at compile-time. Hence, the
2367 compiler is able to figure out the return type of the algorithm. Other
2368 algorithms like `partition` and `sort` work similarly; special algorithm
2369 requirements are always documented, just read the reference documentation
2370 of an algorithm before using it to avoid surprises.
2371
2372 This is the end of the section on algorithms. While this constitutes a fairly
2373 complete explanation of phase interaction inside algorithms, a deeper
2374 understanding can be gained by reading the [advanced section]
2375 (@ref tutorial-appendix-constexpr) on `constexpr` and the reference
2376 for `Constant` and `IntegralConstant`.
2377
2378
2379 @warning
2380 Hana's algorithms are `constexpr` function objects instead of being template
2381 functions. This allows passing them to higher-order algorithms, which is very
2382 useful. However, since those function objects are defined at namespace scope
2383 in the header files, this causes each translation unit to see a different
2384 algorithm object. Hence, the address of an algorithm function object is not
2385 guaranteed to be unique across translation units, which can cause an ODR
2386 violation if one relies on such an address. So, in short, do not rely on the
2387 uniqueness of the address of any global object provided by Hana, which does
2388 not make sense in the general case anyway because such objects are `constexpr`.
2389 See [issue #76](https://github.com/boostorg/hana/issues/76) for more information.
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400 @section tutorial-performance Performance considerations
2401
2402 ------------------------------------------------------------------------------
2403 C++ programmers love performance, so here's a whole section dedicated to it.
2404 Since Hana lives on the frontier between runtime and compile-time computations,
2405 we are not only interested in runtime performance, but also compile-time
2406 performance. Since both topics are pretty much disjoint, we treat them
2407 separately below.
2408
2409 @note
2410 The benchmarks presented in this section are updated automatically when we
2411 push to the repository. If you notice results that do not withstand the
2412 claims made here, open a [GitHub issue][Hana.issues]; it could be a
2413 performance regression.
2414
2415 @warning
2416 As of writing this, not all of Hana's containers are optimized. Implementing
2417 Hana was a big enough challenge that containers were initially written naively
2418 and are now in the process of being rigorously optimized. In particular, the
2419 associative containers (`hana::map` and `hana::set`) have a pretty bad
2420 compile-time behavior because of their naive implementation, and their runtime
2421 behavior also seems to be problematic in some cases. Improving this situation
2422 is in the TODO list.
2423
2424
2425 @subsection tutorial-performance-compile Compile-time performance
2426
2427 C++ metaprogramming brings its share of awful things. One of the most annoying
2428 and well-known problem associated to it is interminable compilation times.
2429 Hana claims to be more compile-time efficient than its predecessors; this is
2430 a bold claim and we will now try to back it. Of course, Hana can't do miracles;
2431 metaprogramming is a byproduct of the C++ template system and the compiler is
2432 not meant to be used as an interpreter for some meta language. However, by
2433 using cutting edge and intensely benchmarked techniques, Hana is able to
2434 minimize the strain on the compiler.
2435
2436 @note
2437 While Hana has better compile-times than pre-C++11 metaprogramming libraries,
2438 modern libraries supporting only type-level computations (such as [Brigand][])
2439 can provide better compile-times, at the cost of generality. Indeed, Hana's
2440 ability to manipulate runtime values comes at a compile-time cost, no matter
2441 how hard we try to mitigate it. If you want to use Hana for intensive type-level
2442 computations, you should benchmark and see whether it suits you.
2443
2444 Before we dive, let me make a quick note on the methodology used to measure
2445 compile-time performance in Hana. Previous metaprogramming libraries measured
2446 the compile-time complexity of their meta-algorithms and meta-sequences by
2447 looking at the number of instantiations the compiler had to perform. While
2448 easy to understand, this way of measuring the compile-time complexity actually
2449 does not give us a lot of information regarding the compilation time, which
2450 is what we're interested in minimizing at the end of the day. Basically, the
2451 reason for this is that template metaprogramming is such a twisted model of
2452 computation that it's very hard to find a standard way of measuring the
2453 performance of algorithms. Hence, instead of presenting meaningless complexity
2454 analyses, we prefer to benchmark everything on every supported compiler and to
2455 pick the best implementation on that compiler. Also note that the benchmarks
2456 we present here are quite precise. Indeed, even though we do not take multiple
2457 measurements and take their mean or something similar to reduce incertitude,
2458 the benchmarks are very stable when they are regenerated, which suggests a
2459 reasonably good precision. Now, let's dive.
2460
2461 First, Hana minimizes its dependency on the preprocessor. In addition to
2462 yielding cleaner error messages in many cases, this reduces the overall
2463 parsing and preprocessing time for header files. Also, because Hana only
2464 supports cutting edge compilers, there are very few workarounds in the
2465 library, which results in a cleaner and smaller library. Finally, Hana
2466 minimizes reliance on any kind of external dependencies. In particular,
2467 it only uses other Boost libraries in a few specific cases, and it does
2468 not rely on the standard library for the largest part. There are several
2469 reasons (other than include times) for doing so; they are documented in
2470 the [rationales](@ref tutorial-rationales-dependencies).
2471
2472 Below is a chart showing the time required to include different libraries. The
2473 chart shows the time for including everything in the (non-external) public API
2474 of each library. For example, for Hana this means the `<boost/hana.hpp>` header,
2475 which excludes the external adapters. For other libraries like Boost.Fusion,
2476 this means including all the public headers in the `boost/fusion/` directory,
2477 but not the adapters for external libraries like the MPL.
2478
2479 <div class="benchmark-chart"
2480 style="min-width: 310px; height: 400px; margin: 0 auto"
2481 data-dataset="benchmark.including.compile.json">
2482 </div>
2483
2484 In addition to reduced preprocessing times, Hana uses modern techniques to
2485 implement heterogeneous sequences and algorithms in the most compile-time
2486 efficient way possible. Before jumping to the compile-time performance of
2487 the algorithms, we will have a look at the compile-time cost of creating
2488 heterogeneous sequences. Indeed, since we will be presenting algorithms that
2489 work on sequences, we must be aware of the cost of creating the sequences
2490 themselves, since that will influence the benchmarks for the algorithms.
2491 The following chart presents the compile-time cost of creating a sequence
2492 of `n` heterogeneous elements.
2493
2494 <div class="benchmark-chart"
2495 style="min-width: 310px; height: 400px; margin: 0 auto"
2496 data-dataset="benchmark.make.compile.json">
2497 </div>
2498
2499 @note
2500 You can zoom on the chart by selecting an area to zoom into. Also, you can
2501 hide a series of points by clicking on it in the legend on the right.
2502
2503 The benchmark methodology is to always create the sequences in the most
2504 efficient way possible. For Hana and `std::tuple`, this simply means using
2505 the appropriate `make_tuple` function. However, for the MPL, this means
2506 creating a `mpl::vectorN` of size up to 20, and then using `mpl::push_back`
2507 to create larger vectors. We use a similar technique for Fusion sequences.
2508 The reason for doing so is that Fusion and MPL sequences have fixed size
2509 limits, and the techniques used here have been found to be the fastest way
2510 to create longer sequences.
2511
2512 For completeness, we also present the compile-time cost of creating a
2513 `std::array` with `n` elements. However, note that `std::array` can only
2514 hold elements with a single type, so we're comparing apples and oranges
2515 here. As you can see, the cost of creating a `std::array` is constant and
2516 essentially inexistent (the non-zero overhead is that of simply including
2517 the `<array>` header). Hence, while Hana provides improved compile-times
2518 over other heterogeneous containers, please stick with normal homogeneous
2519 containers if that's all you need for your application; your compile-times
2520 will be much faster that way.
2521
2522 You can also see that creating sequences has a non-negligible cost. Actually,
2523 this is really the most expensive part of doing heterogeneous computations,
2524 as you will see in the following charts. Hence, when you look at the charts
2525 below, keep in mind the cost of merely creating the sequences. Also note that
2526 only the most important algorithms will be presented here, but the [Metabench][]
2527 project provides micro benchmarks for compile-time performance for almost all
2528 of Hana's algorithms. Also, the benchmarks we present compare several different
2529 libraries. However, since Hana and Fusion can work with values and not only
2530 types, comparing their algorithms with type-only libraries like MPL is not
2531 really fair. Indeed, Hana and Fusion algorithms are more powerful since they
2532 also allow runtime effects to be performed. However, the comparison between
2533 Fusion and Hana is fair, because both libraries are just as powerful (strictly
2534 speaking). Finally, we can't show benchmarks of the algorithms for `std::tuple`,
2535 because the standard does not provide equivalent algorithms. Of course, we
2536 could use Hana's external adapters, but that would not be a faithful comparison.
2537
2538 The first algorithm which is ubiquitous in metaprogramming is `transform`.
2539 It takes a sequence and a function, and returns a new sequence containing the
2540 result of applying the function to each element. The following chart presents
2541 the compile-time performance of applying `transform` to a sequence of `n`
2542 elements. The `x` axis represents the number of elements in the sequence, and
2543 the `y` axis represents the compilation time in seconds. Also note that we're
2544 using the `transform` equivalent in each library; we're not using Hana's
2545 `transform` through the Boost.Fusion adapters, for example, because we really
2546 want to benchmark their implementation against ours.
2547
2548 <div class="benchmark-chart"
2549 style="min-width: 310px; height: 400px; margin: 0 auto"
2550 data-dataset="benchmark.transform.compile.json">
2551 </div>
2552
2553 Here, we can see that Hana's tuple performs better than all the other
2554 alternatives. This is mainly due to the fact that we use C++11 variadic
2555 parameter pack expansion to implement this algorithm under the hood, which
2556 is quite efficient.
2557
2558 Before we move on, it is important to mention something regarding the benchmark
2559 methodology for Fusion algorithms. Some algorithms in Fusion are lazy, which
2560 means that they don't actually perform anything, but simply return a modified
2561 view to the original data. This is the case of `fusion::transform`, which
2562 simply returns a transformed view that applies the function to each element
2563 of the original sequence as those elements are accessed. If we want to
2564 benchmark anything at all, we need to force the evaluation of that view, as
2565 would eventually happen when accessing the elements of the sequence in real
2566 code. However, for complex computations with multiple layers, a lazy approach
2567 may yield a substantially different compile-time profile. Of course, this
2568 difference is poorly represented in micro benchmarks, so keep in mind that
2569 these benchmarks only give a part of the big picture. For completeness in the
2570 rest of the section, we will mention when a Fusion algorithm is lazy, so that
2571 you know when we're _artificially_ forcing the evaluation of the algorithm for
2572 the purpose of benchmarking.
2573
2574 @note
2575 We are currently considering adding lazy views to Hana. If this feature is
2576 important to you, please let us know by commenting
2577 [this issue](https://github.com/boostorg/hana/issues/193).
2578
2579 The second important class of algorithms are folds. Folds can be used to
2580 implement many other algorithms like `count_if`, `minimum` and so on.
2581 Hence, a good compile-time performance for fold algorithms ensures a good
2582 compile-time performance for those derived algorithms, which is why we're
2583 only presenting folds here. Also note that all the non-monadic fold variants
2584 are somewhat equivalent in terms of compile-time, so we only present the left
2585 folds. The following chart presents the compile-time performance of applying
2586 `fold_left` to a sequence of `n` elements. The `x` axis represents the number
2587 of elements in the sequence, and the `y` axis represents the compilation time
2588 in seconds. The function used for folding is a dummy function that does nothing.
2589 In real code, you would likely fold with a nontrivial operation, so the curves
2590 would be worse than that. However, these are micro benchmarks and hence they
2591 only show the performance of the algorithm itself.
2592
2593 <div class="benchmark-chart"
2594 style="min-width: 310px; height: 400px; margin: 0 auto"
2595 data-dataset="benchmark.fold_left.compile.json">
2596 </div>
2597
2598 The third and last algorithm that we present here is the `find_if` algorithm.
2599 This algorithm is difficult to implement efficiently, because it requires
2600 stopping at the first element which satisfies the given predicate. For the
2601 same reason, modern techniques don't really help us here, so this algorithm
2602 constitutes a good test of the implementation quality of Hana, without taking
2603 into account the free lunch given to use by C++14.
2604
2605 <div class="benchmark-chart"
2606 style="min-width: 310px; height: 400px; margin: 0 auto"
2607 data-dataset="benchmark.find_if.compile.json">
2608 </div>
2609
2610 As you can see, Hana performs better than Fusion, and as well as MPL, yet
2611 Hana's `find_if` can be used with values too, unlike MPL's. This concludes
2612 the section on compile-time performance. In case you want to see the
2613 performance of an algorithm that we have not presented here, the [Metabench][]
2614 project provides compile-time benchmarks for most of Hana's algorithms.
2615
2616
2617 @subsection tutorial-performance-runtime Runtime performance
2618
2619 Hana was designed to be very efficient at runtime. But before we dive into the
2620 details, let's clarify one thing. Hana being a metaprogramming library which
2621 allows manipulating both types and values, it does not always make sense to
2622 even talk about runtime performance. Indeed, for type-level computations and
2623 computations on `IntegralConstant`s, runtime performance is simply not a
2624 concern, because the result of the computation is contained in a _type_, which
2625 is a purely compile-time entity. In other words, these computations involve
2626 only compile-time work, and no code is even generated to perform these
2627 computations at runtime. The only case where it makes sense to discuss runtime
2628 performance is when manipulating runtime values in heterogeneous containers
2629 and algorithms, because this is the only case where the compiler has to
2630 generate some runtime code. It is therefore only computations of this sort
2631 that we will be studying in the remainder of this section.
2632
2633 Like we did for compile-time benchmarks, the methodology used to measure
2634 runtime performance in Hana is data driven rather than analytical. In other
2635 words, instead of trying to determine the complexity of an algorithm by
2636 counting the number of basic operations it does as a function of the input
2637 size, we simply take measurements for the most interesting cases and see how
2638 it behaves. There are a couple of reasons for doing so. First, we do not
2639 expect Hana's algorithms to be called on large inputs since those algorithms
2640 work on heterogeneous sequences whose length must be known at compile-time.
2641 For example, if you tried to call the `find_if` algorithm on a sequence of
2642 100k elements, your compiler would simply die while trying to generate the
2643 code for this algorithm. Hence, algorithms can't be called on very large inputs
2644 and the analytical approach then loses a lot of its attractiveness. Secondly,
2645 processors have evolved into pretty complex beasts, and the actual performance
2646 you'll be able to squeeze out is actually controlled by much more than the
2647 mere number of steps your algorithm is doing. For example, bad cache behavior
2648 or branch misprediction could turn a theoretically efficient algorithm into a
2649 slowpoke, especially for small inputs. Since Hana causes a lot of unrolling to
2650 happen, these factors must be considered even more carefully and any analytical
2651 approach would probably only comfort us into thinking we're efficient. Instead,
2652 we want hard data, and pretty charts to display it!
2653
2654 @note
2655 Like for compile-time performance, we're forcing the evaluation of some Fusion
2656 algorithms that are normally lazy. Again, depending on the complexity of the
2657 computation, a lazy algorithm may cause substantially different code to be
2658 generated or a different design to be used, for better or worse. Keep this
2659 in mind when you look at these runtime benchmarks. If performance is absolutely
2660 critical to your application, you should profile _before_ and _after_ switching
2661 from Fusion to Hana. And let us know if Hana performs worse; we'll fix it!
2662
2663 There are a couple of different aspects we will want to benchmark. First, we
2664 will obviously want to benchmark the execution time of the algorithms.
2665 Secondly, because of the by-value semantics used throughout the library, we
2666 will also want to make sure that the minimum amount of data is copied around.
2667 Finally, we will want to make sure that using Hana does not cause too much
2668 code bloat because of unrolling, as explained in the [section]
2669 (@ref tutorial-algorithms-codegen) on algorithms.
2670
2671 Just like we studied only a couple of key algorithms for compile-time
2672 performance, we will focus on the runtime performance of a few algorithms.
2673 For each benchmarked aspect, we will compare the algorithm as implemented by
2674 different libraries. Our goal is to always be at least as efficient as
2675 Boost.Fusion, which is near from optimality in terms of runtime performance.
2676 For comparison, we also show the same algorithm as executed on a runtime
2677 sequence, and on a sequence whose length is known at compile-time but whose
2678 `transform` algorithm does not use explicit loop unrolling. All the benchmarks
2679 presented here are done in a _Release_ CMake configuration, which takes care
2680 of passing the proper optimization flags (usually `-O3`). Let's start with the
2681 following chart, which shows the execution time required to `transform`
2682 different kinds of sequences:
2683
2684 <div class="benchmark-chart"
2685 style="min-width: 310px; height: 400px; margin: 0 auto"
2686 data-dataset="benchmark.transform.execute.json">
2687 </div>
2688
2689 @note
2690 Keep in mind that `fusion::transform` is usually lazy, and we're forcing its
2691 evaluation for the purpose of benchmarking.
2692
2693 As you can see, Hana and Fusion are pretty much on the same line. `std::array`
2694 is slightly slower for larger collections data sets, and `std::vector` is
2695 noticeably slower for larger collections. Since we also want to look out for
2696 code bloat, let's take a look at the size of the executable generated for the
2697 exact same scenario:
2698
2699 <div class="benchmark-chart"
2700 style="min-width: 310px; height: 400px; margin: 0 auto"
2701 data-dataset="benchmark.transform.bloat.json">
2702 </div>
2703
2704 As you can see, code bloat does not seem to be an issue, at least not one that
2705 can be detected in micro benchmarks such as this one. Let's now take a look at
2706 the `fold` algorithm, which is used very frequently:
2707
2708 <div class="benchmark-chart"
2709 style="min-width: 310px; height: 400px; margin: 0 auto"
2710 data-dataset="benchmark.fold_left.execute.json">
2711 </div>
2712
2713 Here, you can see that everybody is performing pretty much the same, which
2714 is a good sign that Hana is at least not screwing things up.
2715 Again, let's look at the executable size:
2716
2717 <div class="benchmark-chart"
2718 style="min-width: 310px; height: 400px; margin: 0 auto"
2719 data-dataset="benchmark.fold_left.bloat.json">
2720 </div>
2721
2722 Here again, the code size did not explode. So at least for moderate usages of
2723 Hana (and Fusion for that matter, since they have the same problem), code
2724 bloat should not be a major concern. The containers in the charts we just
2725 presented contain randomly generated `int`s, which is cheap to copy around and
2726 lends itself well to micro benchmarks. However, what happens when we chain
2727 multiple algorithms on a container whose elements are expensive to copy? More
2728 generally, the question is: when an algorithm is passed a temporary object,
2729 does it seize the opportunity to avoid unnecessary copies? Consider:
2730
2731 @code{cpp}
2732 auto xs = hana::make_tuple("some"s, "huge"s, "string"s);
2733
2734 // No copy of xs's elements should be made: they should only be moved around.
2735 auto ys = hana::reverse(std::move(xs));
2736 @endcode
2737
2738 To answer this question, we'll look at the chart generated when benchmarking
2739 the above code for strings of about 1k characters. However, note that it does
2740 not really make sense to benchmark this for standard library algorithms,
2741 because they do not return containers.
2742
2743 <div class="benchmark-chart"
2744 style="min-width: 310px; height: 400px; margin: 0 auto"
2745 data-dataset="benchmark.reverse.move.json">
2746 </div>
2747
2748 @note
2749 Keep in mind that `fusion::reverse` is usually lazy, and we're forcing its
2750 evaluation for the purpose of benchmarking.
2751
2752 As you can see, Hana is faster than Fusion, probably because of a more
2753 consistent use of move semantics in the implementation. If we had not
2754 provided a temporary container to `reverse`, no move could have been
2755 performed by Hana and both libraries would have performed similarly:
2756
2757 <div class="benchmark-chart"
2758 style="min-width: 310px; height: 400px; margin: 0 auto"
2759 data-dataset="benchmark.reverse.nomove.json">
2760 </div>
2761
2762 This concludes the section on runtime performance. Hopefully you are now
2763 convinced that Hana was built for speed. Performance is important to us:
2764 if you ever encounter a scenario where Hana causes bad code to be generated
2765 (and the fault is not on the compiler), please open an [issue][Hana.issues]
2766 so the problem can be addressed.
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777 @section tutorial-ext Integration with external libraries
2778
2779 ------------------------------------------------------------------------------
2780
2781 Hana provides out-of-the-box integration with some existing libraries.
2782 Specifically, this means that you can use some containers from these
2783 libraries in Hana's algorithms by simply including the appropriate header
2784 making the bridge between Hana and the external component. This can be
2785 very useful for porting existing code from e.g. Fusion/MPL to Hana:
2786
2787 @snippet example/tutorial/ext/fusion_to_hana.cpp main
2788
2789 @note
2790 At this time, only adapters to use data types from other libraries inside Hana
2791 are provided; adapters for the other way around (using Hana containers inside
2792 other libraries) are not provided.
2793
2794 However, using external adapters has a couple of pitfalls. For example, after
2795 a while using Hana, you might become used to comparing Hana tuples using the
2796 normal comparison operators, or doing arithmetic with Hana `integral_constant`s.
2797 Of course, nothing guarantees that these operators are defined for external
2798 adapters too (and in general they won't be). Hence, you'll have to stick to
2799 the functions provided by Hana that implement these operators. For example:
2800
2801 @code{cpp}
2802 auto r = std::ratio<3, 4>{} + std::ratio<4, 5>{}; // error, the operator is not defined!
2803 @endcode
2804
2805 Instead, you should use the following:
2806
2807 @snippet example/tutorial/ext/ratio_plus.cpp main
2808
2809 But sometimes, it's much worse. Some external components define operators, but
2810 they don't necessarily have the same semantics as those from Hana. For example,
2811 comparing two `std::tuple`s of different lengths will give an error when using
2812 `operator==`:
2813
2814 @code{cpp}
2815 std::make_tuple(1, 2, 3) == std::make_tuple(1, 2); // compiler error
2816 @endcode
2817
2818 On the other hand, comparing Hana tuples of different lengths will just return
2819 a false `IntegralConstant`:
2820
2821 @code{cpp}
2822 hana::make_tuple(1, 2, 3) == hana::make_tuple(1, 2); // hana::false_c
2823 @endcode
2824
2825 This is because `std::tuple` defines its own operators, and their semantics
2826 are different from that of Hana's operators. The solution is to stick with
2827 Hana's named functions instead of using operators when you know you'll have
2828 to work with other libraries:
2829
2830 @code{cpp}
2831 hana::equal(std::make_tuple(1, 2, 3), std::make_tuple(1, 2)); // hana::false_c
2832 @endcode
2833
2834 When using external adapters, one should also be careful not to forget
2835 including the proper bridge headers. For example, suppose I want to use
2836 a Boost.MPL vector with Hana. I include the appropriate bridge header:
2837
2838 @snippet example/tutorial/ext/mpl_vector.cpp front
2839
2840 @note
2841 The exact layout of these bridge headers is documented in the section about
2842 [Header organization](@ref tutorial-header_organization).
2843
2844 Now, however, suppose that I use `mpl::size` to query the size of the vector
2845 and then compare it to some value. I could also use `hana::length` and
2846 everything would be fine, but bear with me for the sake of the example:
2847
2848 @snippet example/tutorial/ext/mpl_vector.cpp size
2849
2850 The reason why this breaks is that `mpl::size` returns a MPL IntegralConstant,
2851 and Hana has no way of knowing about these unless you include the proper
2852 bridge header. Hence, you should do the following instead:
2853
2854 @snippet example/tutorial/ext/mpl_vector.cpp size-fixed
2855
2856 The morale is that when working with external libraries, you have to be a bit
2857 careful about what objects you are manipulating. The final pitfall is about
2858 implementation limits in external libraries. Many older libraries have limits
2859 regarding the maximum size of the heterogeneous containers that can be created
2860 with them. For example, one may not create a Fusion list of more than
2861 `FUSION_MAX_LIST_SIZE` elements in it. Obviously, these limits are inherited
2862 by Hana and for example, trying to compute the permutations of a `fusion::list`
2863 containing 5 elements (the resulting list would contain 120 elements) will
2864 fail in a gruesome way:
2865
2866 @code{cpp}
2867 auto list = fusion::make_list(1, 2, 3, 4, 5);
2868 auto oh_jeez = hana::permutations(list); // probably won't make it
2869 @endcode
2870
2871 Apart from the pitfalls explained in this section, using external adapters
2872 should be just as straightforward as using normal Hana containers. Of course,
2873 whenever possible, you should try to stick with Hana's containers because they
2874 are usually more friendly to work with and are often more optimized.
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885 @section tutorial-core Hana's core
2886
2887 ------------------------------------------------------------------------------
2888 The goal of this section is to give a high-level overview of Hana's core.
2889 This core is based on the notion of _tag_, which is borrowed from the
2890 Boost.Fusion and Boost.MPL libraries but taken much further by Hana. These
2891 tags are then used for several purposes, like algorithm customization,
2892 documentation grouping, improving error messages and converting containers
2893 into other containers. Because of its modular design, Hana can be extended
2894 in a ad-hoc manner very easily. In fact, all the functionality of the library
2895 is provided through an ad-hoc customization mechanism, which is explained here.
2896
2897
2898 @subsection tutorial-core-tags Tags
2899
2900 Heterogeneous programming is basically programming with objects having
2901 different types. However, it is clear that some families of objects, while
2902 having different representations (C++ types), are strongly related. For
2903 example, the `std::integral_constant<int, n>` types are different for each
2904 different `n`, but conceptually they all represent the same thing; a
2905 compile-time number. The fact that `std::integral_constant<int, 1>{}` and
2906 `std::integral_constant<int, 2>{}` have different types is just a side effect
2907 of the fact that we're using their type to encode the _value_ of these objects.
2908 Indeed, when manipulating a sequence of `std::integral_constant<int, ...>`s,
2909 chances are that you actually think of it as a homogeneous sequence of an
2910 imaginary `integral_constant` type, disregarding the actual types of the
2911 objects and pretending they are all just `integral_constant`s with different
2912 values.
2913
2914 To reflect this reality, Hana provides _tags_ representing its heterogeneous
2915 containers and other compile-time entities. For example, all of Hana's
2916 `integral_constant<int, ...>`s have different types, but they all share
2917 the same tag, `integral_constant_tag<int>`. This allows the programmer to
2918 think in terms of that single type instead of trying to think in terms of the
2919 actual types of the objects. Concretely, tags are implemented as empty `struct`s.
2920 To make them stand out, Hana adopts the convention of naming these tags by
2921 adding the `_tag` suffix.
2922
2923 @note
2924 The tag of an object of type `T` can be obtained by using `tag_of<T>::%type`,
2925 or equivalently `tag_of_t<T>`.
2926
2927 Tags are an extension to normal C++ types. Indeed, by default, the tag of a
2928 type `T` is `T` itself, and the core of the library is designed to work in
2929 those cases. For example, `hana::make` expects either a tag or an actual type;
2930 if you send it a type `T`, it will do the logical thing and construct an
2931 object of type `T` with the arguments you pass it. If you pass a tag to it,
2932 however, you should specialize `make` for that tag and provide your own
2933 implementation, as explained below. Because tags are an extension to usual
2934 types, we end up mostly reasoning in terms of tags instead of usual types,
2935 and the documentation sometimes uses the words _type_, _data type_ and _tag_
2936 interchangeably.
2937
2938
2939 @subsection tutorial-core-tag_dispatching Tag dispatching
2940
2941 Tag dispatching is a generic programming technique for picking the right
2942 implementation of a function depending on the type of the arguments passed
2943 to the function. The usual mechanism for overriding a function's behavior
2944 is overloading. Unfortunately, this mechanism is not always convenient when
2945 dealing with families of related types having different base templates, or
2946 when the kind of template parameters is not known (is it a type or a non-type
2947 template parameter?). For example, consider trying to overload a function for
2948 all Boost.Fusion vectors:
2949
2950 @code{cpp}
2951 template <typename ...T>
2952 void function(boost::fusion::vector<T...> v) {
2953 // whatever
2954 }
2955 @endcode
2956
2957 If you know Boost.Fusion, then you probably know that it won't work. This is
2958 because Boost.Fusion vectors are not necessarily specializations of the
2959 `boost::fusion::vector` template. Fusion vectors also exist in numbered
2960 forms, which are all of different types:
2961
2962 @code{cpp}
2963 boost::fusion::vector1<T>
2964 boost::fusion::vector2<T, U>
2965 boost::fusion::vector3<T, U, V>
2966 ...
2967 @endcode
2968
2969 This is an implementation detail required by the lack of variadic templates in
2970 C++03 that leaks into the interface. This is unfortunate, but we need a way to
2971 work around it. To do so, we use an infrastructure with three distinct
2972 components:
2973
2974 1. A metafunction associating a single tag to every type in a family of
2975 related types. In Hana, this tag can be accessed using the `tag_of`
2976 metafunction. Specifically, for any type `T`, `tag_of<T>::%type` is
2977 the tag used to dispatch it.
2978
2979 2. A function belonging to the public interface of the library, for which
2980 we'd like to be able to provide a customized implementation. In Hana,
2981 these functions are the algorithms associated to a concept, like
2982 `transform` or `unpack`.
2983
2984 3. An implementation for the function, parameterized with the tag(s) of the
2985 argument(s) passed to the function. In Hana, this is usually done by having
2986 a separate template called `xxx_impl` (for an interface function `xxx`)
2987 with a nested `apply` static function, as will be shown below.
2988
2989 When the public interface function `xxx` is called, it will get the tag of the
2990 argument(s) it wishes to dispatch the call on, and then forward the call to
2991 the `xxx_impl` implementation associated to those tags. For example, let's
2992 implement a basic setup for tag dispatching of a function that prints its
2993 argument to a stream. First, we define the public interface function and the
2994 implementation that can be specialized:
2995
2996 @snippet example/tutorial/tag_dispatching.cpp setup
2997
2998 Now, let's define a type that needs tag dispatching to customize the behavior
2999 of `print`. While some C++14 examples exist, they are too complicated to show
3000 in this tutorial and we will therefore use a C++03 tuple implemented as several
3001 different types to illustrate the technique:
3002
3003 @snippet example/tutorial/tag_dispatching.cpp vector
3004
3005 The nested `using hana_tag = vector_tag;` part is a terse way of controling
3006 the result of the `tag_of` metafunction, and hence the tag of the `vectorN`
3007 type. This is explained in the reference for `tag_of`. Finally, if you wanted
3008 to customize the behavior of the `print` function for all the `vectorN` types,
3009 you would normally have to write something along the lines of
3010
3011 @snippet example/tutorial/tag_dispatching.cpp old_way
3012
3013 Now, with tag dispatching, you can rely on the `vectorN`s all sharing the same
3014 tag and specialize only the `print_impl` struct instead:
3015
3016 @snippet example/tutorial/tag_dispatching.cpp customize
3017
3018 One upside is that all `vectorN`s can now be treated uniformly by the `print`
3019 function, at the cost of some boilerplate when creating the data structure
3020 (to specify the tag of each `vectorN`) and when creating the initial `print`
3021 function (to setup the tag dispatching system with `print_impl`). There are
3022 also other advantages to this technique, like the ability to check for
3023 preconditions in the interface function without having to do it in each
3024 custom implementation, which would be tedious:
3025
3026 @snippet example/tutorial/tag_dispatching.cpp preconditions
3027
3028 @note
3029 Checking preconditions does not make much sense for a `print` function, but
3030 consider for example a function to get the `n`th element of a sequence; you
3031 might want to make sure that the index is not out-of-bounds.
3032
3033 This technique also makes it easier to provide interface functions as function
3034 objects instead of normal overloaded functions, because only the interface
3035 function itself must go through the trouble of defining a function object.
3036 Function objects have several advantages over overloaded functions, like the
3037 ability to be used in higher order algorithms or as variables:
3038
3039 @snippet example/tutorial/tag_dispatching.cpp function_objects
3040
3041 As you are probably aware of, being able to implement an algorithm for many
3042 types at the same time is tremendously useful (that's precisely the goal of
3043 C++ templates!). However, even more useful is the ability to implement an
3044 algorithm for many types _that satisfy some condition_. C++ templates are
3045 currently missing this ability to constrain their template parameters, but a
3046 language feature called [concepts][C++17.clite] is being rolled out with the
3047 goal of addressing this issue.
3048
3049 With something similar in mind, Hana's algorithms support an additional layer
3050 of tag-dispatching to what was explained above. This layer allows us to
3051 "specialize" an algorithm for all types that satisfy some predicate. For
3052 example, let's say we wanted to implement the `print` function above for all
3053 types that represent some kind of sequence. Right now, we wouldn't have an
3054 easy way to do this. However, the tag dispatching for Hana's algorithms is
3055 set up slightly differently than what was shown above, and we could hence
3056 write the following:
3057
3058 @snippet example/tutorial/tag_dispatching.cpp customize-when
3059
3060 where `Tag represents some kind of sequence` would only need to be a boolean
3061 expression representing whether `Tag` is a sequence. We'll see how such
3062 predicates can be created in the next section, but for now let's assume that
3063 it _just works_. Without going into the details of how this tag-dispatching is
3064 set up, the above specialization will only be picked up when the predicate is
3065 satisfied, and if no better match can be found. Hence, for example, if our
3066 `vector_tag` was to satisfy the predicate, our initial implementation for
3067 `vector_tag` would still be preferred over the `hana::when`-based specialization,
3068 because it represents a better match. In general, any specialization (whether
3069 explicit or partial) _not_ using `hana::when` will be preferred over a
3070 specialization using `hana::when`, which was designed to be as unsurprising
3071 as possible from a user point of view. This covers pretty much all there's
3072 to say about tag-dispatching in Hana. The next section will explain how we
3073 can create C++ concepts for metaprogramming, which could then be used in
3074 conjunction with `hana::when` to achieve a great deal of expressiveness.
3075
3076
3077 @subsection tutorial-core-concepts Emulation of C++ concepts
3078
3079 The implementation of concepts in Hana is very simple. At its heart, a concept
3080 is just a template `struct` with a nested `::%value` boolean representing
3081 whether the given type is a _model_ of the concept:
3082
3083 @code{cpp}
3084 template <typename T>
3085 struct Concept {
3086 static constexpr bool value = whether T models Concept;
3087 };
3088 @endcode
3089
3090 Then, one can test whether a type `T` is a model of `Concept` by looking at
3091 `Concept<T>::%value`. Simple enough, right? Now, while the way one might
3092 implement the check does not have to be anything specific as far as Hana
3093 is concerned, the rest of this section will explain how it is usually done
3094 in Hana, and how it interacts with tag dispatching. You should then be able
3095 to define your own concepts if you so desire, or at least to understand better
3096 how Hana works internally.
3097
3098 Usually, a concept defined by Hana will require that any model implements some
3099 tag-dispatched functions. For example, the `Foldable` concept requires that
3100 any model defines at least one of `hana::unpack` and `hana::fold_left`. Of
3101 course, concepts usually also define semantic requirements (called laws) that
3102 must be satisfied by their models, but these laws are not (and couldn't be)
3103 checked by the concept. But how do we check that some functions are properly
3104 implemented? For this, we'll have to slightly modify the way we defined
3105 tag-dispatched methods as shown in the previous section. Let's go back to
3106 our `print` example and try to define a `Printable` concept for those objects
3107 that can be `print`ed. Our end goal is to have a template struct such as
3108
3109 @code{cpp}
3110 template <typename T>
3111 struct Printable {
3112 static constexpr bool value = whether print_impl<tag of T> is defined;
3113 };
3114 @endcode
3115
3116 To know whether `print_impl<...>` has been defined, we'll modify `print_impl`
3117 so that it inherits from a special base class when it is not overridden, and
3118 we'll simply check whether `print_impl<T>` inherits from that base class:
3119
3120 @snippet example/tutorial/concepts.cpp special_base_class
3121
3122 Of course, when we specialize `print_impl` with a custom type, we don't
3123 inherit from that `special_base_class` type:
3124
3125 @snippet example/tutorial/concepts.cpp special_base_class_customize
3126
3127 As you can see, `Printable<T>::%value` really only checks whether the
3128 `print_impl<T>` struct was specialized by a custom type. In particular,
3129 it does not even check whether the nested `::%apply` function is defined
3130 or if it is syntactically valid. It is assumed that if one specializes
3131 `print_impl` for a custom type, the nested `::%apply` function exists and
3132 is correct. If it is not, a compilation error will be triggered when one
3133 tries to call `print` on an object of that type. Concepts in Hana make the
3134 same assumptions.
3135
3136 Since this pattern of inheriting from a special base class is quite abundant
3137 in Hana, the library provides a dummy type called `hana::default_` that can be
3138 used in place of `special_base_class`. Then, instead of using `std::is_base_of`,
3139 one can use `hana::is_default`, which looks nicer. With this syntactic sugar,
3140 the code now becomes:
3141
3142 @snippet example/tutorial/concepts.cpp actual
3143
3144 This is all that there's to know about the interaction between tag-dispatched
3145 functions and concepts. However, some concepts in Hana do not rely solely on
3146 the definition of specific tag-dispatched functions to determine if a type is
3147 a model of the concept. This can happen when a concept merely introduces
3148 semantic guarantees through laws and refined concepts, but no additional
3149 syntactic requirements. Defining such a concept can be useful for several
3150 reasons. First, it sometimes happen that an algorithm can be implemented
3151 more efficiently if we can assume some semantic guarantees X or Y, so we
3152 might create a concept to enforce those guarantees. Secondly, it is sometimes
3153 possible to automatically define the models for several concepts when we have
3154 additional semantic guarantees, which saves the user the trouble of defining
3155 those models manually. For example, this is the case of the `Sequence` concept,
3156 which basically adds semantic guarantees to `Iterable` and `Foldable`, and in
3157 turn allows us to define the models for a myriad of concepts ranging from
3158 `Comparable` to `Monad`.
3159
3160 For these concepts, it is usually necessary to specialize the corresponding
3161 template struct in the `boost::hana` namespace to provide a model for a custom
3162 type. Doing so is like providing a seal saying that the semantic guarantees
3163 required by the concept are respected by the custom type. The concepts that
3164 require being explicitly specialized will document that fact. So that's it!
3165 This is all that there's to know about concepts in Hana, which ends this
3166 section about the core of Hana.
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177 @section tutorial-header_organization Header organization
3178
3179 ------------------------------------------------------------------------------
3180 The library is designed to be modular while keeping the number of headers that
3181 must be included to get basic functionality reasonably low. The structure of
3182 the library was also intentionally kept simple, because we all love simplicity.
3183 What follows is a general overview of the header organization. A list of all
3184 the headers provided by the library is also available in the panel on the left
3185 (under the [Headers](files.html) label) in case you need more details.
3186
3187 - `boost/hana.hpp`\n
3188 This is the master header of the library, which includes the whole public
3189 interface of the library. Note that external adapters, experimental features
3190 and implementation details are not included by this header, however, since
3191 some of them require additional dependencies.
3192
3193 - `boost/hana/`\n
3194 This is the main directory of the library containing the definitions of
3195 everything provided by the library. Each algorithm and container provided
3196 by the library has its own header. For a container or an algorithm named
3197 `XXX`, the corresponding header is `boost/hana/XXX.hpp`.
3198
3199 - `boost/hana/concept/`\n
3200 This subdirectory contains the definition of Hana's concepts. These
3201 headers provide a way to check whether an object is a model of the
3202 corresponding concept, and they sometimes also provide default
3203 implementations for other related concepts, which are documented
3204 on a per-concept basis. They also include all the algorithms associated
3205 to that concept.
3206
3207 - `boost/hana/core/`\n
3208 This subdirectory contains the machinery for tag dispatching and other
3209 related utilities like `make` and `to`.
3210
3211 - `boost/hana/fwd/`\n
3212 This subdirectory contains the forward declaration of everything in the
3213 library. It is essentially a mirror of the `boost/hana/` directory, except
3214 all the headers contain only forward declarations and documentation. For
3215 example, to include the `hana::tuple` container, one can use the
3216 `boost/hana/tuple.hpp` header. However, if one only wants the
3217 forward declaration of that container, the `boost/hana/fwd/tuple.hpp`
3218 header can be used instead. Note that forward declarations for headers
3219 in `boost/hana/ext/` and `boost/hana/functional/` are not provided.
3220
3221 - `boost/hana/functional/`\n
3222 This subdirectory contains various function objects that are often useful,
3223 but that do not necessarily belong to a concept.
3224
3225 - `boost/hana/ext/`\n
3226 This directory contains adapters for external libraries. For a component
3227 named `xxx` in a namespace `ns`, the external adapter lives in the
3228 `boost/hana/ext/ns/xxx.hpp` header. For example, the external adapter
3229 for `std::tuple` lives in the `boost/hana/ext/std/tuple.hpp` header,
3230 while the external adapter for `boost::mpl::vector` is in
3231 `boost/hana/ext/boost/mpl/vector.hpp`.
3232
3233 Note that only the strict minimum required to adapt the external components
3234 is included in these headers (e.g. a forward declaration). This means that
3235 the definition of the external component should still be included when one
3236 wants to use it. For example:
3237 @snippet example/tutorial/include_ext.cpp main
3238
3239 - `boost/hana/experimental/`\n
3240 This directory contains experimental features that may or may not make it
3241 into the library at some point, but that were deemed useful enough to be
3242 made available to the public. Features in this subdirectory reside in the
3243 `hana::experimental` namespace. Also, do not expect these features to be
3244 stable; they may be moved, renamed, changed or removed between releases of
3245 the library. These features may also require additional external dependencies;
3246 each feature documents the additional dependencies it requires, if any.
3247
3248 Because of the potential additional dependencies, these headers are also
3249 not included by the master header of the library.
3250
3251 - `boost/hana/detail/`\n
3252 This directory contains utilities required internally. Nothing in `detail/`
3253 is guaranteed to be stable, so you should not use it.
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264 @section tutorial-conclusion Conclusion
3265
3266 ------------------------------------------------------------------------------
3267 You now have everything you need to start using the library. From this point
3268 forward, mastering the library is only a matter of understanding how to use
3269 the general purpose concepts and containers provided with it, which is best
3270 done by looking at the reference documentation. At some point, you will
3271 probably also want to create your own concepts and data types that fit your
3272 needs better; go ahead, the library was designed to be used that way.
3273
3274 @subsection tutorial-conclusion-warning Fair warning: functional programming ahead
3275
3276 Programming with heterogeneous objects is inherently functional -- since it is
3277 impossible to modify the type of an object, a new object must be introduced
3278 instead, which rules out mutation. Unlike previous metaprogramming libraries
3279 whose design was modeled on the STL, Hana uses a functional style of
3280 programming which is the source for a good portion of its expressiveness.
3281 However, as a result, many concepts presented in the reference will be
3282 unfamiliar to C++ programmers without a knowledge of functional programming.
3283 The reference attempts to make these concepts approachable by using intuition
3284 whenever possible, but bear in mind that the highest rewards are usually the
3285 fruit of some effort.
3286
3287 This finishes the tutorial part of the documentation. I hope you enjoy using
3288 the library, and please consider [contributing][Hana.contributing] to make it
3289 even better!
3290
3291 -- Louis
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302 @section tutorial-reference Using the reference
3303
3304 ------------------------------------------------------------------------------
3305 As for most generic libraries, algorithms in Hana are documented by the
3306 concept to which they belong (`Foldable`, `Iterable`, `Searchable`, `Sequence`,
3307 etc...). The different containers are then documented on their own page, and
3308 the concepts that they model are documented there. The concepts modeled by
3309 some container defines what algorithms can be used with such a container.
3310
3311 More specifically, the structure of the reference (available in the menu to
3312 the left) goes as follow:
3313
3314 - @ref group-core\n
3315 Documentation for the core module, which contains everything needed to
3316 create concepts, data types and related utilities. This is relevant
3317 if you need to extend the library, but otherwise you can probably
3318 ignore this.
3319
3320 - @ref group-concepts\n
3321 Documentation for all the concepts provided with the library. Each concept:
3322 - Documents which functions must be implemented absolutely in order to
3323 model that concept. The set of functions that must be provided is called
3324 a _minimal complete definition_.
3325 - Documents semantic constraints that any model of that concept must satisfy.
3326 These constraints are usually called laws and they are expressed in a
3327 semi-formal mathematical language. Of course, those laws can't be checked
3328 automatically but you should still make sure you satisfy them.
3329 - Documents the concept(s) it refines, if any. Sometimes, a concept is
3330 powerful enough to provide a model of a concept it refines, or at least
3331 the implementation for some of its associated functions. When this is the
3332 case, the concept will document which functions of the refined concept it
3333 provides, and how it does so. Also, it is sometimes possible that the
3334 model for a refined concept is unique, in which case it can be provided
3335 automatically. When this happens, it will be documented but you don't have
3336 to do anything special to get that model.
3337
3338 - @ref group-datatypes\n
3339 Documentation for all the data structures provided with the library. Each
3340 data structure documents the concept(s) it models, and how it does so. It
3341 also documents the methods tied to it but not to any concept, for example
3342 `maybe` for `optional`.
3343
3344 - @ref group-functional\n
3345 General purpose function objects that are generally useful in a purely
3346 functional setting. These are currently not tied to any concept or container.
3347
3348 - @ref group-ext\n
3349 Documentation for all the adapters for external libraries. These adapters
3350 are documented as if they were native types provided by Hana, but obviously
3351 Hana only provides the compatibility layer between them and the library.
3352
3353 - @ref group-config\n
3354 Macros that can be used to tweak the global behavior of the library.
3355
3356 - @ref group-assertions\n
3357 Macros to perform various types of assertions.
3358
3359 - [<b>Alphabetical index</b>](functions.html)\n
3360 Alphabetical index of everything provided in the library.
3361
3362 - [<b>Headers</b>](files.html)\n
3363 A list of all the headers provided by the library.
3364
3365 - @ref group-details\n
3366 Implementation details; don't go there. Anything not documented at all or
3367 documented in this group is not guaranteed to be stable.
3368
3369 After you get to know Hana a bit better, it will probably happen that you just
3370 want to find the reference for a precise function, concept or container. If
3371 you know the name of what you're looking for, you can use the _search_ box
3372 located in the upper right corner of any page of the documentation. My
3373 personal experience is that this is by far the quickest way of finding
3374 what you want when you already know its name.
3375
3376
3377 @subsection tutorial-reference-signatures Function signatures
3378
3379 As you will see in the reference, several functions provide signatures
3380 documented in a semi-formal mathematical language. We are in the process
3381 of documenting all functions in this way, but this may take a while. The
3382 notation used is the usual mathematical notation for defining functions.
3383 Specifically, a function `Return f(Arg1, ..., ArgN);` can be defined
3384 equivalently using mathematical notation as
3385
3386 @f[
3387 \mathtt{f} : \mathtt{Arg}_1 \times \dots \times \mathtt{Arg}_n
3388 \to \mathtt{Return}
3389 @f]
3390
3391 However, instead of documenting the actual argument and return types of
3392 functions, those signatures are written in terms of argument and return tags.
3393 This is done because of the heterogeneous setting, where the actual type of
3394 an object is usually pretty meaningless and does not help to reason about
3395 what's being returned or taken by a function. For example, instead of
3396 documenting the `equal` function for `integral_constant`s as
3397
3398 @f[
3399 \mathtt{equal} : \mathtt{integral\_constant<T, n>} \times
3400 \mathtt{integral\_constant<T, m>}
3401 \to \mathtt{integral\_constant<bool, n == m>}
3402 @f]
3403
3404 which is not really helpful (as it really presents nothing but the
3405 implementation), it is instead documented using `integral_constant_tag`,
3406 which acts as the "type" of all `integral_constant`s. Note that since `equal`
3407 is part of the `Comparable` concept, it is not _actually_ documented for
3408 `hana::integral_constant` specifically, but the idea is there:
3409
3410 @f[
3411 \mathtt{equal} : \mathtt{integral\_constant\_tag<T>} \times
3412 \mathtt{integral\_constant\_tag<T>}
3413 \to \mathtt{integral\_constant\_tag<bool>}
3414 @f]
3415
3416 This clearly conveys the intention that comparing two `integral_constant`s
3417 gives back another `integral_constant` holding a `bool`. In general, this
3418 abstraction of the actual representation of objects makes it possible for
3419 us to reason in a high level manner about functions, even though their
3420 actual return and argument types are heterogeneous and not helpful. Finally,
3421 most functions expect container elements to have some properties. For example,
3422 this is the case of the `sort` algorithm, which obviously requires the
3423 container elements to be `Orderable`. Normally, we would write the signature
3424 for the non-predicated version of `sort` as
3425
3426 @f[
3427 \mathtt{sort} : \mathtt{S} \to \mathtt{S} \\
3428 \text{where S is a Sequence}
3429 @f]
3430
3431 However, this fails to express the requirement that the contents of `S` are
3432 `Orderable`. To express this, we use the following notation:
3433
3434 @f[
3435 \mathtt{sort} : \mathtt{S(T)} \to \mathtt{S(T)} \\
3436 \text{where S is a Sequence and T is Orderable}
3437 @f]
3438
3439 One way to see this is to pretend that `S`, the sequence tag, is actually
3440 parameterized by the tag of the sequence's elements, `T`. We're also pretending
3441 that the elements all have the same tag `T`, which is not the case in general.
3442 Now, by stating that `T` must be `Orderable`, we're expressing the fact that
3443 the sequence's elements must be `Orderable`. This notation is used in different
3444 flavors to express different kinds of requirements. For example, the
3445 `cartesian_product` algorithm takes a sequence of sequences and returns the
3446 cartesian product of those sequences as a sequence of sequences. Using our
3447 notation, this can be conveyed very easily:
3448
3449 @f[
3450 \mathtt{cartesian\_product} : \mathtt{S(S(T))} \to \mathtt{S(S(T))} \\
3451 \text{where S is a Sequence}
3452 @f]
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463 @section tutorial-acknowledgements Acknowledgements
3464
3465 ------------------------------------------------------------------------------
3466 I'd like to thank the following persons and organizations for contributing to
3467 Hana in one way or another:
3468
3469 - Zach Laine and Matt Calabrese for the original idea of using function call
3470 syntax to do type-level computations, as presented in their BoostCon
3471 [presentation][video.inst_must_go] ([slides 1][slides.inst_must_go1])
3472 ([slides 2][slides.inst_must_go2]).
3473 - Joel Falcou for mentoring me two consecutive years during my work on Hana
3474 as part of the [Google Summer of Code][GSoC] program, Niall Douglas for
3475 being the GSoC admin for Boost and helping me get in the program, and
3476 finally Google for their awesome GSoC program.
3477 - The [Boost Steering committee][Boost.Steering] for unlocking a grant for me
3478 to work on Hana in the winter of 2015, as an extension to the previous
3479 year's GSoC.
3480 - Several [C++Now][] attendees and members of the [Boost mailing list]
3481 [Boost.Devel] for insightful conversations, comments and questions
3482 about the project.
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493 @section tutorial-glossary Glossary
3494
3495 ------------------------------------------------------------------------------
3496 The reference documentation uses a couple of terms that are specific to this
3497 library. Also, a simplified implementation of functions is sometimes provided
3498 in pseudo-code, the actual implementation sometimes being slightly hard to
3499 understand. This section defines terms used in the reference and in the
3500 pseudo-code used to describe some functions.
3501
3502 @anchor tutorial-glossary-forwarded
3503 #### `forwarded(x)`
3504 Means that the object is forwarded optimally. This means that if `x` is a
3505 parameter, it is `std::forward`ed, and if it is a captured variable, it is
3506 moved from whenever the enclosing lambda is an rvalue.
3507
3508 Also note that when `x` can be moved from, the statement `return forwarded(x);`
3509 in a function with `decltype(auto)` does not mean that an rvalue reference to
3510 `x` will be returned, which would create a dangling reference. Rather, it
3511 means that `x` is returned by value, the value being constructed with the
3512 `std::forward`ed `x`.
3513
3514 @anchor tutorial-glossary-perfect_capture
3515 #### `perfect-capture`
3516 This is used in lambdas to signify that the captured variables are
3517 initialized using perfect forwarding, as if `[x(forwarded(x))...]() { }`
3518 had been used.
3519
3520 @anchor tutorial-glossary-tag_dispatched
3521 #### `tag-dispatched`
3522 This means that the documented function uses [tag dispatching]
3523 (@ref tutorial-core-tag_dispatching), and hence the exact
3524 implementation depends on the model of the concept associated
3525 to the function.
3526
3527 @anchor tutorial-glossary-implementation_defined
3528 #### `implementation-defined`
3529 This expresses the fact that the exact implementation of an entity (usually a
3530 type) should not be relied upon by users. In particular, this means that one
3531 can not assume anything beyond what is written explicitly in the documentation.
3532 Usually, the concepts satisfied by an implementation-defined entity will be
3533 documented, because one could otherwise do nothing with it. Concretely,
3534 assuming too much about an implementation-defined entity will probably
3535 not kill you, but it will very probably break your code when you update
3536 to a newer version of Hana.
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547 @section tutorial-rationales Rationales/FAQ
3548
3549 ------------------------------------------------------------------------------
3550 This section documents the rationale for some design choices. It also serves
3551 as a FAQ for some (not so) frequently asked questions. If you think something
3552 should be added to this list, open a GitHub issue and we'll consider either
3553 improving the documentation or adding the question here.
3554
3555
3556 @subsection tutorial-rationales-dependencies Why restrict usage of external dependencies?
3557
3558 There are several reasons for doing so. First, Hana is a very fundamental
3559 library; we are basically reimplementing the core language and the standard
3560 library with support for heterogeneous types. When going through the code,
3561 one quickly realizes that other libraries are rarely needed, and that almost
3562 everything has to be implemented from scratch. Also, since Hana is very
3563 fundamental, there is even more incentive for keeping the dependencies
3564 minimal, because those dependencies will be handed down to the users.
3565 Regarding the minimal reliance on Boost in particular, one big argument
3566 for using it is portability. However, as a cutting edge library, Hana only
3567 targets very recent compilers. Hence, we can afford to depend on modern
3568 constructs and the portability given to us by using Boost would mostly
3569 represent dead weight.
3570
3571
3572 @subsection tutorial-rationales-iterators Why no iterators?
3573
3574 Iterator based designs have their own merits, but they are also known to
3575 reduce the composability of algorithms. Furthermore, the context of
3576 heterogeneous programming brings a lot of points that make iterators much
3577 less interesting. For example, incrementing an iterator would have to return
3578 a new iterator with a different type, because the type of the new object it
3579 is pointing to in the sequence might be different. It also turns out that
3580 implementing most algorithms in terms of iterators leads to a worse
3581 compile-time performance, simply because the execution model of metaprogramming
3582 (using the compiler as an interpreter) is so different from the runtime
3583 execution model of C++ (a processor accessing contiguous memory).
3584
3585
3586 @subsection tutorial-rationales-container_representation Why leave some container's representation implementation-defined?
3587
3588 First, it gives much more wiggle room for the implementation to perform
3589 compile-time and runtime optimizations by using clever representations for
3590 specific containers. For example, a tuple containing homogeneous objects of
3591 type `T` could be implemented as an array of type `T` instead, which is more
3592 efficient at compile-time. Secondly, and most importantly, it turns out that
3593 knowing the type of a _heterogeneous_ container is not as useful as you would
3594 think. Indeed, in the context of heterogeneous programming, the type of the
3595 object returned by a computation is usually part of the computation too. In
3596 other words, there is no way to know the type of the object returned by an
3597 algorithm without actually performing the algorithm. For example, consider
3598 the `find_if` algorithm:
3599
3600 @snippet example/tutorial/rationale.container.cpp hana
3601
3602 If the predicate is satisfied for some element of the tuple, result will be
3603 equal to `just(x)`. Otherwise, `result` will be equal to `nothing`. However,
3604 the `nothing`ness of the result is known at compile-time, which requires
3605 `just(x)` and `nothing` to have different types. Now, say you wanted to
3606 explicitly write the type of the result:
3607
3608 @snippet example/tutorial/rationale.container.cpp hana-explicit
3609
3610 In order to possess the knowledge of what `some_type` is, you would need to
3611 actually perform the algorithm, because `some_type` depends on whether the
3612 predicate is satisfied or not for some element in the container. In other
3613 words, if you were able to write the above, then you would already know what
3614 the result of the algorithm is and you would not need to perform the algorithm
3615 in the first place. In Boost.Fusion, this problem is addressed by having a
3616 separate `result_of` namespace, which contains a metafunction computing the
3617 result type of any algorithm given the types of the arguments passed to it.
3618 For example, the above example could be rewritten with Fusion as:
3619
3620 @snippet example/tutorial/rationale.container.cpp fusion
3621
3622 Notice that we're basically doing the computation twice; once in the `result_of`
3623 namespace and once in the normal `fusion` namespace, which is highly redundant.
3624 Before the days of `auto` and `decltype`, such techniques were necessary to
3625 perform heterogeneous computations. However, since the advent of modern C++,
3626 the need for explicit return types in the context of heterogeneous programming
3627 is largely obsolete, and knowing the actual type of containers is usually not
3628 that useful.
3629
3630
3631 @subsection tutorial-rationales-why_Hana Why Hana?
3632
3633 No, it isn't the name of my girlfriend! I just needed a short and good looking
3634 name that people would easily remember, and Hana came up. It also came to my
3635 attention that Hana means _flower_ in Japanese, and _one_ in Korean. Since
3636 Hana is pretty and it unifies type-level and heterogeneous programming under
3637 a single paradigm, the name appears to be quite well chosen in retrospect :-).
3638
3639
3640 @subsection tutorial-rationales-tuple Why define our own tuple?
3641
3642 Since Hana defines a lot of algorithms on tuples, a possible way to go would
3643 have been to simply use `std::tuple` and provide the algorithms only, instead
3644 of also providing our own tuple. The reason for providing our own tuple is
3645 principally performance. Indeed, all the `std::tuple` implementations tested
3646 so far have a very bad compile-time performance. Also, to get truly amazing
3647 compile-time performance, we need to take advantage of the tuple's internal
3648 representation in some algorithms, which requires defining our own. Finally,
3649 some sugar like `operator[]` could not be provided if we were using a
3650 `std::tuple`, since that operator must be defined as a member function.
3651
3652
3653 @subsection tutorial-rationales-naming How are names chosen?
3654
3655 When deciding upon a name `X`, I try to balance the following things
3656 (in no specific order):
3657
3658 - How idiomatic is `X` in C++?
3659 - How idiomatic is `X` in the rest of the programming world?
3660 - How good of a name `X` _actually is_, regardless of historical reasons
3661 - How do I, as the library author, feel about `X`
3662 - How do users of the library feel about `X`
3663 - Are there technical reasons not to use `X`, like name clashes or names
3664 reserved by the standard
3665
3666 Of course, good naming is and will always be hard. Names are and will always
3667 be tainted by the author's own bias. Still, I try to choose names in a
3668 reasonable manner.
3669
3670
3671 @subsection tutorial-rationales-parameters How is the parameter order decided?
3672
3673 Unlike naming, which is fairly subjective, the order of the parameters of a
3674 function is usually pretty straightforward to determine. Basically, the rule
3675 of thumb is "the container goes first". It has always been this way in Fusion
3676 and MPL, and this is intuitive for most C++ programmers. Also, in higher-order
3677 algorithms, I try to put the function parameter last, so that multi-line
3678 lambdas look nice:
3679
3680 @code{cpp}
3681 algorithm(container, [](auto x) {
3682 return ...;
3683 });
3684
3685 // is nicer than
3686
3687 algorithm([](auto x) {
3688 return ...;
3689 }, container);
3690 @endcode
3691
3692
3693 @subsection tutorial-rationales-tag_dispatching Why tag dispatching?
3694
3695 There are several different techniques we could have used to provide
3696 customization points in the library, and tag-dispatching was chosen. Why?
3697 First, I wanted a two-layer dispatching system because this allows functions
3698 from the first layer (the ones that are called by users) to actually be
3699 function objects, which allows passing them to higher-order algorithms.
3700 Using a dispatching system with two layers also allows adding some
3701 compile-time sanity checks to the first layer, which improves error messages.
3702
3703 Now, tag-dispatching was chosen over other techniques with two layers for a
3704 couple of reasons. First, having to explicitly state how some tag is a model
3705 of a concept gives the responsibility of making sure that the semantic
3706 requirements of the concept are respected to the user. Secondly, when checking
3707 whether a type is a model of some concept, we basically check that some key
3708 functions are implemented. In particular, we check that the functions from the
3709 minimal complete definition of that concept are implemented. For example,
3710 `Iterable<T>` checks whether the `is_empty`, `at` and `drop_front` functions
3711 implemented for `T`. However, the only way to detect this without
3712 tag-dispatching is to basically check whether the following expressions
3713 are valid in a SFINAE-able context:
3714
3715 @code{cpp}
3716 implementation_of_at(std::declval<T>(), std::declval<N>())
3717 implementation_of_is_empty(std::declval<T>())
3718 implementation_of_drop_front(std::declval<T>())
3719 @endcode
3720
3721 Unfortunately, this requires actually doing the algorithms, which might either
3722 trigger a hard compile-time error or hurt compile-time performance. Also, this
3723 requires picking an arbitrary index `N` to call `at` with: what if the `Iterable`
3724 is empty? With tag dispatching, we can just ask whether `at_impl<T>`,
3725 `is_empty_impl<T>` and `drop_front_impl<T>` are defined, and nothing happens
3726 until we actually call their nested `::%apply` function.
3727
3728
3729 @subsection tutorial-rationales-zip_longest Why not provide zip_longest?
3730
3731 It would require either (1) padding the shortest sequences with an arbitrary
3732 object, or (2) padding the shortest sequences with an object provided by the
3733 user when calling `zip_longest`. Since there is no requirement that all the
3734 zipped sequences have elements of similar types, there is no way to provide a
3735 single consistent padding object in all cases. A tuple of padding objects
3736 should be provided, but I find it perhaps too complicated to be worth it for
3737 now. If you need this functionality, open a GitHub issue.
3738
3739
3740 @subsection tutorial-rationales-concepts Why aren't concepts constexpr functions?
3741
3742 Since the C++ concept proposal maps concepts to boolean `constexpr` functions,
3743 it would make sense that Hana defines its concepts as such too, instead of as
3744 structs with a nested `::%value`. Indeed, this was the first choice, but it
3745 had to be revised because template functions have one limitation that makes
3746 them less flexible. Specifically, a template function can't be passed to a
3747 higher-order metafunction. In other words, it is not possible to write the
3748 following
3749
3750 @code{cpp}
3751 template <??? Concept>
3752 struct some_metafunction {
3753 // ...
3754 };
3755 @endcode
3756
3757 This sort of code is very useful in some contexts, such as checking whether
3758 two types have a common embedding modeling a concept:
3759
3760 @code{cpp}
3761 template <??? Concept, typename T, typename U>
3762 struct have_common_embedding {
3763 // whether T and U both model Concept, and share a common type that also models Concept
3764 };
3765 @endcode
3766
3767 With concepts as boolean `constexpr` functions, this can't be written
3768 generically. When concepts are just template structs, however, we can
3769 use template template parameters:
3770
3771 @code{cpp}
3772 template <template <typename ...> class Concept, typename T, typename U>
3773 struct have_common_embedding {
3774 // whether T and U both model Concept, and share a common type that also models Concept
3775 };
3776 @endcode
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787 @section tutorial-appendix-constexpr Appendix I: Advanced constexpr
3788
3789 ------------------------------------------------------------------------------
3790 In C++, the border between compile-time and runtime is hazy, a fact that is
3791 even more true with the introduction of [generalized constant expressions]
3792 [C++14.gconstexpr] in C++14. However, being able to manipulate heterogeneous
3793 objects is all about understanding that border and then crossing it at one's
3794 will. The goal of this section is to set things straight with `constexpr`; to
3795 understand which problems it can solve and which ones it can't. This section
3796 covers advanced concepts about to constant expressions; only readers with a
3797 good understanding of `constexpr` should attempt to read this.
3798
3799
3800 @subsection tutorial-appendix-constexpr-stripping Constexpr stripping
3801
3802 Let's start with a challenging question. Should the following code compile?
3803
3804 @code{cpp}
3805 template <typename T>
3806 void f(T t) {
3807 static_assert(t == 1, "");
3808 }
3809
3810 constexpr int one = 1;
3811 f(one);
3812 @endcode
3813
3814 The answer is no, and the error given by Clang goes like
3815
3816 @code{cpp}
3817 error: static_assert expression is not an integral constant expression
3818 static_assert(t == 1, "");
3819 ^~~~~~
3820 @endcode
3821
3822 The explanation is that inside of `f`'s body, `t` is not a constant expression,
3823 and hence it can't be used as the operand to a `static_assert`. The reason is
3824 that such a function simply can't be generated by the compiler. To understand
3825 the issue, consider what should happen when we instantiate the `f` template
3826 with a concrete type:
3827
3828 @code{cpp}
3829 // Here, the compiler should generate the code for f<int> and store the
3830 // address of that code into fptr.
3831 void (*fptr)(int) = f<int>;
3832 @endcode
3833
3834 Clearly, the compiler can't generate `f<int>`'s code, which should trigger a
3835 `static_assert` if `t != 1`, because we haven't specified `t` yet. Even worse,
3836 the generated function should work on both constant and non-constant
3837 expressions:
3838
3839 @code{cpp}
3840 void (*fptr)(int) = f<int>; // assume this was possible
3841 int i = ...; // user input
3842 fptr(i);
3843 @endcode
3844
3845 Clearly, `fptr`'s code can't be generated, because it would require being able
3846 to `static_assert` on a runtime value, which does not make sense. Furthermore,
3847 note that it does not matter whether you make the function `constexpr` or not;
3848 making `f` `constexpr` would only state that the _result_ of `f` is a constant
3849 expression whenever its argument is a constant expression, but it still does
3850 not give you the ability to know whether you were called with a constant
3851 expression from `f`'s body. In other words, what we would want is something
3852 like:
3853
3854 @code{cpp}
3855 template <typename T>
3856 void f(constexpr T t) {
3857 static_assert(t == 1, "");
3858 }
3859
3860 constexpr int one = 1;
3861 f(one);
3862 @endcode
3863
3864 In this hypothetical scenario, the compiler would know that `t` is a constant
3865 expression from the body of `f`, and the `static_assert` could be made to work.
3866 However, `constexpr` parameters do not exist in the current language, and
3867 adding them would bring up very challenging design and implementation issues.
3868 The conclusion of this little experiment is that __argument passing strips
3869 away `constexpr`-ness__. What might be unclear by now are the consequences
3870 of this stripping, which are explained next.
3871
3872
3873 @subsection tutorial-tutorial-appendix-constexpr-preservation Constexpr preservation
3874
3875 The fact that an argument is not a constant expression means that we can't use
3876 it as a non-type template parameter, as an array bound, inside a `static_assert`
3877 or anything else that requires a constant expression. In addition, this means
3878 that the return type of a function can't depend on the _value_ of an argument
3879 which is nothing new if you think about it:
3880
3881 @code{cpp}
3882 template <int i>
3883 struct foo { };
3884
3885 auto f(int i) -> foo<i>; // obviously won't work
3886 @endcode
3887
3888 In fact, the return type of a function may only depend on the types of its
3889 arguments, and `constexpr` can't change this fact. This is of utmost importance
3890 to us, because we're interested in manipulating heterogeneous objects, which
3891 eventually means returning objects with different types depending on the
3892 argument of the function. For example, a function might want to return an
3893 object of type `T` in one case and an object of type `U` in the other;
3894 from our analysis, we now know that these "cases" will have to depend on
3895 information encoded in the _types_ of the arguments, not in their _values_.
3896
3897 To preserve `constexpr`-ness through argument passing, we have to encode the
3898 `constexpr` value into a type, and then pass a not-necessarily-`constexpr`
3899 object of that type to the function. The function, which must be a template,
3900 may then access the `constexpr` value encoded inside that type.
3901
3902 @todo
3903 Improve this explanation and talk about non-integral constant expressions
3904 wrapped into types.
3905
3906
3907 @subsection tutorial-appendix-constexpr-effects Side effects
3908
3909 Let me ask a tricky question. Is the following code valid?
3910
3911 @code{cpp}
3912 template <typename T>
3913 constexpr int f(T& n) { return 1; }
3914
3915 int n = 0;
3916 constexpr int i = f(n);
3917 @endcode
3918
3919 The answer is _yes_, but the reason might not be obvious at first. What
3920 happens here is that we have a non-`constexpr` `int n`, and a `constexpr`
3921 function `f` taking a reference to its argument. The reason why most people
3922 think it shouldn't work is that `n` is not `constexpr`. However, we're not
3923 doing anything with `n` inside of `f`, so there is no actual reason why this
3924 shouldn't work! This is a bit like `throw`ing inside of a `constexpr` function:
3925
3926 @code{cpp}
3927 constexpr int sqrt(int i) {
3928 if (i < 0) throw "i should be non-negative";
3929
3930 return ...;
3931 }
3932
3933 constexpr int two = sqrt(4); // ok: did not attempt to throw
3934 constexpr int error = sqrt(-4); // error: can't throw in a constant expression
3935 @endcode
3936
3937 As long as the code path where `throw` appears is not executed, the result of
3938 the invocation can be a constant expression. Similarly, we can do whatever we
3939 want inside of `f`, as long as we don't execute a code path that requires
3940 accessing its argument `n`, which is not a constant expression:
3941
3942 @code{cpp}
3943 template <typename T>
3944 constexpr int f(T& n, bool touch_n) {
3945 if (touch_n) n + 1;
3946 return 1;
3947 }
3948
3949 int n = 0;
3950 constexpr int i = f(n, false); // ok
3951 constexpr int j = f(n, true); // error
3952 @endcode
3953
3954 The error given by Clang for the second invocation is
3955
3956 @code{cpp}
3957 error: constexpr variable 'j' must be initialized by a constant expression
3958 constexpr int j = f(n, true); // error
3959 ^ ~~~~~~~~~~
3960 note: read of non-const variable 'n' is not allowed in a constant expression
3961 if (touch_n) n + 1;
3962 ^
3963 @endcode
3964
3965 Let's now step the game up a bit and consider a more subtle example.
3966 Is the following code valid?
3967
3968 @code{cpp}
3969 template <typename T>
3970 constexpr int f(T n) { return 1; }
3971
3972 int n = 0;
3973 constexpr int i = f(n);
3974 @endcode
3975
3976 The only difference with our initial scenario is that `f` now takes its
3977 argument by value instead of by reference. However, this makes a world of
3978 difference. Indeed, we're now asking the compiler to make a copy of `n`
3979 and to pass this copy to `f`. However, `n` is not `constexpr`, so its
3980 value is only known at runtime. How could the compiler make a copy (at
3981 compile-time) of a variable whose value is only known at runtime? Of
3982 course, it can't. Indeed, the error message given by Clang is pretty
3983 explicit about what's happening:
3984
3985 @code{cpp}
3986 error: constexpr variable 'i' must be initialized by a constant expression
3987 constexpr int i = f(n);
3988 ^ ~~~~
3989 note: read of non-const variable 'n' is not allowed in a constant expression
3990 constexpr int i = f(n);
3991 ^
3992 @endcode
3993
3994 @todo
3995 Explain how side-effects may not appear inside constant expressions, even
3996 if the expression they yield are not accessed.
3997
3998 <!-------------------
3999 Let me ask a tricky question. Is the following code valid?
4000
4001 @code{cpp}
4002 template <typename X>
4003 auto identity(X x) { return x; }
4004
4005 static_assert(value(identity(bool_c<true>)), "");
4006 @endcode
4007
4008 The answer is "no", but the reason might not be obvious at first. Even more
4009 puzzling is that the following code is perfectly valid:
4010
4011 @snippet example/tutorial/constant_side_effects.cpp pure
4012
4013 To understand why the compiler can't possibly evaluate the first assertion
4014 at compile-time, notice that `identity` was not marked `constexpr` and
4015 consider the following alternative (but valid) definition for `identity`:
4016
4017 @snippet example/tutorial/constant_side_effects.cpp impure_identity
4018
4019 The signature of the function did not change; the function could even have
4020 been defined in a separate source file. However, it is now obvious that the
4021 compiler can't evaluate that expression at compile-time. On the other hand,
4022 when we write
4023
4024 @snippet example/tutorial/constant_side_effects.cpp impure
4025
4026 we're telling the compiler to perform those potential side effects during the
4027 dynamic initialization phase! Then, we use `value` to return the compile-time
4028 value associated to its argument. Also note that `value` takes a `const&` to
4029 its argument; if it tried taking it by value, we would be reading from a
4030 non-`constexpr` variable to do the copying, and that could hide side-effects.
4031 ------>
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042 @section tutorial-appendix-MPL Appendix II: A minimal MPL
4043
4044 ------------------------------------------------------------------------------
4045 This section presents a mini reimplementation of the MPL library. The goal is
4046 to be as backward compatible as possible with the MPL, while still using Hana
4047 under the hood. Only the "Algorithms" part of the MPL is implemented as a case
4048 study, but it should be possible to implement many (but not all) metafunctions
4049 of the MPL.
4050
4051 Scroll down to the `main` function to see the tests. The tests are exactly
4052 the examples in the MPL documentation that were copy/pasted and then
4053 modified as little as possible to work with this reimplementation.
4054
4055 @include example/tutorial/appendix_mpl.cpp
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066 <!-- Links -->
4067 [Boost.Devel]: http://news.gmane.org/gmane.comp.lib.boost.devel
4068 [Boost.Fusion]: http://www.boost.org/doc/libs/release/libs/fusion/doc/html/index.html
4069 [Boost.MPL]: http://www.boost.org/doc/libs/release/libs/mpl/doc/index.html
4070 [Boost.Steering]: https://sites.google.com/a/boost.org/steering/home
4071 [Brigand]: https://github.com/edouarda/brigand
4072 [C++14.auto_rt]: http://en.wikipedia.org/wiki/C%2B%2B14#Function_return_type_deduction
4073 [C++14.gconstexpr]: http://en.wikipedia.org/wiki/C%2B%2B11#constexpr_.E2.80.93_Generalized_constant_expressions
4074 [C++14.glambda]: http://en.wikipedia.org/wiki/C%2B%2B14#Generic_lambdas
4075 [C++14.ice]: http://en.cppreference.com/w/cpp/types/integral_constant
4076 [C++14.udl]: http://en.wikipedia.org/wiki/C%2B%2B11#User-defined_literals
4077 [C++14.vtemplate]: http://en.wikipedia.org/wiki/C%2B%2B14#Variable_templates
4078 [C++14]: http://en.wikipedia.org/wiki/C%2B%2B14
4079 [C++17.clite]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3580.pdf
4080 [C++Now]: http://cppnow.org
4081 [Chandler.MeetingC++]: https://youtu.be/qkzaZumt_uk?t=4478
4082 [CMake]: http://www.cmake.org
4083 [constexpr_throw]: http://stackoverflow.com/a/8626450/627587
4084 [CopyConstructible]: http://en.cppreference.com/w/cpp/concept/CopyConstructible
4085 [GOTW]: http://www.gotw.ca/gotw/index.htm
4086 [GSoC]: http://www.google-melange.com/gsoc/homepage/google/gsoc2014
4087 [Hana.chat]: https://gitter.im/boostorg/hana
4088 [Hana.contributing]: https://github.com/boostorg/hana/blob/master/CONTRIBUTING.md#how-to-contribute
4089 [Hana.findmodule]: https://github.com/boostorg/hana/blob/master/cmake/FindHana.cmake
4090 [Hana.hacking]: https://github.com/boostorg/hana/blob/master/README.md#hacking-on-hana
4091 [Hana.issues]: https://github.com/boostorg/hana/issues
4092 [Hana.repository]: https://github.com/boostorg/hana
4093 [Hana.StackOverflow]: http://stackoverflow.com/questions/tagged/boost-hana
4094 [Hana.wiki]: https://github.com/boostorg/hana/wiki
4095 [Homebrew]: http://brew.sh
4096 [lie-to-children]: http://en.wikipedia.org/wiki/Lie-to-children
4097 [Metabench]: https://ldionne.github.io/metabench
4098 [MPL.arithmetic]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/arithmetic-operations.html
4099 [MPL.metafunction]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/metafunction.html
4100 [MPL.mfc]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/metafunction-class.html
4101 [MPL11]: http://github.com/ldionne/mpl11
4102 [N4461]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4461.html
4103 [N4487]: https://isocpp.org/files/papers/N4487.pdf
4104 [pkg-config]: http://www.freedesktop.org/wiki/Software/pkg-config/
4105 [POD]: http://en.cppreference.com/w/cpp/concept/PODType
4106 [SFINAE]: http://en.cppreference.com/w/cpp/language/sfinae
4107 [slides.inst_must_go1]: https://github.com/boostcon/2010_presentations/raw/master/mon/instantiations_must_go.pdf
4108 [slides.inst_must_go2]: https://github.com/boostcon/2010_presentations/raw/master/mon/instantiations_must_go_2.pdf
4109 [SO.sfinae]: http://stackoverflow.com/a/257382/627587
4110 [Sprout]: https://github.com/bolero-MURAKAMI/Sprout
4111 [StackOverflow]: http://stackoverflow.com
4112 [video.inst_must_go]: https://www.youtube.com/watch?v=x7UmrRzKAXU
4113
4114 */