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