summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/example
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/example')
-rw-r--r--src/boost/libs/hana/example/CMakeLists.txt68
-rw-r--r--src/boost/libs/hana/example/accessors.cpp42
-rw-r--r--src/boost/libs/hana/example/adapt_adt.cpp67
-rw-r--r--src/boost/libs/hana/example/adapt_struct.cpp60
-rw-r--r--src/boost/libs/hana/example/adjust.cpp23
-rw-r--r--src/boost/libs/hana/example/adjust_if.cpp27
-rw-r--r--src/boost/libs/hana/example/all.cpp16
-rw-r--r--src/boost/libs/hana/example/all_of.cpp39
-rw-r--r--src/boost/libs/hana/example/and.cpp14
-rw-r--r--src/boost/libs/hana/example/any.cpp16
-rw-r--r--src/boost/libs/hana/example/any_of.cpp39
-rw-r--r--src/boost/libs/hana/example/ap.cpp48
-rw-r--r--src/boost/libs/hana/example/append.cpp15
-rw-r--r--src/boost/libs/hana/example/at.cpp17
-rw-r--r--src/boost/libs/hana/example/at_c.cpp16
-rw-r--r--src/boost/libs/hana/example/at_key.cpp27
-rw-r--r--src/boost/libs/hana/example/back.cpp13
-rw-r--r--src/boost/libs/hana/example/basic_tuple/make.cpp19
-rw-r--r--src/boost/libs/hana/example/cartesian_product.cpp37
-rw-r--r--src/boost/libs/hana/example/chain.cpp41
-rw-r--r--src/boost/libs/hana/example/cmake_integration/CMakeLists.txt12
-rw-r--r--src/boost/libs/hana/example/cmake_integration/main.cpp8
-rw-r--r--src/boost/libs/hana/example/comparing.cpp40
-rw-r--r--src/boost/libs/hana/example/concat.cpp19
-rw-r--r--src/boost/libs/hana/example/contains.cpp23
-rw-r--r--src/boost/libs/hana/example/core/common/common.cpp17
-rw-r--r--src/boost/libs/hana/example/core/common/common_t.cpp16
-rw-r--r--src/boost/libs/hana/example/core/common/has_common.cpp12
-rw-r--r--src/boost/libs/hana/example/core/convert/embedding.cpp36
-rw-r--r--src/boost/libs/hana/example/core/convert/is_convertible.cpp17
-rw-r--r--src/boost/libs/hana/example/core/convert/is_embedded.cpp20
-rw-r--r--src/boost/libs/hana/example/core/convert/to.cpp37
-rw-r--r--src/boost/libs/hana/example/core/default.cpp54
-rw-r--r--src/boost/libs/hana/example/core/is_a.cpp16
-rw-r--r--src/boost/libs/hana/example/core/make.cpp21
-rw-r--r--src/boost/libs/hana/example/core/tag_of.cpp20
-rw-r--r--src/boost/libs/hana/example/core/tag_of_t.cpp15
-rw-r--r--src/boost/libs/hana/example/core/when.cpp19
-rw-r--r--src/boost/libs/hana/example/core/when_valid.cpp19
-rw-r--r--src/boost/libs/hana/example/count.cpp22
-rw-r--r--src/boost/libs/hana/example/count_if.cpp32
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/comparable.cpp55
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/det.cpp48
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/functor.cpp33
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix.cpp69
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/comparable.hpp33
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/det.hpp60
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/functor.hpp33
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/group.hpp28
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/matrix.hpp110
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/monoid.hpp37
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/ring.hpp62
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/ring.cpp96
-rw-r--r--src/boost/libs/hana/example/cycle.cpp14
-rw-r--r--src/boost/libs/hana/example/define_struct.cpp55
-rw-r--r--src/boost/libs/hana/example/detail/wrong.cpp24
-rw-r--r--src/boost/libs/hana/example/div.cpp18
-rw-r--r--src/boost/libs/hana/example/drop_back.cpp23
-rw-r--r--src/boost/libs/hana/example/drop_front.cpp24
-rw-r--r--src/boost/libs/hana/example/drop_front_exactly.cpp22
-rw-r--r--src/boost/libs/hana/example/drop_while.cpp33
-rw-r--r--src/boost/libs/hana/example/duplicate.cpp14
-rw-r--r--src/boost/libs/hana/example/empty.cpp16
-rw-r--r--src/boost/libs/hana/example/equal.cpp18
-rw-r--r--src/boost/libs/hana/example/eval.cpp13
-rw-r--r--src/boost/libs/hana/example/eval_if.cpp38
-rw-r--r--src/boost/libs/hana/example/ext/boost/fusion/deque.cpp35
-rw-r--r--src/boost/libs/hana/example/ext/boost/fusion/list.cpp35
-rw-r--r--src/boost/libs/hana/example/ext/boost/fusion/tuple.cpp35
-rw-r--r--src/boost/libs/hana/example/ext/boost/fusion/vector.cpp35
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/integral_c/integral_constant.cpp24
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/list/comparable.cpp22
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/list/conversion.cpp22
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/list/foldable.cpp31
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/list/iterable.cpp33
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/list/searchable.cpp30
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/vector/comparable.cpp22
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/vector/conversion.cpp22
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/vector/foldable.cpp31
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/vector/iterable.cpp33
-rw-r--r--src/boost/libs/hana/example/ext/boost/mpl/vector/searchable.cpp30
-rw-r--r--src/boost/libs/hana/example/ext/boost/tuple.cpp33
-rw-r--r--src/boost/libs/hana/example/ext/std/array/comparable.cpp24
-rw-r--r--src/boost/libs/hana/example/ext/std/array/foldable.cpp21
-rw-r--r--src/boost/libs/hana/example/ext/std/array/iterable.cpp20
-rw-r--r--src/boost/libs/hana/example/ext/std/array/orderable.cpp23
-rw-r--r--src/boost/libs/hana/example/ext/std/integer_sequence/comparable.cpp22
-rw-r--r--src/boost/libs/hana/example/ext/std/integer_sequence/foldable.cpp25
-rw-r--r--src/boost/libs/hana/example/ext/std/integer_sequence/iterable.cpp23
-rw-r--r--src/boost/libs/hana/example/ext/std/integer_sequence/searchable.cpp25
-rw-r--r--src/boost/libs/hana/example/ext/std/integral_constant.cpp22
-rw-r--r--src/boost/libs/hana/example/ext/std/pair.cpp21
-rw-r--r--src/boost/libs/hana/example/ext/std/ratio/arithmetic.cpp57
-rw-r--r--src/boost/libs/hana/example/ext/std/ratio/comparable.cpp17
-rw-r--r--src/boost/libs/hana/example/ext/std/ratio/orderable.cpp17
-rw-r--r--src/boost/libs/hana/example/ext/std/tuple.cpp32
-rw-r--r--src/boost/libs/hana/example/extend.cpp35
-rw-r--r--src/boost/libs/hana/example/extract.cpp14
-rw-r--r--src/boost/libs/hana/example/fill.cpp22
-rw-r--r--src/boost/libs/hana/example/filter.cpp25
-rw-r--r--src/boost/libs/hana/example/find.cpp31
-rw-r--r--src/boost/libs/hana/example/find_if.cpp39
-rw-r--r--src/boost/libs/hana/example/first.cpp12
-rw-r--r--src/boost/libs/hana/example/flatten.cpp25
-rw-r--r--src/boost/libs/hana/example/fold.cpp38
-rw-r--r--src/boost/libs/hana/example/fold_left.cpp38
-rw-r--r--src/boost/libs/hana/example/fold_right.cpp38
-rw-r--r--src/boost/libs/hana/example/foldable/to.cpp24
-rw-r--r--src/boost/libs/hana/example/for_each.cpp20
-rw-r--r--src/boost/libs/hana/example/front.cpp12
-rw-r--r--src/boost/libs/hana/example/functional/always.cpp12
-rw-r--r--src/boost/libs/hana/example/functional/apply.cpp12
-rw-r--r--src/boost/libs/hana/example/functional/arg.cpp15
-rw-r--r--src/boost/libs/hana/example/functional/capture.cpp18
-rw-r--r--src/boost/libs/hana/example/functional/compose.cpp21
-rw-r--r--src/boost/libs/hana/example/functional/curry.cpp26
-rw-r--r--src/boost/libs/hana/example/functional/demux.cpp30
-rw-r--r--src/boost/libs/hana/example/functional/fix.cpp18
-rw-r--r--src/boost/libs/hana/example/functional/flip.cpp21
-rw-r--r--src/boost/libs/hana/example/functional/id.cpp12
-rw-r--r--src/boost/libs/hana/example/functional/infix.cpp20
-rw-r--r--src/boost/libs/hana/example/functional/iterate.cpp19
-rw-r--r--src/boost/libs/hana/example/functional/lockstep.cpp20
-rw-r--r--src/boost/libs/hana/example/functional/on.cpp36
-rw-r--r--src/boost/libs/hana/example/functional/overload.cpp31
-rw-r--r--src/boost/libs/hana/example/functional/overload_linearly.cpp22
-rw-r--r--src/boost/libs/hana/example/functional/partial.cpp13
-rw-r--r--src/boost/libs/hana/example/functional/placeholder.cpp21
-rw-r--r--src/boost/libs/hana/example/functional/reverse_partial.cpp14
-rw-r--r--src/boost/libs/hana/example/fuse.cpp26
-rw-r--r--src/boost/libs/hana/example/greater.cpp14
-rw-r--r--src/boost/libs/hana/example/greater_equal.cpp15
-rw-r--r--src/boost/libs/hana/example/group.cpp64
-rw-r--r--src/boost/libs/hana/example/hash.cpp44
-rw-r--r--src/boost/libs/hana/example/if.cpp24
-rw-r--r--src/boost/libs/hana/example/in.cpp14
-rw-r--r--src/boost/libs/hana/example/index_if.cpp22
-rw-r--r--src/boost/libs/hana/example/insert.cpp23
-rw-r--r--src/boost/libs/hana/example/insert_range.cpp22
-rw-r--r--src/boost/libs/hana/example/integral_constant.cpp101
-rw-r--r--src/boost/libs/hana/example/intersperse.cpp15
-rw-r--r--src/boost/libs/hana/example/is_disjoint.cpp45
-rw-r--r--src/boost/libs/hana/example/is_empty.cpp15
-rw-r--r--src/boost/libs/hana/example/is_subset.cpp19
-rw-r--r--src/boost/libs/hana/example/iterable/searchable.cpp47
-rw-r--r--src/boost/libs/hana/example/lazy/comonad.cpp30
-rw-r--r--src/boost/libs/hana/example/lazy/functor.cpp17
-rw-r--r--src/boost/libs/hana/example/lazy/make.cpp24
-rw-r--r--src/boost/libs/hana/example/lazy/monad.cpp47
-rw-r--r--src/boost/libs/hana/example/length.cpp20
-rw-r--r--src/boost/libs/hana/example/less.cpp21
-rw-r--r--src/boost/libs/hana/example/less_equal.cpp16
-rw-r--r--src/boost/libs/hana/example/lexicographical_compare.cpp39
-rw-r--r--src/boost/libs/hana/example/lift.cpp15
-rw-r--r--src/boost/libs/hana/example/map/comparable.cpp28
-rw-r--r--src/boost/libs/hana/example/map/difference.cpp45
-rw-r--r--src/boost/libs/hana/example/map/erase_key.cpp33
-rw-r--r--src/boost/libs/hana/example/map/foldable.cpp39
-rw-r--r--src/boost/libs/hana/example/map/insert.cpp32
-rw-r--r--src/boost/libs/hana/example/map/intersection.cpp47
-rw-r--r--src/boost/libs/hana/example/map/keys.cpp30
-rw-r--r--src/boost/libs/hana/example/map/make.cpp29
-rw-r--r--src/boost/libs/hana/example/map/map.cpp76
-rw-r--r--src/boost/libs/hana/example/map/searchable.cpp30
-rw-r--r--src/boost/libs/hana/example/map/symmetric_difference.cpp33
-rw-r--r--src/boost/libs/hana/example/map/to.cpp30
-rw-r--r--src/boost/libs/hana/example/map/union.cpp53
-rw-r--r--src/boost/libs/hana/example/map/values.cpp29
-rw-r--r--src/boost/libs/hana/example/max.cpp15
-rw-r--r--src/boost/libs/hana/example/maximum.cpp25
-rw-r--r--src/boost/libs/hana/example/maximum_by.cpp22
-rw-r--r--src/boost/libs/hana/example/members.cpp25
-rw-r--r--src/boost/libs/hana/example/min.cpp15
-rw-r--r--src/boost/libs/hana/example/minimum.cpp25
-rw-r--r--src/boost/libs/hana/example/minimum_by.cpp23
-rw-r--r--src/boost/libs/hana/example/minus.cpp15
-rw-r--r--src/boost/libs/hana/example/misc/dimensional_analysis.cpp71
-rw-r--r--src/boost/libs/hana/example/misc/from_json.cpp129
-rw-r--r--src/boost/libs/hana/example/misc/indexed_sort.cpp62
-rw-r--r--src/boost/libs/hana/example/misc/infinite_list.cpp116
-rw-r--r--src/boost/libs/hana/example/misc/infinite_set.cpp321
-rw-r--r--src/boost/libs/hana/example/misc/lambda_tuple.cpp244
-rw-r--r--src/boost/libs/hana/example/misc/nth.cpp45
-rw-r--r--src/boost/libs/hana/example/misc/overload_linearly.cpp42
-rw-r--r--src/boost/libs/hana/example/misc/printf.cpp66
-rw-r--r--src/boost/libs/hana/example/misc/ref_tuple.cpp92
-rw-r--r--src/boost/libs/hana/example/misc/restricted_function.cpp143
-rw-r--r--src/boost/libs/hana/example/misc/tree.cpp144
-rw-r--r--src/boost/libs/hana/example/mod.cpp16
-rw-r--r--src/boost/libs/hana/example/monadic_compose.cpp33
-rw-r--r--src/boost/libs/hana/example/monadic_fold_left.cpp72
-rw-r--r--src/boost/libs/hana/example/monadic_fold_right.cpp61
-rw-r--r--src/boost/libs/hana/example/mult.cpp15
-rw-r--r--src/boost/libs/hana/example/negate.cpp15
-rw-r--r--src/boost/libs/hana/example/none.cpp17
-rw-r--r--src/boost/libs/hana/example/none_of.cpp35
-rw-r--r--src/boost/libs/hana/example/not.cpp15
-rw-r--r--src/boost/libs/hana/example/not_equal.cpp18
-rw-r--r--src/boost/libs/hana/example/one.cpp15
-rw-r--r--src/boost/libs/hana/example/optional/applicative.complex.cpp50
-rw-r--r--src/boost/libs/hana/example/optional/applicative.cpp19
-rw-r--r--src/boost/libs/hana/example/optional/comparable.cpp17
-rw-r--r--src/boost/libs/hana/example/optional/foldable.cpp14
-rw-r--r--src/boost/libs/hana/example/optional/functor.cpp16
-rw-r--r--src/boost/libs/hana/example/optional/is_just.cpp15
-rw-r--r--src/boost/libs/hana/example/optional/is_nothing.cpp15
-rw-r--r--src/boost/libs/hana/example/optional/just.cpp13
-rw-r--r--src/boost/libs/hana/example/optional/make.cpp20
-rw-r--r--src/boost/libs/hana/example/optional/maybe.cpp13
-rw-r--r--src/boost/libs/hana/example/optional/monad.cpp23
-rw-r--r--src/boost/libs/hana/example/optional/monad_plus.cpp18
-rw-r--r--src/boost/libs/hana/example/optional/nothing.cpp13
-rw-r--r--src/boost/libs/hana/example/optional/orderable.cpp17
-rw-r--r--src/boost/libs/hana/example/optional/searchable.cpp27
-rw-r--r--src/boost/libs/hana/example/optional/sfinae.cpp21
-rw-r--r--src/boost/libs/hana/example/optional/sfinae_friendly_metafunctions.cpp44
-rw-r--r--src/boost/libs/hana/example/optional/value.cpp20
-rw-r--r--src/boost/libs/hana/example/optional/value_or.cpp13
-rw-r--r--src/boost/libs/hana/example/or.cpp15
-rw-r--r--src/boost/libs/hana/example/ordering.cpp20
-rw-r--r--src/boost/libs/hana/example/overview.cpp59
-rw-r--r--src/boost/libs/hana/example/pair/comparable.cpp15
-rw-r--r--src/boost/libs/hana/example/pair/foldable.cpp16
-rw-r--r--src/boost/libs/hana/example/pair/make.cpp17
-rw-r--r--src/boost/libs/hana/example/pair/orderable.cpp14
-rw-r--r--src/boost/libs/hana/example/pair/product.cpp14
-rw-r--r--src/boost/libs/hana/example/partition.cpp52
-rw-r--r--src/boost/libs/hana/example/permutations.cpp33
-rw-r--r--src/boost/libs/hana/example/plus.cpp16
-rw-r--r--src/boost/libs/hana/example/power.cpp15
-rw-r--r--src/boost/libs/hana/example/prefix.cpp21
-rw-r--r--src/boost/libs/hana/example/prepend.cpp14
-rw-r--r--src/boost/libs/hana/example/product.cpp26
-rw-r--r--src/boost/libs/hana/example/product/comparable.cpp18
-rw-r--r--src/boost/libs/hana/example/product/make.cpp14
-rw-r--r--src/boost/libs/hana/example/range/comparable.cpp20
-rw-r--r--src/boost/libs/hana/example/range/foldable.cpp25
-rw-r--r--src/boost/libs/hana/example/range/iterable.cpp24
-rw-r--r--src/boost/libs/hana/example/range/make.cpp19
-rw-r--r--src/boost/libs/hana/example/range/range_c.cpp19
-rw-r--r--src/boost/libs/hana/example/range/searchable.cpp17
-rw-r--r--src/boost/libs/hana/example/remove.cpp18
-rw-r--r--src/boost/libs/hana/example/remove_at.cpp16
-rw-r--r--src/boost/libs/hana/example/remove_at_c.cpp15
-rw-r--r--src/boost/libs/hana/example/remove_if.cpp25
-rw-r--r--src/boost/libs/hana/example/remove_range.cpp16
-rw-r--r--src/boost/libs/hana/example/remove_range_c.cpp15
-rw-r--r--src/boost/libs/hana/example/repeat.cpp19
-rw-r--r--src/boost/libs/hana/example/replace.cpp17
-rw-r--r--src/boost/libs/hana/example/replace_if.cpp23
-rw-r--r--src/boost/libs/hana/example/replicate.cpp18
-rw-r--r--src/boost/libs/hana/example/reverse.cpp13
-rw-r--r--src/boost/libs/hana/example/reverse_fold.cpp38
-rw-r--r--src/boost/libs/hana/example/scan_left.cpp39
-rw-r--r--src/boost/libs/hana/example/scan_right.cpp39
-rw-r--r--src/boost/libs/hana/example/second.cpp12
-rw-r--r--src/boost/libs/hana/example/sequence/applicative.cpp31
-rw-r--r--src/boost/libs/hana/example/sequence/comparable.cpp15
-rw-r--r--src/boost/libs/hana/example/sequence/foldable.cpp27
-rw-r--r--src/boost/libs/hana/example/sequence/functor.cpp26
-rw-r--r--src/boost/libs/hana/example/sequence/iterable.cpp19
-rw-r--r--src/boost/libs/hana/example/sequence/make.cpp15
-rw-r--r--src/boost/libs/hana/example/sequence/monad.ints.cpp21
-rw-r--r--src/boost/libs/hana/example/sequence/monad.types.cpp67
-rw-r--r--src/boost/libs/hana/example/sequence/monad_plus.cpp27
-rw-r--r--src/boost/libs/hana/example/sequence/orderable.cpp13
-rw-r--r--src/boost/libs/hana/example/sequence/searchable.cpp26
-rw-r--r--src/boost/libs/hana/example/set/comparable.cpp26
-rw-r--r--src/boost/libs/hana/example/set/difference.cpp20
-rw-r--r--src/boost/libs/hana/example/set/erase_key.cpp19
-rw-r--r--src/boost/libs/hana/example/set/foldable.cpp20
-rw-r--r--src/boost/libs/hana/example/set/insert.cpp25
-rw-r--r--src/boost/libs/hana/example/set/intersection.cpp19
-rw-r--r--src/boost/libs/hana/example/set/make.cpp17
-rw-r--r--src/boost/libs/hana/example/set/searchable.cpp25
-rw-r--r--src/boost/libs/hana/example/set/symmetric_difference.cpp19
-rw-r--r--src/boost/libs/hana/example/set/to.cpp28
-rw-r--r--src/boost/libs/hana/example/set/union.cpp23
-rw-r--r--src/boost/libs/hana/example/size.cpp20
-rw-r--r--src/boost/libs/hana/example/slice.cpp43
-rw-r--r--src/boost/libs/hana/example/slice_c.cpp18
-rw-r--r--src/boost/libs/hana/example/sort.cpp47
-rw-r--r--src/boost/libs/hana/example/span.cpp44
-rw-r--r--src/boost/libs/hana/example/string/comparable.cpp20
-rw-r--r--src/boost/libs/hana/example/string/foldable.cpp26
-rw-r--r--src/boost/libs/hana/example/string/from_c_str.cpp20
-rw-r--r--src/boost/libs/hana/example/string/hashable.cpp19
-rw-r--r--src/boost/libs/hana/example/string/iterable.cpp26
-rw-r--r--src/boost/libs/hana/example/string/literal.cpp28
-rw-r--r--src/boost/libs/hana/example/string/macro.cpp17
-rw-r--r--src/boost/libs/hana/example/string/make.cpp17
-rw-r--r--src/boost/libs/hana/example/string/monoid.cpp15
-rw-r--r--src/boost/libs/hana/example/string/orderable.cpp20
-rw-r--r--src/boost/libs/hana/example/string/searchable.cpp21
-rw-r--r--src/boost/libs/hana/example/string/string_c.cpp14
-rw-r--r--src/boost/libs/hana/example/string/to.cpp21
-rw-r--r--src/boost/libs/hana/example/struct.custom_accessor.cpp68
-rw-r--r--src/boost/libs/hana/example/struct.mcd.nested.cpp57
-rw-r--r--src/boost/libs/hana/example/struct.mcd.tag_dispatching.cpp63
-rw-r--r--src/boost/libs/hana/example/struct/comparable.cpp28
-rw-r--r--src/boost/libs/hana/example/struct/foldable.cpp31
-rw-r--r--src/boost/libs/hana/example/struct/keys.cpp29
-rw-r--r--src/boost/libs/hana/example/struct/searchable.cpp46
-rw-r--r--src/boost/libs/hana/example/struct/to.cpp30
-rw-r--r--src/boost/libs/hana/example/suffix.cpp15
-rw-r--r--src/boost/libs/hana/example/sum.cpp20
-rw-r--r--src/boost/libs/hana/example/take_back.cpp19
-rw-r--r--src/boost/libs/hana/example/take_back_c.cpp13
-rw-r--r--src/boost/libs/hana/example/take_front.cpp19
-rw-r--r--src/boost/libs/hana/example/take_front_c.cpp13
-rw-r--r--src/boost/libs/hana/example/take_while.cpp21
-rw-r--r--src/boost/libs/hana/example/tap.cpp28
-rw-r--r--src/boost/libs/hana/example/then.cpp21
-rw-r--r--src/boost/libs/hana/example/transform.cpp40
-rw-r--r--src/boost/libs/hana/example/tuple/foldable.cpp26
-rw-r--r--src/boost/libs/hana/example/tuple/interop.cpp34
-rw-r--r--src/boost/libs/hana/example/tuple/make.cpp19
-rw-r--r--src/boost/libs/hana/example/tuple/tuple.cpp29
-rw-r--r--src/boost/libs/hana/example/tuple/tuple_c.cpp22
-rw-r--r--src/boost/libs/hana/example/tuple/tuple_t.cpp19
-rw-r--r--src/boost/libs/hana/example/tutorial/algorithms.cpp148
-rw-r--r--src/boost/libs/hana/example/tutorial/appendix_mpl.cpp697
-rw-r--r--src/boost/libs/hana/example/tutorial/concepts.cpp64
-rw-r--r--src/boost/libs/hana/example/tutorial/constant_side_effects.cpp36
-rw-r--r--src/boost/libs/hana/example/tutorial/containers.cpp106
-rw-r--r--src/boost/libs/hana/example/tutorial/ext/fusion_to_hana.cpp31
-rw-r--r--src/boost/libs/hana/example/tutorial/ext/mpl_vector.cpp40
-rw-r--r--src/boost/libs/hana/example/tutorial/ext/ratio_plus.cpp15
-rw-r--r--src/boost/libs/hana/example/tutorial/include_ext.cpp16
-rw-r--r--src/boost/libs/hana/example/tutorial/integral-branching.cpp55
-rw-r--r--src/boost/libs/hana/example/tutorial/integral.cpp128
-rw-r--r--src/boost/libs/hana/example/tutorial/introduction.cpp80
-rw-r--r--src/boost/libs/hana/example/tutorial/introspection.adapt.cpp100
-rw-r--r--src/boost/libs/hana/example/tutorial/introspection.cpp158
-rw-r--r--src/boost/libs/hana/example/tutorial/introspection.json.cpp81
-rw-r--r--src/boost/libs/hana/example/tutorial/introspection.sfinae.cpp44
-rw-r--r--src/boost/libs/hana/example/tutorial/mpl_cheatsheet.cpp58
-rw-r--r--src/boost/libs/hana/example/tutorial/quickstart.cpp101
-rw-r--r--src/boost/libs/hana/example/tutorial/quickstart.switchAny.cpp105
-rw-r--r--src/boost/libs/hana/example/tutorial/rationale.container.cpp52
-rw-r--r--src/boost/libs/hana/example/tutorial/tag_dispatching.cpp170
-rw-r--r--src/boost/libs/hana/example/tutorial/type.cpp260
-rw-r--r--src/boost/libs/hana/example/type/alignof.cpp16
-rw-r--r--src/boost/libs/hana/example/type/basic_type.cpp31
-rw-r--r--src/boost/libs/hana/example/type/comparable.cpp17
-rw-r--r--src/boost/libs/hana/example/type/decltype.cpp20
-rw-r--r--src/boost/libs/hana/example/type/hashable.cpp23
-rw-r--r--src/boost/libs/hana/example/type/integral.cpp18
-rw-r--r--src/boost/libs/hana/example/type/is_valid.cpp31
-rw-r--r--src/boost/libs/hana/example/type/make.cpp19
-rw-r--r--src/boost/libs/hana/example/type/metafunction.cpp26
-rw-r--r--src/boost/libs/hana/example/type/metafunction_class.cpp26
-rw-r--r--src/boost/libs/hana/example/type/sizeof.cpp16
-rw-r--r--src/boost/libs/hana/example/type/template.cpp26
-rw-r--r--src/boost/libs/hana/example/type/trait.cpp17
-rw-r--r--src/boost/libs/hana/example/type/typeid.cpp36
-rw-r--r--src/boost/libs/hana/example/unfold_left.cpp28
-rw-r--r--src/boost/libs/hana/example/unfold_right.cpp28
-rw-r--r--src/boost/libs/hana/example/unique.cpp38
-rw-r--r--src/boost/libs/hana/example/unpack.cpp18
-rw-r--r--src/boost/libs/hana/example/value.cpp14
-rw-r--r--src/boost/libs/hana/example/value_of.cpp16
-rw-r--r--src/boost/libs/hana/example/version.cpp16
-rw-r--r--src/boost/libs/hana/example/wandbox.cpp88
-rw-r--r--src/boost/libs/hana/example/while.cpp45
-rw-r--r--src/boost/libs/hana/example/zero.cpp15
-rw-r--r--src/boost/libs/hana/example/zip.cpp17
-rw-r--r--src/boost/libs/hana/example/zip_shortest.cpp17
-rw-r--r--src/boost/libs/hana/example/zip_shortest_with.cpp19
-rw-r--r--src/boost/libs/hana/example/zip_with.cpp51
370 files changed, 13061 insertions, 0 deletions
diff --git a/src/boost/libs/hana/example/CMakeLists.txt b/src/boost/libs/hana/example/CMakeLists.txt
new file mode 100644
index 000000000..0f59c5120
--- /dev/null
+++ b/src/boost/libs/hana/example/CMakeLists.txt
@@ -0,0 +1,68 @@
+# Copyright Louis Dionne 2013-2017
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+add_custom_target(examples COMMENT "Build all the examples.")
+add_dependencies(hana_check examples)
+
+
+##############################################################################
+# Take note of files that depend on Boost
+##############################################################################
+list(APPEND EXAMPLES_REQUIRING_BOOST
+ "ext/boost/*.cpp"
+ "tutorial/appendix_mpl.cpp"
+ "tutorial/ext/fusion_to_hana.cpp"
+ "tutorial/ext/mpl_vector.cpp"
+ "tutorial/integral.cpp"
+ "tutorial/introduction.cpp"
+ "tutorial/mpl_cheatsheet.cpp"
+ "tutorial/quadrants.cpp"
+ "tutorial/quickstart.switchAny.cpp"
+ "tutorial/rationale.container.cpp"
+ "tutorial/type.cpp"
+ "type/basic_type.cpp")
+file(GLOB_RECURSE EXAMPLES_REQUIRING_BOOST ${EXAMPLES_REQUIRING_BOOST})
+
+
+##############################################################################
+# Caveats: Take note of examples that are not supported.
+##############################################################################
+if (NOT Boost_FOUND)
+ list(APPEND EXCLUDED_EXAMPLES ${EXAMPLES_REQUIRING_BOOST})
+endif()
+
+list(APPEND EXCLUDED_EXAMPLES "cmake_integration/main.cpp")
+
+
+##############################################################################
+# Add all the examples
+##############################################################################
+file(GLOB_RECURSE EXAMPLES "*.cpp")
+file(GLOB_RECURSE EXCLUDED_EXAMPLES ${EXCLUDED_EXAMPLES})
+list(REMOVE_ITEM EXAMPLES "" ${EXCLUDED_EXAMPLES})
+
+# Several examples have unused parameters because the name of the parameters
+# are useful for illustration, even if the implementation is not actually
+# presented. We don't want to generate warnings for that or need to comment
+# out all unused parameter names.
+include(CheckCXXCompilerFlag)
+check_cxx_compiler_flag(-Wno-unused-parameter BOOST_HANA_HAS_WNO_UNUSED_PARAMETER)
+check_cxx_compiler_flag(-Wno-unused-lambda-capture BOOST_HANA_HAS_WNO_UNUSED_LAMBDA_CAPTURE)
+
+foreach(_file IN LISTS EXAMPLES)
+ boost_hana_target_name_for(_target "${_file}")
+ add_executable(${_target} EXCLUDE_FROM_ALL "${_file}")
+ add_test(${_target} "${CMAKE_CURRENT_BINARY_DIR}/${_target}")
+ boost_hana_set_test_properties(${_target})
+ if (_file IN_LIST EXAMPLES_REQUIRING_BOOST)
+ target_link_libraries(${_target} PRIVATE Boost::boost)
+ endif()
+ if (BOOST_HANA_HAS_WNO_UNUSED_PARAMETER)
+ target_compile_options(${_target} PRIVATE -Wno-unused-parameter)
+ endif()
+ if (BOOST_HANA_HAS_WNO_UNUSED_LAMBDA_CAPTURE)
+ target_compile_options(${_target} PRIVATE -Wno-unused-lambda-capture)
+ endif()
+ add_dependencies(examples ${_target})
+endforeach()
diff --git a/src/boost/libs/hana/example/accessors.cpp b/src/boost/libs/hana/example/accessors.cpp
new file mode 100644
index 000000000..cbc489019
--- /dev/null
+++ b/src/boost/libs/hana/example/accessors.cpp
@@ -0,0 +1,42 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/accessors.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/string.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (unsigned short, age)
+ );
+};
+
+int main() {
+ constexpr auto accessors = hana::accessors<Person>();
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::first(accessors[hana::size_c<0>]) == BOOST_HANA_STRING("name")
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::first(accessors[hana::size_c<1>]) == BOOST_HANA_STRING("age")
+ );
+
+ constexpr auto get_name = hana::second(accessors[hana::size_c<0>]);
+ constexpr auto get_age = hana::second(accessors[hana::size_c<1>]);
+
+ Person john{"John", 30};
+ BOOST_HANA_RUNTIME_CHECK(get_name(john) == "John");
+ BOOST_HANA_RUNTIME_CHECK(get_age(john) == 30);
+}
diff --git a/src/boost/libs/hana/example/adapt_adt.cpp b/src/boost/libs/hana/example/adapt_adt.cpp
new file mode 100644
index 000000000..54e591dca
--- /dev/null
+++ b/src/boost/libs/hana/example/adapt_adt.cpp
@@ -0,0 +1,67 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/accessors.hpp>
+#include <boost/hana/adapt_adt.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+namespace ns {
+ struct Person {
+ explicit Person(std::string const& name, int age)
+ : name_(name), age_(age)
+ { }
+ std::string const& get_name() const { return name_; }
+ int get_age() const { return age_; }
+
+ private:
+ std::string name_;
+ int age_;
+ };
+}
+
+BOOST_HANA_ADAPT_ADT(ns::Person,
+ (name, [](ns::Person const& p) { return p.get_name(); }),
+ (age, [](ns::Person const& p) { return p.get_age(); })
+);
+
+// The member names are hana::strings:
+auto names = hana::transform(hana::accessors<ns::Person>(), hana::first);
+BOOST_HANA_CONSTANT_CHECK(
+ names == hana::make_tuple(BOOST_HANA_STRING("name"), BOOST_HANA_STRING("age"))
+);
+
+int main() {
+ ns::Person john{"John", 30}, bob{"Bob", 40};
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(john, john));
+ BOOST_HANA_RUNTIME_CHECK(hana::not_equal(john, bob));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("name")) == hana::just("John"));
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("age")) == hana::just(30));
+ BOOST_HANA_CONSTANT_CHECK(hana::find(john, BOOST_HANA_STRING("foo")) == hana::nothing);
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to_tuple(john) == hana::make_tuple(
+ hana::make_pair(BOOST_HANA_STRING("name"), "John"),
+ hana::make_pair(BOOST_HANA_STRING("age"), 30)
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to_map(john) == hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("name"), "John"),
+ hana::make_pair(BOOST_HANA_STRING("age"), 30)
+ ));
+}
diff --git a/src/boost/libs/hana/example/adapt_struct.cpp b/src/boost/libs/hana/example/adapt_struct.cpp
new file mode 100644
index 000000000..9170e2ce1
--- /dev/null
+++ b/src/boost/libs/hana/example/adapt_struct.cpp
@@ -0,0 +1,60 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/accessors.hpp>
+#include <boost/hana/adapt_struct.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+namespace ns {
+ struct Person {
+ std::string name;
+ int age;
+ };
+}
+
+BOOST_HANA_ADAPT_STRUCT(ns::Person,
+ name,
+ age
+);
+
+// The member names are hana::strings:
+auto names = hana::transform(hana::accessors<ns::Person>(), hana::first);
+BOOST_HANA_CONSTANT_CHECK(
+ names == hana::make_tuple(BOOST_HANA_STRING("name"), BOOST_HANA_STRING("age"))
+);
+
+int main() {
+ ns::Person john{"John", 30}, bob{"Bob", 40};
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(john, john));
+ BOOST_HANA_RUNTIME_CHECK(hana::not_equal(john, bob));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("name")) == hana::just("John"));
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("age")) == hana::just(30));
+ BOOST_HANA_CONSTANT_CHECK(hana::find(john, BOOST_HANA_STRING("foo")) == hana::nothing);
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to_tuple(john) == hana::make_tuple(
+ hana::make_pair(BOOST_HANA_STRING("name"), "John"),
+ hana::make_pair(BOOST_HANA_STRING("age"), 30)
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to_map(john) == hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("name"), "John"),
+ hana::make_pair(BOOST_HANA_STRING("age"), 30)
+ ));
+}
diff --git a/src/boost/libs/hana/example/adjust.cpp b/src/boost/libs/hana/example/adjust.cpp
new file mode 100644
index 000000000..74ad18367
--- /dev/null
+++ b/src/boost/libs/hana/example/adjust.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/adjust.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto negate = [](auto x) {
+ return -x;
+};
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::adjust(hana::make_tuple(1, 4, 9, 2, 3, 4), 4, negate)
+ ==
+ hana::make_tuple(1, -4, 9, 2, 3, -4)
+ );
+}
diff --git a/src/boost/libs/hana/example/adjust_if.cpp b/src/boost/libs/hana/example/adjust_if.cpp
new file mode 100644
index 000000000..399f9e60f
--- /dev/null
+++ b/src/boost/libs/hana/example/adjust_if.cpp
@@ -0,0 +1,27 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/adjust_if.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto negative = [](auto x) {
+ return x < 0;
+};
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto negate = [](auto x) {
+ return -x;
+};
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::adjust_if(hana::make_tuple(-3, -2, -1, 0, 1, 2, 3), negative, negate)
+ ==
+ hana::make_tuple(3, 2, 1, 0, 1, 2, 3)
+ );
+}
diff --git a/src/boost/libs/hana/example/all.cpp b/src/boost/libs/hana/example/all.cpp
new file mode 100644
index 000000000..b34e31eb0
--- /dev/null
+++ b/src/boost/libs/hana/example/all.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/all.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::all(hana::make_tuple(hana::true_c, true, hana::true_c)), "");
+BOOST_HANA_CONSTANT_CHECK(!hana::all(hana::make_tuple(true, hana::false_c, hana::true_c)));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/all_of.cpp b/src/boost/libs/hana/example/all_of.cpp
new file mode 100644
index 000000000..6a7dee956
--- /dev/null
+++ b/src/boost/libs/hana/example/all_of.cpp
@@ -0,0 +1,39 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/traits.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto is_odd = [](auto x) {
+ return x % 2_c != 0_c;
+};
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::all_of(hana::make_tuple(1, 3), is_odd));
+ BOOST_HANA_CONSTANT_CHECK(!hana::all_of(hana::make_tuple(3_c, 4_c), is_odd));
+
+ BOOST_HANA_CONSTANT_CHECK(
+ !hana::all_of(hana::make_tuple(hana::type<void>{}, hana::type<char&>{}),
+ hana::traits::is_void)
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::all_of(hana::make_tuple(hana::type_c<int>, hana::type_c<char>),
+ hana::traits::is_integral)
+ );
+}
diff --git a/src/boost/libs/hana/example/and.cpp b/src/boost/libs/hana/example/and.cpp
new file mode 100644
index 000000000..f33a32d70
--- /dev/null
+++ b/src/boost/libs/hana/example/and.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/and.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::and_(hana::true_c, hana::true_c, hana::true_c, hana::true_c));
+static_assert(!hana::and_(hana::true_c, false, hana::true_c, hana::true_c), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/any.cpp b/src/boost/libs/hana/example/any.cpp
new file mode 100644
index 000000000..14e0861f5
--- /dev/null
+++ b/src/boost/libs/hana/example/any.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/any.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::any(hana::make_tuple(false, hana::false_c, hana::true_c)));
+static_assert(hana::any(hana::make_tuple(false, hana::false_c, true)), "");
+static_assert(!hana::any(hana::make_tuple(false, hana::false_c, hana::false_c)), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/any_of.cpp b/src/boost/libs/hana/example/any_of.cpp
new file mode 100644
index 000000000..330c10631
--- /dev/null
+++ b/src/boost/libs/hana/example/any_of.cpp
@@ -0,0 +1,39 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/traits.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto is_odd = [](auto x) {
+ return x % 2_c != 0_c;
+};
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::any_of(hana::make_tuple(1, 2), is_odd));
+ BOOST_HANA_CONSTANT_CHECK(!hana::any_of(hana::make_tuple(2_c, 4_c), is_odd));
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(hana::make_tuple(hana::type<void>{}, hana::type<char&>{}),
+ hana::traits::is_void)
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ !hana::any_of(hana::make_tuple(hana::type<void>{}, hana::type<char&>{}),
+ hana::traits::is_integral)
+ );
+}
diff --git a/src/boost/libs/hana/example/ap.cpp b/src/boost/libs/hana/example/ap.cpp
new file mode 100644
index 000000000..51000d91e
--- /dev/null
+++ b/src/boost/libs/hana/example/ap.cpp
@@ -0,0 +1,48 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/ap.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <functional>
+namespace hana = boost::hana;
+
+
+int main() {
+ // with tuples
+ static_assert(
+ hana::ap(hana::make_tuple(std::plus<>{}), hana::make_tuple(1, 2),
+ hana::make_tuple(3, 4, 5))
+ ==
+ hana::make_tuple(
+ 1 + 3, 1 + 4, 1 + 5,
+ 2 + 3, 2 + 4, 2 + 5
+ )
+ , "");
+
+ // with optional values
+ BOOST_HANA_CONSTEXPR_LAMBDA auto multiply = [](auto a, auto b, auto c) {
+ return a * b * c;
+ };
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::ap(hana::just(multiply), hana::just(1),
+ hana::just(2),
+ hana::just(3))
+ ==
+ hana::just(1 * 2 * 3)
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::ap(hana::just(multiply), hana::just(1),
+ hana::nothing,
+ hana::just(3))
+ ==
+ hana::nothing
+ );
+}
diff --git a/src/boost/libs/hana/example/append.cpp b/src/boost/libs/hana/example/append.cpp
new file mode 100644
index 000000000..8731cb733
--- /dev/null
+++ b/src/boost/libs/hana/example/append.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/append.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::append(hana::make_tuple(), 1) == hana::make_tuple(1), "");
+static_assert(hana::append(hana::make_tuple(1, '2'), 3.3) == hana::make_tuple(1, '2', 3.3), "");
+static_assert(hana::append(hana::append(hana::append(hana::make_tuple(), 1), '2'), 3.3) == hana::make_tuple(1, '2', 3.3), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/at.cpp b/src/boost/libs/hana/example/at.cpp
new file mode 100644
index 000000000..802a4f7d9
--- /dev/null
+++ b/src/boost/libs/hana/example/at.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/at.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.0);
+
+static_assert(hana::at(xs, hana::size_t<0>{}) == 0, "");
+static_assert(hana::at(xs, hana::size_t<1>{}) == '1', "");
+static_assert(hana::at(xs, hana::size_t<2>{}) == 2.0, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/at_c.cpp b/src/boost/libs/hana/example/at_c.cpp
new file mode 100644
index 000000000..df4e257fa
--- /dev/null
+++ b/src/boost/libs/hana/example/at_c.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/at.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.0);
+
+static_assert(hana::at_c<0>(xs) == 0, "");
+static_assert(hana::at_c<1>(xs) == '1', "");
+static_assert(hana::at_c<2>(xs) == 2.0, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/at_key.cpp b/src/boost/libs/hana/example/at_key.cpp
new file mode 100644
index 000000000..41f29b573
--- /dev/null
+++ b/src/boost/libs/hana/example/at_key.cpp
@@ -0,0 +1,27 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto m = hana::make_map(
+ hana::make_pair(hana::type<int>{}, std::string{"int"}),
+ hana::make_pair(hana::int_<3>{}, std::string{"3"})
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(m, hana::type<int>{}) == "int");
+
+ // usage as operator[]
+ BOOST_HANA_RUNTIME_CHECK(m[hana::type<int>{}] == "int");
+ BOOST_HANA_RUNTIME_CHECK(m[hana::int_<3>{}] == "3");
+}
diff --git a/src/boost/libs/hana/example/back.cpp b/src/boost/libs/hana/example/back.cpp
new file mode 100644
index 000000000..4ca689c13
--- /dev/null
+++ b/src/boost/libs/hana/example/back.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/back.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::back(hana::make_tuple(1, '2', 3.3)) == 3.3, "");
+static_assert(hana::back(hana::make_tuple(1, '2', 3.3, nullptr)) == nullptr, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/basic_tuple/make.cpp b/src/boost/libs/hana/example/basic_tuple/make.cpp
new file mode 100644
index 000000000..b037dd04c
--- /dev/null
+++ b/src/boost/libs/hana/example/basic_tuple/make.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/basic_tuple.hpp>
+#include <boost/hana/core/make.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+constexpr hana::basic_tuple<int, char, double> xs{1, '2', 3.3};
+constexpr auto ys = hana::make<hana::basic_tuple_tag>(1, '2', 3.3);
+constexpr auto zs = hana::make_basic_tuple(1, '2', 3.3);
+
+static_assert(std::is_same<decltype(ys), decltype(xs)>::value, "");
+static_assert(std::is_same<decltype(zs), decltype(xs)>::value, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/cartesian_product.cpp b/src/boost/libs/hana/example/cartesian_product.cpp
new file mode 100644
index 000000000..22aab5070
--- /dev/null
+++ b/src/boost/libs/hana/example/cartesian_product.cpp
@@ -0,0 +1,37 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/cartesian_product.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto tuples = hana::make_tuple(
+ hana::make_tuple(1, 2, 3),
+ hana::make_tuple('a', 'b'),
+ hana::make_tuple(hana::type_c<int>, hana::type_c<char>)
+);
+
+constexpr auto prod = hana::make_tuple(
+ hana::make_tuple(1, 'a', hana::type_c<int>),
+ hana::make_tuple(1, 'a', hana::type_c<char>),
+ hana::make_tuple(1, 'b', hana::type_c<int>),
+ hana::make_tuple(1, 'b', hana::type_c<char>),
+
+ hana::make_tuple(2, 'a', hana::type_c<int>),
+ hana::make_tuple(2, 'a', hana::type_c<char>),
+ hana::make_tuple(2, 'b', hana::type_c<int>),
+ hana::make_tuple(2, 'b', hana::type_c<char>),
+
+ hana::make_tuple(3, 'a', hana::type_c<int>),
+ hana::make_tuple(3, 'a', hana::type_c<char>),
+ hana::make_tuple(3, 'b', hana::type_c<int>),
+ hana::make_tuple(3, 'b', hana::type_c<char>)
+);
+
+static_assert(hana::cartesian_product(tuples) == prod, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/chain.cpp b/src/boost/libs/hana/example/chain.cpp
new file mode 100644
index 000000000..0e7850b74
--- /dev/null
+++ b/src/boost/libs/hana/example/chain.cpp
@@ -0,0 +1,41 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto deref = [](auto x) -> decltype(*x) {
+ return *x;
+};
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto age = [](auto x) -> decltype(x.age) {
+ return x.age;
+};
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto f = [](auto x) {
+ return hana::chain(hana::sfinae(deref)(x), hana::sfinae(age));
+};
+
+struct Person {
+ unsigned int age;
+ // ...
+};
+
+int main() {
+ constexpr Person john{30};
+
+ // Can't dereference a non-pointer.
+ BOOST_HANA_CONSTANT_CHECK(f(john) == hana::nothing);
+
+ // `int` has no member named `age`.
+ BOOST_HANA_CONSTANT_CHECK(f(1) == hana::nothing);
+
+ // All is good.
+ BOOST_HANA_CONSTEXPR_CHECK(f(&john) == hana::just(30u));
+}
diff --git a/src/boost/libs/hana/example/cmake_integration/CMakeLists.txt b/src/boost/libs/hana/example/cmake_integration/CMakeLists.txt
new file mode 100644
index 000000000..000d03dd8
--- /dev/null
+++ b/src/boost/libs/hana/example/cmake_integration/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright Louis Dionne 2013-2017
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+# [snip]
+cmake_minimum_required(VERSION 3.0)
+project(external CXX)
+
+find_package(Hana REQUIRED)
+add_executable(external main.cpp)
+target_link_libraries(external hana)
+# [snip]
diff --git a/src/boost/libs/hana/example/cmake_integration/main.cpp b/src/boost/libs/hana/example/cmake_integration/main.cpp
new file mode 100644
index 000000000..e35e81350
--- /dev/null
+++ b/src/boost/libs/hana/example/cmake_integration/main.cpp
@@ -0,0 +1,8 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+
+
+int main() { }
diff --git a/src/boost/libs/hana/example/comparing.cpp b/src/boost/libs/hana/example/comparing.cpp
new file mode 100644
index 000000000..8c6538816
--- /dev/null
+++ b/src/boost/libs/hana/example/comparing.cpp
@@ -0,0 +1,40 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/comparing.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/group.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto sequences = hana::make_tuple(
+ hana::make_tuple(1, 2, 3),
+ hana::make_tuple('x', 'y', 'z'),
+ hana::range_c<long, 0, 1>,
+ hana::tuple_t<char, int>,
+ hana::range_c<int, 0, 2>,
+ hana::make_tuple(123.4, nullptr)
+ );
+
+ constexpr auto grouped = hana::group.by(hana::comparing(hana::length), sequences);
+
+ static_assert(grouped == hana::make_tuple(
+ hana::make_tuple(
+ hana::make_tuple(1, 2, 3),
+ hana::make_tuple('x', 'y', 'z')
+ ),
+ hana::make_tuple(
+ hana::range_c<long, 0, 1>
+ ),
+ hana::make_tuple(
+ hana::tuple_t<char, int>,
+ hana::range_c<int, 0, 2>,
+ hana::make_tuple(123.4, nullptr)
+ )
+ ), "");
+}
diff --git a/src/boost/libs/hana/example/concat.cpp b/src/boost/libs/hana/example/concat.cpp
new file mode 100644
index 000000000..d344a58dd
--- /dev/null
+++ b/src/boost/libs/hana/example/concat.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/concat.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+static_assert(
+ hana::concat(hana::make_tuple(1, '2'), hana::make_tuple(3.3, 4_c))
+ ==
+ hana::make_tuple(1, '2', 3.3, 4_c)
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/contains.cpp b/src/boost/libs/hana/example/contains.cpp
new file mode 100644
index 000000000..ce7bc5d19
--- /dev/null
+++ b/src/boost/libs/hana/example/contains.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::contains(hana::make_tuple(2, hana::int_c<2>, hana::int_c<3>, 'x'), hana::int_c<3>));
+
+BOOST_HANA_CONSTANT_CHECK(hana::contains(hana::make_set(hana::int_c<3>, hana::type_c<void>), hana::type_c<void>));
+
+// contains can be applied in infix notation
+BOOST_HANA_CONSTANT_CHECK(
+ hana::make_tuple(2, hana::int_c<2>, hana::int_c<3>, 'x') ^hana::contains^ hana::int_c<2>
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/common/common.cpp b/src/boost/libs/hana/example/core/common/common.cpp
new file mode 100644
index 000000000..30883b276
--- /dev/null
+++ b/src/boost/libs/hana/example/core/common/common.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/common.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct Person { };
+struct Employee : Person { };
+
+static_assert(std::is_same<hana::common<int, float>::type, float>{}, "");
+static_assert(std::is_same<hana::common<Person, Employee>::type, Person>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/common/common_t.cpp b/src/boost/libs/hana/example/core/common/common_t.cpp
new file mode 100644
index 000000000..25df42df7
--- /dev/null
+++ b/src/boost/libs/hana/example/core/common/common_t.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/common.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+static_assert(std::is_same<
+ hana::common_t<int, float>,
+ hana::common<int, float>::type
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/common/has_common.cpp b/src/boost/libs/hana/example/core/common/has_common.cpp
new file mode 100644
index 000000000..2dcd40f25
--- /dev/null
+++ b/src/boost/libs/hana/example/core/common/has_common.cpp
@@ -0,0 +1,12 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/common.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::has_common<int, float>{}, "");
+static_assert(!hana::has_common<void, float>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/convert/embedding.cpp b/src/boost/libs/hana/example/core/convert/embedding.cpp
new file mode 100644
index 000000000..618637a2b
--- /dev/null
+++ b/src/boost/libs/hana/example/core/convert/embedding.cpp
@@ -0,0 +1,36 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/core/when.hpp>
+
+#include <vector>
+namespace hana = boost::hana;
+
+
+namespace boost { namespace hana {
+ template <typename To, typename From>
+ struct to_impl<std::vector<To>, std::vector<From>,
+ when<is_convertible<From, To>::value>>
+ : embedding<is_embedded<From, To>::value>
+ {
+ static std::vector<To> apply(std::vector<From> const& xs) {
+ std::vector<To> result;
+ for (auto const& x: xs)
+ result.push_back(to<To>(x));
+ return result;
+ }
+ };
+}}
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::to<std::vector<int>>(std::vector<float>{1.1, 2.2, 3.3})
+ ==
+ std::vector<int>{1, 2, 3}
+ );
+
+ static_assert(!hana::is_embedded<std::vector<float>, std::vector<int>>{}, "");
+}
diff --git a/src/boost/libs/hana/example/core/convert/is_convertible.cpp b/src/boost/libs/hana/example/core/convert/is_convertible.cpp
new file mode 100644
index 000000000..e076924dc
--- /dev/null
+++ b/src/boost/libs/hana/example/core/convert/is_convertible.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/to.hpp>
+namespace hana = boost::hana;
+
+
+struct Person { };
+struct Employee : Person { };
+
+static_assert(hana::is_convertible<Employee, Person>{}, "");
+static_assert(!hana::is_convertible<Person, Employee>{}, "");
+
+static_assert(hana::is_convertible<int, float>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/convert/is_embedded.cpp b/src/boost/libs/hana/example/core/convert/is_embedded.cpp
new file mode 100644
index 000000000..2f0906d49
--- /dev/null
+++ b/src/boost/libs/hana/example/core/convert/is_embedded.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/to.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::is_embedded<int, long>{}, "");
+
+// int -> unsigned long could cause negative values to be lost
+static_assert(!hana::is_embedded<int, unsigned int long>{}, "");
+
+// similarly, float can't represent all the values of int
+static_assert(!hana::is_embedded<int, float>{}, "");
+
+// OK, the conversion is lossless
+static_assert(hana::is_embedded<float, double>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/convert/to.cpp b/src/boost/libs/hana/example/core/convert/to.cpp
new file mode 100644
index 000000000..07244ea2f
--- /dev/null
+++ b/src/boost/libs/hana/example/core/convert/to.cpp
@@ -0,0 +1,37 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+template <typename X, typename Y, typename Z>
+struct Triple {
+ X first;
+ Y second;
+ Z third;
+};
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto triple = [](auto x, auto y, auto z) {
+ return Triple<decltype(x), decltype(y), decltype(z)>{x, y, z};
+};
+
+namespace boost { namespace hana {
+ template <typename X, typename Y, typename Z>
+ struct to_impl<tuple_tag, Triple<X, Y, Z>> {
+ static constexpr auto apply(Triple<X, Y, Z> xs) {
+ return make_tuple(xs.first, xs.second, xs.third);
+ }
+ };
+}}
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::to<hana::tuple_tag>(triple(1, '2', 3.3)) == hana::make_tuple(1, '2', 3.3)
+ );
+}
diff --git a/src/boost/libs/hana/example/core/default.cpp b/src/boost/libs/hana/example/core/default.cpp
new file mode 100644
index 000000000..73ff31b54
--- /dev/null
+++ b/src/boost/libs/hana/example/core/default.cpp
@@ -0,0 +1,54 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/default.hpp>
+#include <boost/hana/core/tag_of.hpp>
+
+#include <algorithm>
+#include <iterator>
+#include <sstream>
+#include <vector>
+namespace hana = boost::hana;
+
+
+// In the header defining the concept of a Printable
+template <typename T>
+struct print_impl : hana::default_ {
+ template <typename Stream, typename X>
+ static void apply(Stream& out, X const& x)
+ { out << x; }
+};
+
+auto print = [](auto& stream, auto const& x) {
+ return print_impl<hana::tag_of_t<decltype(x)>>::apply(stream, x);
+};
+
+// In some other header
+template <typename T>
+struct print_impl<std::vector<T>> {
+ template <typename Stream>
+ static void apply(Stream& out, std::vector<T> const& xs) {
+ out << '[';
+ std::copy(begin(xs), end(xs), std::ostream_iterator<T>{out, ", "});
+ out << ']';
+ }
+};
+
+static_assert(hana::is_default<print_impl<int>>{}, "");
+static_assert(!hana::is_default<print_impl<std::vector<int>>>{}, "");
+
+int main() {
+ {
+ std::stringstream s;
+ print(s, std::vector<int>{1, 2, 3});
+ BOOST_HANA_RUNTIME_CHECK(s.str() == "[1, 2, 3, ]");
+ }
+
+ {
+ std::stringstream s;
+ print(s, "abcd");
+ BOOST_HANA_RUNTIME_CHECK(s.str() == "abcd");
+ }
+}
diff --git a/src/boost/libs/hana/example/core/is_a.cpp b/src/boost/libs/hana/example/core/is_a.cpp
new file mode 100644
index 000000000..a534ea12d
--- /dev/null
+++ b/src/boost/libs/hana/example/core/is_a.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/is_a.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::is_a<hana::tuple_tag, decltype(hana::make_tuple(1, '2', 3.3))>, "");
+static_assert(!hana::is_a<hana::tuple_tag, void>, "");
+static_assert(hana::is_an<hana::integral_constant_tag<int>>(hana::int_c<10>), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/make.cpp b/src/boost/libs/hana/example/core/make.cpp
new file mode 100644
index 000000000..59185c0e1
--- /dev/null
+++ b/src/boost/libs/hana/example/core/make.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::tuple<int, char, double, std::string> ts{1, '2', 3.3, "abcd"};
+ BOOST_HANA_RUNTIME_CHECK(ts == hana::make_tuple(1, '2', 3.3, std::string{"abcd"}));
+
+ // std::string has no notion of tag, but it still works with make<>
+ std::string foo{"foo"};
+ BOOST_HANA_RUNTIME_CHECK(hana::make<std::string>("foo") == foo);
+}
diff --git a/src/boost/libs/hana/example/core/tag_of.cpp b/src/boost/libs/hana/example/core/tag_of.cpp
new file mode 100644
index 000000000..2c9ddf7b4
--- /dev/null
+++ b/src/boost/libs/hana/example/core/tag_of.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/tag_of.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+static_assert(std::is_same<hana::tag_of<int>::type, int>{}, "");
+static_assert(std::is_same<hana::tag_of<int&>::type, int>{}, "");
+static_assert(std::is_same<hana::tag_of<int const&>::type, int>{}, "");
+
+struct PersonTag;
+struct Person { using hana_tag = PersonTag; };
+static_assert(std::is_same<hana::tag_of<Person>::type, PersonTag>{}, "");
+static_assert(std::is_same<hana::tag_of<Person volatile&&>::type, PersonTag>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/tag_of_t.cpp b/src/boost/libs/hana/example/core/tag_of_t.cpp
new file mode 100644
index 000000000..6689ef96e
--- /dev/null
+++ b/src/boost/libs/hana/example/core/tag_of_t.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/tag_of.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct PersonTag;
+struct Person { using hana_tag = PersonTag; };
+static_assert(std::is_same<hana::tag_of_t<Person>, PersonTag>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/when.cpp b/src/boost/libs/hana/example/core/when.cpp
new file mode 100644
index 000000000..2c5e34d29
--- /dev/null
+++ b/src/boost/libs/hana/example/core/when.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/when.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename T, typename = hana::when<true>>
+struct base_template;
+
+template <typename T>
+struct base_template<T, hana::when<std::is_integral<T>::value>> {
+ // something useful...
+};
+
+int main() { }
diff --git a/src/boost/libs/hana/example/core/when_valid.cpp b/src/boost/libs/hana/example/core/when_valid.cpp
new file mode 100644
index 000000000..2ed680fab
--- /dev/null
+++ b/src/boost/libs/hana/example/core/when_valid.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/when.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename T, typename = hana::when<true>>
+struct base_template;
+
+template <typename T>
+struct base_template<T, hana::when_valid<typename T::value_type>> {
+ // something useful...
+};
+
+int main() { }
diff --git a/src/boost/libs/hana/example/count.cpp b/src/boost/libs/hana/example/count.cpp
new file mode 100644
index 000000000..8e26b2daa
--- /dev/null
+++ b/src/boost/libs/hana/example/count.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/count.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto ints = hana::tuple_c<int, 1, 2, 3, 2, 2, 4, 2>;
+ BOOST_HANA_CONSTANT_CHECK(hana::count(ints, hana::int_c<2>) == hana::size_c<4>);
+ static_assert(hana::count(ints, 2) == 4, "");
+
+
+ constexpr auto types = hana::tuple_t<int, char, long, short, char, double>;
+ BOOST_HANA_CONSTANT_CHECK(hana::count(types, hana::type_c<char>) == hana::size_c<2>);
+}
diff --git a/src/boost/libs/hana/example/count_if.cpp b/src/boost/libs/hana/example/count_if.cpp
new file mode 100644
index 000000000..da7a42eba
--- /dev/null
+++ b/src/boost/libs/hana/example/count_if.cpp
@@ -0,0 +1,32 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/count_if.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+auto is_odd = [](auto x) {
+ return x % 2_c != 0_c;
+};
+
+int main() {
+ constexpr auto ints = hana::tuple_c<int, 1, 2, 3>;
+ BOOST_HANA_CONSTANT_CHECK(hana::count_if(ints, is_odd) == hana::size_c<2>);
+
+ constexpr auto types = hana::tuple_t<int, char, long, short, char, double>;
+ BOOST_HANA_CONSTANT_CHECK(hana::count_if(types, hana::trait<std::is_floating_point>) == hana::size_c<1>);
+ BOOST_HANA_CONSTANT_CHECK(hana::count_if(types, hana::equal.to(hana::type_c<char>)) == hana::size_c<2>);
+ BOOST_HANA_CONSTANT_CHECK(hana::count_if(types, hana::equal.to(hana::type_c<void>)) == hana::size_c<0>);
+}
diff --git a/src/boost/libs/hana/example/cppcon_2014/comparable.cpp b/src/boost/libs/hana/example/cppcon_2014/comparable.cpp
new file mode 100644
index 000000000..f93151460
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/comparable.cpp
@@ -0,0 +1,55 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+
+#include "matrix/comparable.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ matrix(row(1, 2)),
+ matrix(row(1, 2))
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(
+ matrix(row(1, 2)),
+ matrix(row(1, 5))
+ )));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ matrix(row(1, 2),
+ row(3, 4)),
+ matrix(row(1, 2),
+ row(3, 4))
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(
+ matrix(row(1, 2),
+ row(3, 4)),
+ matrix(row(1, 2),
+ row(0, 4))
+ )));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(
+ matrix(row(1, 2),
+ row(3, 4)),
+ matrix(row(0, 2),
+ row(3, 4))
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ matrix(row(1),
+ row(2)),
+ matrix(row(3, 4),
+ row(5, 6))
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ matrix(row(1),
+ row(2)),
+ matrix(row(3, 4))
+ )));
+}
+
diff --git a/src/boost/libs/hana/example/cppcon_2014/det.cpp b/src/boost/libs/hana/example/cppcon_2014/det.cpp
new file mode 100644
index 000000000..8597e70fc
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/det.cpp
@@ -0,0 +1,48 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+
+#include "matrix/det.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ // det
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(det(matrix(row(1))) == 1);
+ BOOST_HANA_CONSTEXPR_CHECK(det(matrix(row(2))) == 2);
+
+ BOOST_HANA_CONSTEXPR_CHECK(det(matrix(row(1, 2), row(3, 4))) == -2);
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ det(matrix(
+ row(1, 5, 6),
+ row(3, 2, 4),
+ row(7, 8, 9)
+ ))
+ == 51
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ det(matrix(
+ row(1, 5, 6, -3),
+ row(3, 2, 4, -5),
+ row(7, 8, 9, -1),
+ row(8, 2, 1, 10)
+ )) == 214
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ det(matrix(
+ row(1, 5, 6, -3, 92),
+ row(3, 2, 4, -5, 13),
+ row(7, 8, 9, -1, 0),
+ row(8, 2, 1, 10, 41),
+ row(3, 12, 92, -7, -4)
+ )) == -3115014
+ );
+ }
+}
diff --git a/src/boost/libs/hana/example/cppcon_2014/functor.cpp b/src/boost/libs/hana/example/cppcon_2014/functor.cpp
new file mode 100644
index 000000000..b616a5241
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/functor.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include "matrix/comparable.hpp"
+#include "matrix/functor.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ // transform
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto m = matrix(
+ row(1, hana::int_c<2>, 3),
+ row(hana::int_c<4>, 5, 6),
+ row(7, 8, hana::int_c<9>)
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::transform(m, hana::_ + hana::int_c<1>),
+ matrix(
+ row(2, hana::int_c<3>, 4),
+ row(hana::int_c<5>, 6, 7),
+ row(8, 9, hana::int_c<10>)
+ )
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix.cpp b/src/boost/libs/hana/example/cppcon_2014/matrix.cpp
new file mode 100644
index 000000000..0d5d020f1
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix.cpp
@@ -0,0 +1,69 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include "matrix/comparable.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ // transpose
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto m = matrix(
+ row(1, 2.2, '3'),
+ row(4, '5', 6)
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ transpose(m),
+ matrix(
+ row(1, 4),
+ row(2.2, '5'),
+ row('3', 6)
+ )
+ ));
+ }
+
+ // vector
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto v = vector(1, '2', hana::int_c<3>, 4.2f);
+ BOOST_HANA_CONSTEXPR_CHECK(v.size() == 4ul);
+ BOOST_HANA_CONSTEXPR_CHECK(v.nrows() == 4ul);
+ BOOST_HANA_CONSTEXPR_CHECK(v.ncolumns() == 1ul);
+ }
+
+ // matrix.at
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto m = matrix(
+ row(1, '2', 3),
+ row('4', hana::char_c<'5'>, 6),
+ row(hana::int_c<7>, '8', 9.3)
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<0>, hana::int_c<0>) == 1);
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<0>, hana::int_c<1>) == '2');
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<0>, hana::int_c<2>) == 3);
+
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<1>, hana::int_c<0>) == '4');
+ BOOST_HANA_CONSTANT_CHECK(m.at(hana::int_c<1>, hana::int_c<1>) == hana::char_c<'5'>);
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<1>, hana::int_c<2>) == 6);
+
+ BOOST_HANA_CONSTANT_CHECK(m.at(hana::int_c<2>, hana::int_c<0>) == hana::int_c<7>);
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<2>, hana::int_c<1>) == '8');
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<2>, hana::int_c<2>) == 9.3);
+ }
+
+ // size, ncolumns, nrows
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto m = matrix(
+ row(1, '2', 3),
+ row('4', hana::char_c<'5'>, 6)
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(m.size() == 6ul);
+ BOOST_HANA_CONSTEXPR_CHECK(m.ncolumns() == 3ul);
+ BOOST_HANA_CONSTEXPR_CHECK(m.nrows() == 2ul);
+ }
+}
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/comparable.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/comparable.hpp
new file mode 100644
index 000000000..d84b0dac8
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/comparable.hpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_COMPARABLE_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_COMPARABLE_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/all.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/zip_with.hpp>
+
+
+namespace boost { namespace hana {
+ template <unsigned R1, unsigned C1, unsigned R2, unsigned C2>
+ struct equal_impl<cppcon::Matrix<R1, C1>, cppcon::Matrix<R2, C2>> {
+ template <typename M1, typename M2>
+ static constexpr auto apply(M1 const& m1, M2 const& m2) {
+ return eval_if(bool_c<R1 == R2 && C1 == C2>,
+ [&](auto _) {
+ return all(zip_with(_(equal), cppcon::rows(m1),
+ cppcon::rows(m2)));
+ },
+ [] { return false_c; }
+ );
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_COMPARABLE_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/det.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/det.hpp
new file mode 100644
index 000000000..f499fda7e
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/det.hpp
@@ -0,0 +1,60 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/functional/fix.hpp>
+#include <boost/hana/functional/flip.hpp>
+#include <boost/hana/functional/on.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/power.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/remove_at.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <utility>
+
+#include "matrix.hpp"
+
+
+namespace cppcon {
+ namespace hana = boost::hana;
+ auto det = hana::fix([](auto det, auto&& m) -> decltype(auto) {
+ auto matrix_minor = [=](auto&& m, auto i, auto j) -> decltype(auto) {
+ return det(hana::unpack(
+ hana::transform(
+ hana::remove_at(rows(std::forward<decltype(m)>(m)), i),
+ hana::partial(hana::flip(hana::remove_at), j)
+ ),
+ matrix
+ ));
+ };
+
+ auto cofactor = [=](auto&& m, auto i, auto j) {
+ return hana::power(hana::int_c<-1>, hana::plus(i, j)) *
+ matrix_minor(std::forward<decltype(m)>(m), i, j);
+ };
+
+ return hana::eval_if(m.size() == hana::size_c<1>,
+ hana::always(m.at(hana::size_c<0>, hana::size_c<0>)),
+ [=](auto _) {
+ auto cofactors_1st_row = hana::unpack(_(hana::make_range)(hana::size_c<0>, m.ncolumns()),
+ hana::on(hana::make_tuple, hana::partial(cofactor, m, hana::size_c<0>))
+ );
+ return detail::tuple_scalar_product(hana::front(rows(m)), cofactors_1st_row);
+ }
+ );
+ });
+} // end namespace cppcon
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/functor.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/functor.hpp
new file mode 100644
index 000000000..5bb3cd85d
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/functor.hpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_FUNCTOR_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_FUNCTOR_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/functional/flip.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/concept/functor.hpp>
+
+#include <utility>
+
+
+namespace boost { namespace hana {
+ template <unsigned Rows, unsigned Columns>
+ struct transform_impl<cppcon::Matrix<Rows, Columns>> {
+ template <typename M, typename F>
+ static constexpr decltype(auto) apply(M&& m, F&& f) {
+ return unpack(
+ transform(
+ cppcon::rows(std::forward<M>(m)),
+ partial(flip(transform), std::forward<F>(f))
+ ),
+ cppcon::matrix
+ );
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_FUNCTOR_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/group.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/group.hpp
new file mode 100644
index 000000000..87c90b7a7
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/group.hpp
@@ -0,0 +1,28 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_GROUP_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_GROUP_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/concept/group.hpp>
+
+#include <utility>
+
+
+namespace boost { namespace hana {
+ template <unsigned R, unsigned C>
+ struct minus_impl<cppcon::Matrix<R, C>, cppcon::Matrix<R, C>> {
+ template <typename M1, typename M2>
+ static constexpr decltype(auto) apply(M1&& m1, M2&& m2) {
+ return element_wise(minus)(
+ std::forward<M1>(m1),
+ std::forward<M2>(m2)
+ );
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_GROUP_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/matrix.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/matrix.hpp
new file mode 100644
index 000000000..d7e142460
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/matrix.hpp
@@ -0,0 +1,110 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/functional/on.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/fuse.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/sum.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+#include <boost/hana/value.hpp>
+#include <boost/hana/zip.hpp>
+#include <boost/hana/zip_with.hpp>
+
+#include <utility>
+
+
+namespace cppcon {
+ template <unsigned Rows, unsigned Columns>
+ struct Matrix { };
+
+ template <unsigned Rows, unsigned Columns, typename Storage>
+ struct matrix_type {
+ using hana_tag = Matrix<Rows, Columns>;
+
+ Storage rows_;
+ constexpr auto ncolumns() const
+ { return boost::hana::length(boost::hana::front(rows_)); }
+
+ constexpr auto nrows() const
+ { return boost::hana::length(rows_); }
+
+ constexpr auto size() const
+ { return nrows() * ncolumns(); }
+
+ template <typename I, typename J>
+ constexpr decltype(auto) at(I i, J j) const
+ { return boost::hana::at(boost::hana::at(rows_, i), j); }
+ };
+
+ auto row = boost::hana::make_tuple;
+
+ auto matrix = [](auto&& ...rows) -> decltype(auto) {
+ namespace hana = boost::hana;
+ auto storage = hana::make_tuple(std::forward<decltype(rows)>(rows)...);
+ auto ncolumns = hana::length(hana::front(storage));
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::all_of(hana::drop_front(storage), [&](auto const& row) {
+ return hana::length(row) == ncolumns;
+ })
+ );
+
+ return matrix_type<
+ sizeof...(rows), hana::value(ncolumns), decltype(storage)
+ >{std::move(storage)};
+ };
+
+ auto vector = boost::hana::on(matrix, row);
+
+
+ // More operations
+ auto rows = [](auto&& m) -> decltype(auto) {
+ return std::forward<decltype(m)>(m).rows_;
+ };
+
+ auto transpose = [](auto&& m) -> decltype(auto) {
+ return boost::hana::unpack(
+ boost::hana::fuse(boost::hana::zip)(rows(std::forward<decltype(m)>(m))),
+ matrix
+ );
+ };
+
+ auto columns = [](auto&& m) -> decltype(auto) {
+ return rows(transpose(std::forward<decltype(m)>(m)));
+ };
+
+ auto element_wise = [](auto&& f) -> decltype(auto) {
+ namespace hana = boost::hana;
+ return [f(std::forward<decltype(f)>(f))](auto&& ...m) -> decltype(auto) {
+ return hana::unpack(
+ hana::zip_with(hana::partial(hana::zip_with, f),
+ rows(std::forward<decltype(m)>(m))...
+ ),
+ matrix
+ );
+ };
+ };
+
+ namespace detail {
+ auto tuple_scalar_product = [](auto&& u, auto&& v) -> decltype(auto) {
+ namespace hana = boost::hana;
+ return hana::sum<>(hana::zip_with(hana::mult,
+ std::forward<decltype(u)>(u),
+ std::forward<decltype(v)>(v)
+ ));
+ };
+ }
+} // end namespace cppcon
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/monoid.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/monoid.hpp
new file mode 100644
index 000000000..87d62817c
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/monoid.hpp
@@ -0,0 +1,37 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MONOID_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MONOID_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/concept/monoid.hpp>
+#include <boost/hana/range.hpp>
+
+
+namespace boost { namespace hana {
+ template <unsigned R, unsigned C>
+ struct plus_impl<cppcon::Matrix<R, C>, cppcon::Matrix<R, C>> {
+ template <typename M1, typename M2>
+ static constexpr decltype(auto) apply(M1&& m1, M2&& m2) {
+ return element_wise(plus)(
+ std::forward<M1>(m1),
+ std::forward<M2>(m2)
+ );
+ }
+ };
+
+ template <unsigned R, unsigned C>
+ struct zero_impl<cppcon::Matrix<R, C>> {
+ static constexpr decltype(auto) apply() {
+ auto zeros = replicate(int_<0>, int_<C>);
+ return unpack(replicate(zeros, int_<R>), cppcon::matrix);
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MONOID_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/ring.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/ring.hpp
new file mode 100644
index 000000000..748f4f8a3
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/ring.hpp
@@ -0,0 +1,62 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_RING_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_RING_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fwd/mult.hpp>
+#include <boost/hana/fwd/one.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/replicate.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+#include <boost/hana/zip_with.hpp>
+
+#include <utility>
+
+
+namespace boost { namespace hana {
+ template <unsigned R1, unsigned C1, unsigned R2, unsigned C2>
+ struct mult_impl<cppcon::Matrix<R1, C1>, cppcon::Matrix<R2, C2>> {
+ template <typename M1, typename M2>
+ static constexpr decltype(auto) apply(M1&& m1, M2&& m2) {
+ static_assert(C1 == R2,
+ "wrong dimensions for matrix multiplication");
+ auto cols = cppcon::columns(std::forward<M2>(m2));
+ return unpack(
+ transform(cppcon::rows(std::forward<M1>(m1)),
+ [&](auto&& row) -> decltype(auto) {
+ return zip_with(cppcon::detail::tuple_scalar_product,
+ replicate<tuple_tag>(std::forward<decltype(row)>(row), uint_c<R1>),
+ cols
+ );
+ }
+ ),
+ cppcon::matrix
+ );
+ }
+ };
+
+ template <unsigned R, unsigned C>
+ struct one_impl<cppcon::Matrix<R, C>> {
+ static constexpr decltype(auto) apply() {
+ return unpack(range_c<unsigned, 0, R>, [](auto ...n) {
+ return unpack(range_c<unsigned, 0, C>, [=](auto ...m) {
+ auto row = [=](auto n) {
+ return cppcon::row(if_(n == m, int_c<1>, int_c<0>)...);
+ };
+ return cppcon::matrix(row(n)...);
+ });
+ });
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_RING_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/ring.cpp b/src/boost/libs/hana/example/cppcon_2014/ring.cpp
new file mode 100644
index 000000000..9d06400de
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/ring.cpp
@@ -0,0 +1,96 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/one.hpp>
+
+#include "matrix/comparable.hpp"
+#include "matrix/ring.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ // mult
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto a = matrix(
+ row(1, 2, 3),
+ row(4, 5, 6)
+ );
+
+ BOOST_HANA_CONSTEXPR_LAMBDA auto b = matrix(
+ row(1, 2),
+ row(3, 4),
+ row(5, 6)
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::mult(a, b),
+ matrix(
+ row(1*1 + 2*3 + 5*3, 1*2 + 2*4 + 3*6),
+ row(4*1 + 3*5 + 5*6, 4*2 + 5*4 + 6*6)
+ )
+ ));
+ }
+
+ // one
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<1, 1>>(),
+ matrix(
+ row(1)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<2, 2>>(),
+ matrix(
+ row(1, 0),
+ row(0, 1)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<3, 3>>(),
+ matrix(
+ row(1, 0, 0),
+ row(0, 1, 0),
+ row(0, 0, 1)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<4, 4>>(),
+ matrix(
+ row(1, 0, 0, 0),
+ row(0, 1, 0, 0),
+ row(0, 0, 1, 0),
+ row(0, 0, 0, 1)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<4, 5>>(),
+ matrix(
+ row(1, 0, 0, 0, 0),
+ row(0, 1, 0, 0, 0),
+ row(0, 0, 1, 0, 0),
+ row(0, 0, 0, 1, 0)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<5, 4>>(),
+ matrix(
+ row(1, 0, 0, 0),
+ row(0, 1, 0, 0),
+ row(0, 0, 1, 0),
+ row(0, 0, 0, 1),
+ row(0, 0, 0, 0)
+ )
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/example/cycle.cpp b/src/boost/libs/hana/example/cycle.cpp
new file mode 100644
index 000000000..e86eba499
--- /dev/null
+++ b/src/boost/libs/hana/example/cycle.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/cycle.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::cycle(hana::make_tuple('x', 'y'), hana::size_c<2>) == hana::make_tuple('x', 'y', 'x', 'y'), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/define_struct.cpp b/src/boost/libs/hana/example/define_struct.cpp
new file mode 100644
index 000000000..578e9b15e
--- /dev/null
+++ b/src/boost/libs/hana/example/define_struct.cpp
@@ -0,0 +1,55 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/accessors.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (int, age)
+ );
+};
+
+// The member names are hana::strings:
+auto names = hana::transform(hana::accessors<Person>(), hana::first);
+BOOST_HANA_CONSTANT_CHECK(
+ names == hana::make_tuple(BOOST_HANA_STRING("name"), BOOST_HANA_STRING("age"))
+);
+
+int main() {
+ Person john{"John", 30}, bob{"Bob", 40};
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(john, john));
+ BOOST_HANA_RUNTIME_CHECK(hana::not_equal(john, bob));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("name")) == hana::just("John"));
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("age")) == hana::just(30));
+ BOOST_HANA_CONSTANT_CHECK(hana::find(john, BOOST_HANA_STRING("foo")) == hana::nothing);
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to_tuple(john) == hana::make_tuple(
+ hana::make_pair(BOOST_HANA_STRING("name"), "John"),
+ hana::make_pair(BOOST_HANA_STRING("age"), 30)
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to_map(john) == hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("name"), "John"),
+ hana::make_pair(BOOST_HANA_STRING("age"), 30)
+ ));
+}
diff --git a/src/boost/libs/hana/example/detail/wrong.cpp b/src/boost/libs/hana/example/detail/wrong.cpp
new file mode 100644
index 000000000..2b603c623
--- /dev/null
+++ b/src/boost/libs/hana/example/detail/wrong.cpp
@@ -0,0 +1,24 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/detail/wrong.hpp>
+namespace hana = boost::hana;
+
+
+template <typename T, typename U>
+struct base_template {
+ // Can't write this because the assertion would always fire up:
+ // static_assert(false, "...");
+
+ // So instead we write this:
+ static_assert(hana::detail::wrong<base_template<T, U>>::value,
+ "base_template does not have a valid default definition");
+};
+
+template <>
+struct base_template<int, int> {
+ // something useful
+};
+
+int main() { }
diff --git a/src/boost/libs/hana/example/div.cpp b/src/boost/libs/hana/example/div.cpp
new file mode 100644
index 000000000..5c909e1d2
--- /dev/null
+++ b/src/boost/libs/hana/example/div.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/div.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::div(hana::int_c<6>, hana::int_c<3>) == hana::int_c<2>);
+BOOST_HANA_CONSTANT_CHECK(hana::div(hana::int_c<6>, hana::int_c<4>) == hana::int_c<1>);
+
+static_assert(hana::div(6, 3) == 2, "");
+static_assert(hana::div(6, 4) == 1, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/drop_back.cpp b/src/boost/libs/hana/example/drop_back.cpp
new file mode 100644
index 000000000..8083c2ee0
--- /dev/null
+++ b/src/boost/libs/hana/example/drop_back.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_back.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.0);
+
+static_assert(hana::drop_back(xs, hana::size_c<0>) == xs, "");
+static_assert(hana::drop_back(xs, hana::size_c<1>) == hana::make_tuple(0, '1'), "");
+static_assert(hana::drop_back(xs, hana::size_c<2>) == hana::make_tuple(0), "");
+BOOST_HANA_CONSTANT_CHECK(hana::drop_back(xs, hana::size_c<3>) == hana::make_tuple());
+BOOST_HANA_CONSTANT_CHECK(hana::drop_back(xs, hana::size_c<4>) == hana::make_tuple());
+
+static_assert(hana::drop_back(xs) == hana::make_tuple(0, '1'), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/drop_front.cpp b/src/boost/libs/hana/example/drop_front.cpp
new file mode 100644
index 000000000..c48388371
--- /dev/null
+++ b/src/boost/libs/hana/example/drop_front.cpp
@@ -0,0 +1,24 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.0);
+
+static_assert(hana::drop_front(xs, hana::size_c<0>) == xs, "");
+static_assert(hana::drop_front(xs, hana::size_c<1>) == hana::make_tuple('1', 2.0), "");
+static_assert(hana::drop_front(xs, hana::size_c<2>) == hana::make_tuple(2.0), "");
+BOOST_HANA_CONSTANT_CHECK(hana::drop_front(xs, hana::size_c<3>) == hana::make_tuple());
+BOOST_HANA_CONSTANT_CHECK(hana::drop_front(xs, hana::size_c<4>) == hana::make_tuple());
+
+// drop_front(xs) is equivalent to drop_front(xs, size_t<1>)
+static_assert(hana::drop_front(xs) == hana::make_tuple('1', 2.0), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/drop_front_exactly.cpp b/src/boost/libs/hana/example/drop_front_exactly.cpp
new file mode 100644
index 000000000..e7e6923cb
--- /dev/null
+++ b/src/boost/libs/hana/example/drop_front_exactly.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.0);
+
+static_assert(hana::drop_front_exactly(xs, hana::size_c<1>) == hana::make_tuple('1', 2.0), "");
+static_assert(hana::drop_front_exactly(xs, hana::size_c<2>) == hana::make_tuple(2.0), "");
+BOOST_HANA_CONSTANT_CHECK(hana::drop_front_exactly(xs, hana::size_c<3>) == hana::make_tuple());
+
+// drop_front_exactly(xs) is equivalent to drop_front_exactly(xs, size_t<1>)
+static_assert(hana::drop_front_exactly(xs) == hana::make_tuple('1', 2.0), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/drop_while.cpp b/src/boost/libs/hana/example/drop_while.cpp
new file mode 100644
index 000000000..0e3cf7e74
--- /dev/null
+++ b/src/boost/libs/hana/example/drop_while.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_while.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/negate.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+auto negative = [](auto x) {
+ return x < hana::int_c<0>;
+};
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::drop_while(hana::make_range(hana::int_c<-3>, hana::int_c<6>), negative)
+ ==
+ hana::make_range(hana::int_c<0>, hana::int_c<6>)
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::drop_while(hana::make_tuple(1_c, -2_c, 4_c, 5_c), negative)
+ ==
+ hana::make_tuple(1_c, -2_c, 4_c, 5_c)
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/duplicate.cpp b/src/boost/libs/hana/example/duplicate.cpp
new file mode 100644
index 000000000..44737cb7c
--- /dev/null
+++ b/src/boost/libs/hana/example/duplicate.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/duplicate.hpp>
+#include <boost/hana/extract.hpp>
+#include <boost/hana/lazy.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto very_lazy = hana::duplicate(hana::make_lazy(3));
+ static_assert(hana::extract(hana::extract(very_lazy)) == 3, "");
+}
diff --git a/src/boost/libs/hana/example/empty.cpp b/src/boost/libs/hana/example/empty.cpp
new file mode 100644
index 000000000..71900cac4
--- /dev/null
+++ b/src/boost/libs/hana/example/empty.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/empty.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::empty<hana::tuple_tag>() == hana::make_tuple());
+BOOST_HANA_CONSTANT_CHECK(hana::empty<hana::optional_tag>() == hana::nothing);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/equal.cpp b/src/boost/libs/hana/example/equal.cpp
new file mode 100644
index 000000000..a917ebadc
--- /dev/null
+++ b/src/boost/libs/hana/example/equal.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ static_assert(hana::equal(hana::make_tuple(1, 2), hana::make_tuple(1, 2)), "");
+ static_assert(!hana::equal('x', 'y'), "");
+ BOOST_HANA_CONSTANT_CHECK(!hana::equal(hana::make_tuple(1, 2), 'y'));
+
+ static_assert(hana::any_of(hana::make_tuple(1, 2, 3), hana::equal.to(2)), "");
+}
diff --git a/src/boost/libs/hana/example/eval.cpp b/src/boost/libs/hana/example/eval.cpp
new file mode 100644
index 000000000..f17bd11ce
--- /dev/null
+++ b/src/boost/libs/hana/example/eval.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/eval.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/lazy.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::eval(hana::make_lazy(hana::_ + 1)(3)) == 4, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/eval_if.cpp b/src/boost/libs/hana/example/eval_if.cpp
new file mode 100644
index 000000000..60aeef42a
--- /dev/null
+++ b/src/boost/libs/hana/example/eval_if.cpp
@@ -0,0 +1,38 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/traits.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+// eval_if with heterogeneous branches and a Constant condition
+BOOST_HANA_CONSTEXPR_LAMBDA auto safe_make_unsigned = [](auto t) {
+ return hana::eval_if(hana::traits::is_integral(t),
+ hana::make_lazy(hana::traits::make_unsigned)(t),
+ hana::make_lazy(t)
+ );
+};
+
+BOOST_HANA_CONSTANT_CHECK(safe_make_unsigned(hana::type_c<void>) == hana::type_c<void>);
+BOOST_HANA_CONSTANT_CHECK(safe_make_unsigned(hana::type_c<int>) == hana::type_c<unsigned int>);
+
+
+// eval_if with homogeneous branches and a constexpr or runtime condition
+BOOST_HANA_CONSTEXPR_LAMBDA auto safe_divide = [](auto x, auto y) {
+ return hana::eval_if(y == 0,
+ [=](auto) { return 0; },
+ [=](auto _) { return _(x) / y; }
+ );
+};
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(safe_divide(6, 3) == 2);
+ BOOST_HANA_CONSTEXPR_CHECK(safe_divide(6, 0) == 0);
+}
diff --git a/src/boost/libs/hana/example/ext/boost/fusion/deque.cpp b/src/boost/libs/hana/example/ext/boost/fusion/deque.cpp
new file mode 100644
index 000000000..965e78472
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/fusion/deque.cpp
@@ -0,0 +1,35 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/fusion/deque.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <boost/fusion/include/deque.hpp>
+#include <boost/fusion/include/make_deque.hpp>
+
+#include <string>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+
+int main() {
+ fusion::deque<Fish, Cat, Dog> animals{{"Nemo"}, {"Garfield"}, {"Snoopy"}};
+ hana::front(animals).name = "Moby Dick";
+
+ auto names = hana::transform(animals, [](auto a) {
+ return a.name;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ names,
+ fusion::make_deque("Moby Dick", "Garfield", "Snoopy")
+ ));
+}
diff --git a/src/boost/libs/hana/example/ext/boost/fusion/list.cpp b/src/boost/libs/hana/example/ext/boost/fusion/list.cpp
new file mode 100644
index 000000000..dbd2cfc7e
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/fusion/list.cpp
@@ -0,0 +1,35 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/fusion/list.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <boost/fusion/include/make_list.hpp>
+#include <boost/fusion/include/list.hpp>
+
+#include <string>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+
+int main() {
+ fusion::list<Fish, Cat, Dog> animals{{"Nemo"}, {"Garfield"}, {"Snoopy"}};
+ hana::front(animals).name = "Moby Dick";
+
+ auto names = hana::transform(animals, [](auto a) {
+ return a.name;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ names,
+ fusion::make_list("Moby Dick", "Garfield", "Snoopy")
+ ));
+}
diff --git a/src/boost/libs/hana/example/ext/boost/fusion/tuple.cpp b/src/boost/libs/hana/example/ext/boost/fusion/tuple.cpp
new file mode 100644
index 000000000..2c4743b06
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/fusion/tuple.cpp
@@ -0,0 +1,35 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/fusion/tuple.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <boost/fusion/include/make_tuple.hpp>
+#include <boost/fusion/include/tuple.hpp>
+
+#include <string>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+
+int main() {
+ fusion::tuple<Fish, Cat, Dog> animals{Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"}};
+ hana::front(animals).name = "Moby Dick";
+
+ auto names = hana::transform(animals, [](auto a) {
+ return a.name;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ names,
+ fusion::make_tuple("Moby Dick", "Garfield", "Snoopy")
+ ));
+}
diff --git a/src/boost/libs/hana/example/ext/boost/fusion/vector.cpp b/src/boost/libs/hana/example/ext/boost/fusion/vector.cpp
new file mode 100644
index 000000000..fd2f115b1
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/fusion/vector.cpp
@@ -0,0 +1,35 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/fusion/vector.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/vector.hpp>
+
+#include <string>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+
+int main() {
+ fusion::vector<Fish, Cat, Dog> animals{Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"}};
+ hana::front(animals).name = "Moby Dick";
+
+ auto names = hana::transform(animals, [](auto a) {
+ return a.name;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ names,
+ fusion::make_vector("Moby Dick", "Garfield", "Snoopy")
+ ));
+}
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/integral_c/integral_constant.cpp b/src/boost/libs/hana/example/ext/boost/mpl/integral_c/integral_constant.cpp
new file mode 100644
index 000000000..e4b781350
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/integral_c/integral_constant.cpp
@@ -0,0 +1,24 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/integral_c.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+#include <boost/mpl/long.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+static_assert(hana::value(mpl::integral_c<int, 3>{}) == 3, "");
+static_assert(mpl::integral_c<int, 3>::value == 3, "");
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(mpl::integral_c<int, 3>{}, mpl::int_<3>{}));
+BOOST_HANA_CONSTANT_CHECK(hana::equal(mpl::integral_c<int, 3>{}, mpl::long_<3>{}));
+BOOST_HANA_CONSTANT_CHECK(hana::not_equal(mpl::integral_c<int, 3>{}, mpl::int_<0>{}));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/list/comparable.cpp b/src/boost/libs/hana/example/ext/boost/mpl/list/comparable.cpp
new file mode 100644
index 000000000..7f2816488
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/list/comparable.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/list.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <boost/mpl/list.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::equal(mpl::list2<int, char>{}, mpl::list<int, char>{})
+);
+BOOST_HANA_CONSTANT_CHECK(
+ hana::not_equal(mpl::list2<int, char>{}, mpl::list<int, char, float>{})
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/list/conversion.cpp b/src/boost/libs/hana/example/ext/boost/mpl/list/conversion.cpp
new file mode 100644
index 000000000..2bed05599
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/list/conversion.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/ext/boost/mpl/list.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/mpl/list.hpp>
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+auto xs = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<double>);
+static_assert(std::is_same<
+ decltype(hana::to<hana::ext::boost::mpl::list_tag>(xs)),
+ mpl::list<int, char, double>
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/list/foldable.cpp b/src/boost/libs/hana/example/ext/boost/mpl/list/foldable.cpp
new file mode 100644
index 000000000..6f21fdc88
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/list/foldable.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/list.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/mpl/list.hpp>
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+auto types = mpl::list<long, float, short, float, long, long double>{};
+auto number_of_floats = hana::fold_left(types, hana::int_c<0>, [](auto count, auto t) {
+ return hana::if_(hana::trait<std::is_floating_point>(t),
+ count + hana::int_c<1>,
+ count
+ );
+});
+
+BOOST_HANA_CONSTANT_CHECK(number_of_floats == hana::int_c<3>);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/list/iterable.cpp b/src/boost/libs/hana/example/ext/boost/mpl/list/iterable.cpp
new file mode 100644
index 000000000..87a803c20
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/list/iterable.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/drop_while.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/list.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/mpl/list.hpp>
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::front(mpl::list<int, char, void>{}) == hana::type_c<int>);
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(mpl::list<int, char, void>{}),
+ mpl::list<char, void>{}
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(mpl::list<float, double const, int, float&>{},
+ hana::trait<std::is_floating_point>),
+ mpl::list<int, float&>{}
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/list/searchable.cpp b/src/boost/libs/hana/example/ext/boost/mpl/list/searchable.cpp
new file mode 100644
index 000000000..4ce0fd775
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/list/searchable.cpp
@@ -0,0 +1,30 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/list.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/mpl/list.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find_if(mpl::list<int, float, char const*>{}, hana::equal.to(hana::type_c<float>))
+ ==
+ hana::just(hana::type_c<float>)
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find(mpl::list<int, float, char const*>{}, hana::type_c<void>)
+ ==
+ hana::nothing
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/vector/comparable.cpp b/src/boost/libs/hana/example/ext/boost/mpl/vector/comparable.cpp
new file mode 100644
index 000000000..c5e936f50
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/vector/comparable.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/vector.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <boost/mpl/vector.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::equal(mpl::vector2<int, char>{}, mpl::vector<int, char>{})
+);
+BOOST_HANA_CONSTANT_CHECK(
+ hana::not_equal(mpl::vector2<int, char>{}, mpl::vector<int, char, float>{})
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/vector/conversion.cpp b/src/boost/libs/hana/example/ext/boost/mpl/vector/conversion.cpp
new file mode 100644
index 000000000..7319f2009
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/vector/conversion.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/ext/boost/mpl/vector.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/mpl/vector.hpp>
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+auto xs = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<double>);
+static_assert(std::is_same<
+ decltype(hana::to<hana::ext::boost::mpl::vector_tag>(xs)),
+ mpl::vector<int, char, double>
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/vector/foldable.cpp b/src/boost/libs/hana/example/ext/boost/mpl/vector/foldable.cpp
new file mode 100644
index 000000000..eb9411a6c
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/vector/foldable.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/vector.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/mpl/vector.hpp>
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+auto types = mpl::vector<long, float, short, float, long, long double>{};
+auto number_of_floats = hana::fold_left(types, hana::int_c<0>, [](auto count, auto t) {
+ return hana::if_(hana::trait<std::is_floating_point>(t),
+ count + hana::int_c<1>,
+ count
+ );
+});
+
+BOOST_HANA_CONSTANT_CHECK(number_of_floats == hana::int_c<3>);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/vector/iterable.cpp b/src/boost/libs/hana/example/ext/boost/mpl/vector/iterable.cpp
new file mode 100644
index 000000000..c6751a3b7
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/vector/iterable.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/drop_while.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/vector.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/mpl/vector.hpp>
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::front(mpl::vector<int, char, void>{}) == hana::type_c<int>);
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(mpl::vector<int, char, void>{}),
+ mpl::vector<char, void>{}
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(mpl::vector<float, double const, int, float&>{},
+ hana::trait<std::is_floating_point>),
+ mpl::vector<int, float&>{}
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/mpl/vector/searchable.cpp b/src/boost/libs/hana/example/ext/boost/mpl/vector/searchable.cpp
new file mode 100644
index 000000000..476949925
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/mpl/vector/searchable.cpp
@@ -0,0 +1,30 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/vector.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/mpl/vector.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find_if(mpl::vector<int, float, char const*>{}, hana::equal.to(hana::type_c<float>))
+ ==
+ hana::just(hana::type_c<float>)
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find(mpl::vector<int, float, char const*>{}, hana::type_c<void>)
+ ==
+ hana::nothing
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/boost/tuple.cpp b/src/boost/libs/hana/example/ext/boost/tuple.cpp
new file mode 100644
index 000000000..319e80834
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/boost/tuple.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/tuple.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <boost/tuple/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+
+int main() {
+ boost::tuple<Fish, Cat, Dog> animals{{"Nemo"}, {"Garfield"}, {"Snoopy"}};
+ hana::front(animals).name = "Moby Dick";
+
+ auto names = hana::transform(animals, [](auto a) {
+ return a.name;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ names,
+ boost::make_tuple("Moby Dick", "Garfield", "Snoopy")
+ ));
+}
diff --git a/src/boost/libs/hana/example/ext/std/array/comparable.cpp b/src/boost/libs/hana/example/ext/std/array/comparable.cpp
new file mode 100644
index 000000000..c1c814877
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/array/comparable.cpp
@@ -0,0 +1,24 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/array.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <array>
+namespace hana = boost::hana;
+
+
+constexpr std::array<int, 4> xs = {{1, 2, 3, 4}};
+constexpr std::array<int, 5> ys = {{1, 2, 3, 4, 5}};
+
+// arrays have different constexpr contents; result is a constexpr bool
+static_assert(hana::equal(xs, xs), "");
+
+// arrays have different lengths; result is an integral_constant
+BOOST_HANA_CONSTANT_CHECK(hana::not_equal(xs, ys));
+
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/array/foldable.cpp b/src/boost/libs/hana/example/ext/std/array/foldable.cpp
new file mode 100644
index 000000000..cff38e1c1
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/array/foldable.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/ext/std/array.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <array>
+namespace hana = boost::hana;
+
+
+int main() {
+ std::array<int, 5> a = {{0, 1, 2, 3, 4}};
+
+ auto b = hana::unpack(a, [](auto ...i) {
+ return std::array<int, sizeof...(i)>{{(i + 10)...}};
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(b == std::array<int, 5>{{10, 11, 12, 13, 14}});
+}
diff --git a/src/boost/libs/hana/example/ext/std/array/iterable.cpp b/src/boost/libs/hana/example/ext/std/array/iterable.cpp
new file mode 100644
index 000000000..d14dbd911
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/array/iterable.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/at.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/array.hpp>
+
+#include <array>
+namespace hana = boost::hana;
+
+
+constexpr std::array<int, 5> a = {{0, 1, 2, 3, 4}};
+
+static_assert(hana::at_c<2>(a) == 2, "");
+
+static_assert(hana::equal(hana::drop_front(a), std::array<int, 4>{{1, 2, 3, 4}}), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/array/orderable.cpp b/src/boost/libs/hana/example/ext/std/array/orderable.cpp
new file mode 100644
index 000000000..7f4c9f2b7
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/array/orderable.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/ext/std/array.hpp>
+#include <boost/hana/less.hpp>
+
+#include <array>
+namespace hana = boost::hana;
+
+
+constexpr std::array<int, 4> evens = {{2, 4, 6, 8}};
+constexpr std::array<int, 4> odds = {{1, 3, 5, 7}};
+
+constexpr std::array<int, 5> up_to_5 = {{1, 2, 3, 4, 5}};
+
+// arrays with same length
+static_assert(hana::less(odds, evens), "");
+
+// arrays with different lengths
+static_assert(hana::less(up_to_5, odds), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/integer_sequence/comparable.cpp b/src/boost/libs/hana/example/ext/std/integer_sequence/comparable.cpp
new file mode 100644
index 000000000..10b62752a
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/integer_sequence/comparable.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+constexpr std::integer_sequence<int, 1, 2, 3, 4> xs{};
+constexpr std::integer_sequence<long, 1, 2, 3, 4> ys{};
+constexpr std::integer_sequence<long, 1, 2, 3, 4, 5> zs{};
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(xs, ys));
+BOOST_HANA_CONSTANT_CHECK(hana::not_equal(xs, zs));
+BOOST_HANA_CONSTANT_CHECK(hana::not_equal(ys, zs));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/integer_sequence/foldable.cpp b/src/boost/libs/hana/example/ext/std/integer_sequence/foldable.cpp
new file mode 100644
index 000000000..4d7c3253f
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/integer_sequence/foldable.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <tuple>
+#include <utility>
+namespace hana = boost::hana;
+
+
+auto add = [](auto a, auto b, auto c) { return a + b + c; };
+
+int main() {
+ std::tuple<int, long, double> tuple{1, 2l, 3.3};
+
+ auto sum = hana::unpack(std::integer_sequence<int, 0, 1, 2>{}, [&](auto ...i) {
+ // the `i`s are `std::integral_constant<int, ...>`s
+ return add(std::get<decltype(i)::value>(tuple)...);
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(sum == 6.3);
+}
diff --git a/src/boost/libs/hana/example/ext/std/integer_sequence/iterable.cpp b/src/boost/libs/hana/example/ext/std/integer_sequence/iterable.cpp
new file mode 100644
index 000000000..ef421ec37
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/integer_sequence/iterable.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+constexpr std::integer_sequence<int, 0, 1, 2, 3, 4> indices{};
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<2>(indices),
+ std::integral_constant<int, 2>{}
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/integer_sequence/searchable.cpp b/src/boost/libs/hana/example/ext/std/integer_sequence/searchable.cpp
new file mode 100644
index 000000000..c0a159bc8
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/integer_sequence/searchable.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+constexpr std::integer_sequence<int, 1, 2, 3, 4> xs{};
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(xs, hana::int_c<3>),
+ hana::just(std::integral_constant<int, 3>{})
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/integral_constant.cpp b/src/boost/libs/hana/example/ext/std/integral_constant.cpp
new file mode 100644
index 000000000..04e234f1a
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/integral_constant.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+static_assert(hana::value(std::integral_constant<int, 3>{}) == 3, "");
+static_assert(std::integral_constant<int, 3>::value == 3, "");
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(std::integral_constant<int, 3>{}, hana::int_c<3>));
+BOOST_HANA_CONSTANT_CHECK(hana::equal(std::integral_constant<int, 3>{}, hana::long_c<3>));
+BOOST_HANA_CONSTANT_CHECK(hana::not_equal(std::integral_constant<int, 3>{}, hana::int_c<0>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/pair.cpp b/src/boost/libs/hana/example/ext/std/pair.cpp
new file mode 100644
index 000000000..d118b18f8
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/pair.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/ext/std/pair.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto pair = std::make_pair(1, 'x');
+
+static_assert(hana::first(pair) == 1, "");
+static_assert(hana::second(pair) == 'x', "");
+
+static_assert(hana::not_equal(pair, std::make_pair(3, 'z')), "");
+static_assert(hana::less(pair, std::make_pair(3, 'x')), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/ratio/arithmetic.cpp b/src/boost/libs/hana/example/ext/std/ratio/arithmetic.cpp
new file mode 100644
index 000000000..7bcdbbd3f
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/ratio/arithmetic.cpp
@@ -0,0 +1,57 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/div.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/ratio.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/one.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/zero.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::plus(std::ratio<5, 3>{}, std::ratio<3, 12>{}),
+ std::ratio<23, 12>{}
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::minus(std::ratio<5, 3>{}, std::ratio<3, 13>{}),
+ std::ratio<56, 39>{}
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::mult(std::ratio<5, 3>{}, std::ratio<3, 13>{}),
+ std::ratio<15, 39>{}
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::div(std::ratio<5, 3>{}, std::ratio<3, 13>{}),
+ std::ratio<65, 9>{}
+));
+
+// The mod of two ratios is always 0, because they can always be
+// divided without remainder.
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::mod(std::ratio<5, 3>{}, std::ratio<3, 13>{}),
+ std::ratio<0>{}
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zero<hana::ext::std::ratio_tag>(),
+ std::ratio<0>{}
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::one<hana::ext::std::ratio_tag>(),
+ std::ratio<1>{}
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/ratio/comparable.cpp b/src/boost/libs/hana/example/ext/std/ratio/comparable.cpp
new file mode 100644
index 000000000..05d64de32
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/ratio/comparable.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/ratio.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(std::ratio<3, 4>{}, std::ratio<15, 20>{}));
+BOOST_HANA_CONSTANT_CHECK(hana::not_equal(std::ratio<3, 4>{}, std::ratio<3, 5>{}));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/ratio/orderable.cpp b/src/boost/libs/hana/example/ext/std/ratio/orderable.cpp
new file mode 100644
index 000000000..7764bb12a
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/ratio/orderable.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/ext/std/ratio.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/less_equal.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::less(std::ratio<3, 12>{}, std::ratio<5, 12>{}));
+BOOST_HANA_CONSTANT_CHECK(hana::less_equal(std::ratio<6, 12>{}, std::ratio<4, 8>{}));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ext/std/tuple.cpp b/src/boost/libs/hana/example/ext/std/tuple.cpp
new file mode 100644
index 000000000..d545d6fb4
--- /dev/null
+++ b/src/boost/libs/hana/example/ext/std/tuple.cpp
@@ -0,0 +1,32 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <string>
+#include <tuple>
+namespace hana = boost::hana;
+
+
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+
+int main() {
+ std::tuple<Fish, Cat, Dog> animals{{"Nemo"}, {"Garfield"}, {"Snoopy"}};
+ hana::front(animals).name = "Moby Dick";
+
+ auto names = hana::transform(animals, [](auto a) {
+ return a.name;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ names,
+ std::make_tuple("Moby Dick", "Garfield", "Snoopy")
+ ));
+}
diff --git a/src/boost/libs/hana/example/extend.cpp b/src/boost/libs/hana/example/extend.cpp
new file mode 100644
index 000000000..9d5351b19
--- /dev/null
+++ b/src/boost/libs/hana/example/extend.cpp
@@ -0,0 +1,35 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/eval.hpp>
+#include <boost/hana/extend.hpp>
+#include <boost/hana/extract.hpp>
+#include <boost/hana/lazy.hpp>
+
+#include <functional>
+#include <istream>
+#include <sstream>
+namespace hana = boost::hana;
+
+
+template <typename T>
+T read_one(std::istream& s) {
+ T value;
+ s >> value;
+ return value;
+}
+
+int main() {
+ std::stringstream s;
+ s << "1 2 3";
+
+ auto from_stream = hana::extend(hana::make_lazy(read_one<int>)(std::ref(s)), [](auto i) {
+ return hana::eval(i) + 1;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(hana::extract(from_stream) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::extract(from_stream) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::extract(from_stream) == 4);
+}
diff --git a/src/boost/libs/hana/example/extract.cpp b/src/boost/libs/hana/example/extract.cpp
new file mode 100644
index 000000000..1334a831f
--- /dev/null
+++ b/src/boost/libs/hana/example/extract.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/extract.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/lazy.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::extract(hana::make_lazy(1)) == 1, "");
+static_assert(hana::extract(hana::make_lazy(hana::_ + 1)(3)) == 4, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/fill.cpp b/src/boost/libs/hana/example/fill.cpp
new file mode 100644
index 000000000..d18a82149
--- /dev/null
+++ b/src/boost/libs/hana/example/fill.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fill.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ static_assert(
+ hana::fill(hana::make_tuple(1, '2', 3.3, nullptr), 'x')
+ ==
+ hana::make_tuple('x', 'x', 'x', 'x')
+ , "");
+
+ BOOST_HANA_CONSTANT_CHECK(hana::fill(hana::nothing, 'x') == hana::nothing);
+ static_assert(hana::fill(hana::just('y'), 'x') == hana::just('x'), "");
+}
diff --git a/src/boost/libs/hana/example/filter.cpp b/src/boost/libs/hana/example/filter.cpp
new file mode 100644
index 000000000..af7fbba35
--- /dev/null
+++ b/src/boost/libs/hana/example/filter.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/filter.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// First take the type of an object, and then tell whether it's integral
+constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::typeid_);
+
+static_assert(hana::filter(hana::make_tuple(1, 2.0, 3, 4.0), is_integral) == hana::make_tuple(1, 3), "");
+static_assert(hana::filter(hana::just(3), is_integral) == hana::just(3), "");
+BOOST_HANA_CONSTANT_CHECK(hana::filter(hana::just(3.0), is_integral) == hana::nothing);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/find.cpp b/src/boost/libs/hana/example/find.cpp
new file mode 100644
index 000000000..cd75bc974
--- /dev/null
+++ b/src/boost/libs/hana/example/find.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find(hana::make_tuple(hana::int_c<1>, hana::type_c<int>, '3'), hana::type_c<int>) == hana::just(hana::type_c<int>)
+);
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find(hana::make_tuple(hana::int_c<1>, hana::type_c<int>, '3'), hana::type_c<void>) == hana::nothing
+);
+
+constexpr auto m = hana::make_map(
+ hana::make_pair(hana::int_c<2>, 2),
+ hana::make_pair(hana::type_c<float>, 3.3),
+ hana::make_pair(hana::type_c<char>, hana::type_c<int>)
+);
+static_assert(hana::find(m, hana::type_c<float>) == hana::just(3.3), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/find_if.cpp b/src/boost/libs/hana/example/find_if.cpp
new file mode 100644
index 000000000..73264683a
--- /dev/null
+++ b/src/boost/libs/hana/example/find_if.cpp
@@ -0,0 +1,39 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// First get the type of the object, and then call the trait on it.
+constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::typeid_);
+constexpr auto is_class = hana::compose(hana::trait<std::is_class>, hana::typeid_);
+
+static_assert(
+ hana::find_if(hana::make_tuple(1.0, 2, '3'), is_integral) == hana::just(2)
+, "");
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find_if(hana::make_tuple(1.0, 2, '3'), is_class) == hana::nothing
+);
+
+constexpr auto types = hana::tuple_t<char, int, unsigned, long, unsigned long>;
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find_if(types, hana::equal.to(hana::type_c<unsigned>)) == hana::just(hana::type_c<unsigned>)
+);
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find_if(types, hana::equal.to(hana::type_c<void>)) == hana::nothing
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/first.cpp b/src/boost/libs/hana/example/first.cpp
new file mode 100644
index 000000000..c48a9b65e
--- /dev/null
+++ b/src/boost/libs/hana/example/first.cpp
@@ -0,0 +1,12 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::first(hana::make_pair(1, 'x')) == 1, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/flatten.cpp b/src/boost/libs/hana/example/flatten.cpp
new file mode 100644
index 000000000..61c3d272c
--- /dev/null
+++ b/src/boost/libs/hana/example/flatten.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/flatten.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(
+ hana::flatten(hana::make_tuple(hana::make_tuple(1, 2, 3),
+ hana::make_tuple(4, 5),
+ hana::make_tuple(6, 7, 8, 9)))
+ ==
+ hana::make_tuple(1, 2, 3, 4, 5, 6, 7, 8, 9)
+, "");
+
+BOOST_HANA_CONSTANT_CHECK(hana::flatten(hana::nothing) == hana::nothing);
+static_assert(hana::flatten(hana::just(hana::just(1))) == hana::just(1), "");
+BOOST_HANA_CONSTANT_CHECK(hana::flatten(hana::just(hana::nothing)) == hana::nothing);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/fold.cpp b/src/boost/libs/hana/example/fold.cpp
new file mode 100644
index 000000000..a351be580
--- /dev/null
+++ b/src/boost/libs/hana/example/fold.cpp
@@ -0,0 +1,38 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/fold.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+#include <string>
+namespace hana = boost::hana;
+
+
+auto to_string = [](auto x) {
+ std::ostringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+int main() {
+ auto f = [=](std::string s, auto element) {
+ return "f(" + s + ", " + to_string(element) + ")";
+ };
+
+ // with an initial state
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::fold(hana::make_tuple(2, '3', 4, 5.0), "1", f)
+ ==
+ "f(f(f(f(1, 2), 3), 4), 5)"
+ );
+
+ // without initial state
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::fold(hana::make_tuple("1", 2, '3', 4, 5.0), f)
+ ==
+ "f(f(f(f(1, 2), 3), 4), 5)"
+ );
+}
diff --git a/src/boost/libs/hana/example/fold_left.cpp b/src/boost/libs/hana/example/fold_left.cpp
new file mode 100644
index 000000000..4480c3f68
--- /dev/null
+++ b/src/boost/libs/hana/example/fold_left.cpp
@@ -0,0 +1,38 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+#include <string>
+namespace hana = boost::hana;
+
+
+auto to_string = [](auto x) {
+ std::ostringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+int main() {
+ auto f = [=](std::string s, auto element) {
+ return "f(" + s + ", " + to_string(element) + ")";
+ };
+
+ // with an initial state
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::fold_left(hana::make_tuple(2, '3', 4, 5.0), "1", f)
+ ==
+ "f(f(f(f(1, 2), 3), 4), 5)"
+ );
+
+ // without initial state
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::fold_left(hana::make_tuple("1", 2, '3', 4, 5.0), f)
+ ==
+ "f(f(f(f(1, 2), 3), 4), 5)"
+ );
+}
diff --git a/src/boost/libs/hana/example/fold_right.cpp b/src/boost/libs/hana/example/fold_right.cpp
new file mode 100644
index 000000000..5a9e675dd
--- /dev/null
+++ b/src/boost/libs/hana/example/fold_right.cpp
@@ -0,0 +1,38 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+#include <string>
+namespace hana = boost::hana;
+
+
+auto to_string = [](auto x) {
+ std::ostringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+int main() {
+ auto f = [=](auto element, std::string s) {
+ return "f(" + to_string(element) + ", " + s + ")";
+ };
+
+ // with an initial state
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::fold_right(hana::make_tuple(1, '2', 3.0, 4), "5", f)
+ ==
+ "f(1, f(2, f(3, f(4, 5))))"
+ );
+
+ // without initial state
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::fold_right(hana::make_tuple(1, '2', 3.0, 4, "5"), f)
+ ==
+ "f(1, f(2, f(3, f(4, 5))))"
+ );
+}
diff --git a/src/boost/libs/hana/example/foldable/to.cpp b/src/boost/libs/hana/example/foldable/to.cpp
new file mode 100644
index 000000000..ec6a24a5e
--- /dev/null
+++ b/src/boost/libs/hana/example/foldable/to.cpp
@@ -0,0 +1,24 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ static_assert(hana::to<hana::tuple_tag>(hana::just(1)) == hana::make_tuple(1), "");
+ BOOST_HANA_CONSTANT_CHECK(hana::to<hana::tuple_tag>(hana::nothing) == hana::make_tuple());
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::to<hana::tuple_tag>(hana::make_range(hana::int_c<3>, hana::int_c<6>))
+ ==
+ hana::tuple_c<int, 3, 4, 5>
+ );
+}
diff --git a/src/boost/libs/hana/example/for_each.cpp b/src/boost/libs/hana/example/for_each.cpp
new file mode 100644
index 000000000..e58ad9204
--- /dev/null
+++ b/src/boost/libs/hana/example/for_each.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+namespace hana = boost::hana;
+
+
+int main() {
+ std::stringstream ss;
+ hana::for_each(hana::make_tuple(0, '1', "234", 5.5), [&](auto x) {
+ ss << x << ' ';
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "0 1 234 5.5 ");
+}
diff --git a/src/boost/libs/hana/example/front.cpp b/src/boost/libs/hana/example/front.cpp
new file mode 100644
index 000000000..74278545e
--- /dev/null
+++ b/src/boost/libs/hana/example/front.cpp
@@ -0,0 +1,12 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/front.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::front(hana::make_tuple(1, '2', 3.3, nullptr)) == 1, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/always.cpp b/src/boost/libs/hana/example/functional/always.cpp
new file mode 100644
index 000000000..5c4594421
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/always.cpp
@@ -0,0 +1,12 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/functional/always.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::always(1)() == 1, "");
+static_assert(hana::always('2')(1, 2, 3) == '2', "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/apply.cpp b/src/boost/libs/hana/example/functional/apply.cpp
new file mode 100644
index 000000000..a5686a9c6
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/apply.cpp
@@ -0,0 +1,12 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/functional/apply.hpp>
+#include <boost/hana/plus.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::apply(hana::plus, 1, 2) == 3, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/arg.cpp b/src/boost/libs/hana/example/functional/arg.cpp
new file mode 100644
index 000000000..53030a668
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/arg.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/functional/arg.hpp>
+namespace hana = boost::hana;
+
+
+// hana::arg<0>(1, '2', 3.3); // static assertion (regardless of the number of arguments)
+static_assert(hana::arg<1>(1, '2', 3.3) == 1, "");
+static_assert(hana::arg<2>(1, '2', 3.3) == '2', "");
+static_assert(hana::arg<3>(1, '2', 3.3) == 3.3, "");
+// hana::arg<4>(1, '2', 3.3); // static assertion
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/capture.cpp b/src/boost/libs/hana/example/functional/capture.cpp
new file mode 100644
index 000000000..588c9b3f7
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/capture.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/functional/capture.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto sum = [](auto x, auto y, auto z) {
+ return x + y + z;
+ };
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::capture(1, 2, 3)(sum)() == 6);
+ BOOST_HANA_CONSTEXPR_CHECK(hana::capture(1, 2)(sum)(3) == 6);
+}
diff --git a/src/boost/libs/hana/example/functional/compose.cpp b/src/boost/libs/hana/example/functional/compose.cpp
new file mode 100644
index 000000000..a1e026df3
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/compose.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/functional/compose.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto to_char = [](int x) {
+ return static_cast<char>(x + 48);
+ };
+
+ BOOST_HANA_CONSTEXPR_LAMBDA auto increment = [](auto x) {
+ return x + 1;
+ };
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::compose(to_char, increment)(3) == '4');
+}
diff --git a/src/boost/libs/hana/example/functional/curry.cpp b/src/boost/libs/hana/example/functional/curry.cpp
new file mode 100644
index 000000000..6e24b039b
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/curry.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/functional/curry.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto add = [](auto x, auto y, auto z) {
+ return x + y + z;
+ };
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::curry<3>(add)(1)(2)(3) == 1 + 2 + 3);
+ BOOST_HANA_CONSTEXPR_CHECK(hana::curry<3>(add)(1)(2, 3) == hana::curry<3>(add)(1)(2)(3));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::curry<3>(add)(1, 2, 3) == hana::curry<3>(add)(1)(2)(3));
+
+ // curry with a nullary function
+ BOOST_HANA_CONSTEXPR_LAMBDA auto two = []() {
+ return 2;
+ };
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::curry<0>(two)() == two());
+}
diff --git a/src/boost/libs/hana/example/functional/demux.cpp b/src/boost/libs/hana/example/functional/demux.cpp
new file mode 100644
index 000000000..8dfd69eba
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/demux.cpp
@@ -0,0 +1,30 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/demux.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+using hana::_;
+
+
+constexpr auto f = hana::demux(hana::make_tuple)(
+ _ + _,
+ _ - _,
+ _ * _,
+ _ / _
+);
+
+static_assert(
+ f(10, 4) == hana::make_tuple(
+ 10 + 4,
+ 10 - 4,
+ 10 * 4,
+ 10 / 4
+ )
+, "");
+
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/fix.cpp b/src/boost/libs/hana/example/functional/fix.cpp
new file mode 100644
index 000000000..62ad03742
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/fix.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/functional/fix.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTEXPR_STATELESS_LAMBDA auto factorial = hana::fix([](auto fact, auto n) -> int {
+ if (n == 0) return 1;
+ else return n * fact(n - 1);
+});
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(factorial(5) == 120);
+}
diff --git a/src/boost/libs/hana/example/functional/flip.cpp b/src/boost/libs/hana/example/functional/flip.cpp
new file mode 100644
index 000000000..9afb2bcad
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/flip.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/functional/flip.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto minus = [](int x, int y, int z = 0) {
+ return x - y - z;
+};
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(minus(3, 0) == 3 - 0);
+ BOOST_HANA_CONSTEXPR_CHECK(hana::flip(minus)(3, 0) == 0 - 3);
+
+ BOOST_HANA_CONSTEXPR_CHECK(minus(3, 0, 1) == 3 - 0 - 1);
+ BOOST_HANA_CONSTEXPR_CHECK(hana::flip(minus)(3, 0, 1) == 0 - 3 - 1);
+}
diff --git a/src/boost/libs/hana/example/functional/id.cpp b/src/boost/libs/hana/example/functional/id.cpp
new file mode 100644
index 000000000..16a39c1e7
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/id.cpp
@@ -0,0 +1,12 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/functional/id.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::id(1) == 1, "");
+static_assert(hana::id('x') == 'x', "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/infix.cpp b/src/boost/libs/hana/example/functional/infix.cpp
new file mode 100644
index 000000000..3b74044d8
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/infix.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/infix.hpp>
+#include <boost/hana/pair.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto divmod = hana::infix([](auto x, auto y) {
+ // this could be a more efficient implementation
+ return hana::make_pair(x / y, x % y);
+});
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK((42 ^divmod^ 23) == hana::make_pair(1, 19));
+}
diff --git a/src/boost/libs/hana/example/functional/iterate.cpp b/src/boost/libs/hana/example/functional/iterate.cpp
new file mode 100644
index 000000000..40aa7c93c
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/iterate.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/iterate.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto next_10 = hana::iterate<10>(hana::_ + 1);
+static_assert(next_10(3) == 13, "");
+
+constexpr auto xs = hana::make_tuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+static_assert(hana::iterate<3>(hana::make_tuple, xs) ==
+ hana::make_tuple(hana::make_tuple(hana::make_tuple(xs))), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/lockstep.cpp b/src/boost/libs/hana/example/functional/lockstep.cpp
new file mode 100644
index 000000000..cbb8266ca
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/lockstep.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/functional/lockstep.hpp>
+#include <boost/hana/plus.hpp>
+namespace hana = boost::hana;
+
+
+constexpr int to_int(char c) {
+ return static_cast<int>(c) - 48;
+}
+
+constexpr int increment(int i) {
+ return i + 1;
+}
+
+static_assert(hana::lockstep(hana::plus)(to_int, increment)('3', 4) == 3 + 5, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/on.cpp b/src/boost/libs/hana/example/functional/on.cpp
new file mode 100644
index 000000000..bc5e5662b
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/on.cpp
@@ -0,0 +1,36 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/first.hpp>
+#include <boost/hana/functional/on.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/sort.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+// infix application
+constexpr auto sorted = hana::sort.by(hana::less ^hana::on^ hana::first, hana::make_tuple(
+ hana::make_pair(hana::int_c<3>, 'x'),
+ hana::make_pair(hana::int_c<1>, hana::type_c<void>),
+ hana::make_pair(hana::int_c<2>, 9876)
+));
+
+static_assert(sorted == hana::make_tuple(
+ hana::make_pair(hana::int_c<1>, hana::type_c<void>),
+ hana::make_pair(hana::int_c<2>, 9876),
+ hana::make_pair(hana::int_c<3>, 'x')
+), "");
+
+
+// function call syntax
+constexpr auto x = hana::make_pair(1, 2);
+constexpr auto y = hana::make_pair(10, 20);
+static_assert(hana::on(hana::plus, hana::first)(x, y) == 1 + 10, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/overload.cpp b/src/boost/libs/hana/example/functional/overload.cpp
new file mode 100644
index 000000000..2a78f7b5d
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/overload.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/functional/overload.hpp>
+
+#include <iostream>
+#include <string>
+namespace hana = boost::hana;
+
+
+auto on_string = [](std::string const& s) {
+ std::cout << "matched std::string: " << s << std::endl;
+ return s;
+};
+
+auto on_int = [](int i) {
+ std::cout << "matched int: " << i << std::endl;
+ return i;
+};
+
+auto f = hana::overload(on_int, on_string);
+
+int main() {
+ // prints "matched int: 1"
+ BOOST_HANA_RUNTIME_CHECK(f(1) == 1);
+
+ // prints "matched std::string: abcdef"
+ BOOST_HANA_RUNTIME_CHECK(f("abcdef") == std::string{"abcdef"});
+}
diff --git a/src/boost/libs/hana/example/functional/overload_linearly.cpp b/src/boost/libs/hana/example/functional/overload_linearly.cpp
new file mode 100644
index 000000000..632234f56
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/overload_linearly.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/functional/overload_linearly.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+auto f = hana::overload_linearly(
+ [](int i) { return i + 1; },
+ [](std::string s) { return s + "d"; },
+ [](double) { BOOST_HANA_RUNTIME_CHECK(false && "never called"); }
+);
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(f(1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(f("abc") == "abcd");
+ BOOST_HANA_RUNTIME_CHECK(f(2.2) == static_cast<int>(2.2) + 1);
+}
diff --git a/src/boost/libs/hana/example/functional/partial.cpp b/src/boost/libs/hana/example/functional/partial.cpp
new file mode 100644
index 000000000..ac40f12a4
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/partial.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/plus.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto increment = hana::partial(hana::plus, 1);
+static_assert(increment(2) == 3, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/placeholder.cpp b/src/boost/libs/hana/example/functional/placeholder.cpp
new file mode 100644
index 000000000..31cbc4a55
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/placeholder.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/functional/placeholder.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto plus = hana::_ + hana::_;
+static_assert(plus(1, 2) == 1 + 2, "");
+
+constexpr auto increment = hana::_ + 1;
+static_assert(increment(1) == 2, "");
+
+constexpr auto twice = 2 * hana::_;
+static_assert(twice(1) == 2, "");
+
+// Extra arguments are ignored.
+static_assert(twice(1, "ignored") == 2, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/functional/reverse_partial.cpp b/src/boost/libs/hana/example/functional/reverse_partial.cpp
new file mode 100644
index 000000000..45ba8f18b
--- /dev/null
+++ b/src/boost/libs/hana/example/functional/reverse_partial.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/div.hpp>
+#include <boost/hana/functional/reverse_partial.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto half = hana::reverse_partial(hana::div, 2);
+static_assert(half(4) == 2, "");
+static_assert(half(8) == 4, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/fuse.cpp b/src/boost/libs/hana/example/fuse.cpp
new file mode 100644
index 000000000..52f422db2
--- /dev/null
+++ b/src/boost/libs/hana/example/fuse.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/fuse.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+auto tie = [](auto& ...vars) {
+ return hana::fuse([&vars...](auto ...values) {
+ // Using an initializer list to sequence the assignments.
+ int dummy[] = {0, ((void)(vars = values), 0)...};
+ (void)dummy;
+ });
+};
+
+int main() {
+ int a = 0;
+ char b = '\0';
+ double c = 0;
+
+ tie(a, b, c)(hana::make_tuple(1, '2', 3.3));
+ BOOST_HANA_RUNTIME_CHECK(a == 1 && b == '2' && c == 3.3);
+}
diff --git a/src/boost/libs/hana/example/greater.cpp b/src/boost/libs/hana/example/greater.cpp
new file mode 100644
index 000000000..be5b56c79
--- /dev/null
+++ b/src/boost/libs/hana/example/greater.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/integral_constant.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::greater(4, 1), "");
+BOOST_HANA_CONSTANT_CHECK(!hana::greater(hana::int_c<1>, hana::int_c<3>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/greater_equal.cpp b/src/boost/libs/hana/example/greater_equal.cpp
new file mode 100644
index 000000000..5b9021c43
--- /dev/null
+++ b/src/boost/libs/hana/example/greater_equal.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/greater_equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::greater_equal(4, 1), "");
+static_assert(hana::greater_equal(1, 1), "");
+BOOST_HANA_CONSTANT_CHECK(!hana::greater_equal(hana::int_c<1>, hana::int_c<2>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/group.cpp b/src/boost/libs/hana/example/group.cpp
new file mode 100644
index 000000000..9025cb0a3
--- /dev/null
+++ b/src/boost/libs/hana/example/group.cpp
@@ -0,0 +1,64 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/comparing.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/group.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+// group without a predicate
+BOOST_HANA_CONSTANT_CHECK(
+ hana::group(hana::make_tuple(hana::int_c<1>, hana::long_c<1>, hana::type_c<int>, hana::char_c<'x'>, hana::char_c<'x'>))
+ == hana::make_tuple(
+ hana::make_tuple(hana::int_c<1>, hana::long_c<1>),
+ hana::make_tuple(hana::type_c<int>),
+ hana::make_tuple(hana::char_c<'x'>, hana::char_c<'x'>)
+ )
+);
+
+
+// group with a predicate
+constexpr auto tuples = hana::make_tuple(
+ hana::range_c<int, 0, 1>,
+ hana::range_c<int, 0, 2>,
+ hana::range_c<int, 1, 3>,
+ hana::range_c<int, 2, 6>
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::group(tuples, hana::comparing(hana::length))
+ == hana::make_tuple(
+ hana::make_tuple(
+ hana::range_c<int, 0, 1>
+ ),
+ hana::make_tuple(
+ hana::range_c<int, 0, 2>,
+ hana::range_c<int, 1, 3>
+ ),
+ hana::make_tuple(
+ hana::range_c<int, 2, 6>
+ )
+ )
+);
+
+
+// group.by is syntactic sugar
+static_assert(
+ hana::group.by(hana::comparing(hana::typeid_),
+ hana::make_tuple(1, 2, 3, 'x', 'y', 4.4, 5.5))
+ == hana::make_tuple(
+ hana::make_tuple(1, 2, 3),
+ hana::make_tuple('x', 'y'),
+ hana::make_tuple(4.4, 5.5)
+ )
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/hash.cpp b/src/boost/libs/hana/example/hash.cpp
new file mode 100644
index 000000000..dcbdd7afa
--- /dev/null
+++ b/src/boost/libs/hana/example/hash.cpp
@@ -0,0 +1,44 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/hash.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+// Sample implementation of a compile-time set data structure. Of course,
+// this naive implementation only works when no two elements of the same
+// set have the same hash.
+template <typename T>
+struct bucket { };
+
+template <typename ...T>
+struct set
+ : bucket<typename decltype(hana::hash(std::declval<T>()))::type>...
+{ };
+
+template <typename Set, typename T>
+struct contains
+ : std::is_base_of<
+ bucket<typename decltype(hana::hash(std::declval<T>()))::type>,
+ Set
+ >
+{ };
+
+using Set = set<hana::int_<1>, hana::ulong<2>, hana::type<char>>;
+
+static_assert(contains<Set, hana::int_<1>>{}, "");
+static_assert(contains<Set, hana::ulong<2>>{}, "");
+static_assert(contains<Set, hana::type<char>>{}, "");
+
+static_assert(!contains<Set, hana::int_<3>>{}, "");
+static_assert(!contains<Set, hana::type<float>>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/if.cpp b/src/boost/libs/hana/example/if.cpp
new file mode 100644
index 000000000..9d580a07f
--- /dev/null
+++ b/src/boost/libs/hana/example/if.cpp
@@ -0,0 +1,24 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::if_(true, 1, 2) == 1, "");
+static_assert(hana::if_(false, 1, 2) == 2, "");
+
+static_assert(
+ hana::if_(hana::true_c,
+ hana::make_tuple('t', 'r', 'u', 'e'),
+ hana::make_tuple('f', 'a', 'l', 's', 'e')
+ )
+ ==
+ hana::make_tuple('t', 'r', 'u', 'e')
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/in.cpp b/src/boost/libs/hana/example/in.cpp
new file mode 100644
index 000000000..ae8f227cf
--- /dev/null
+++ b/src/boost/libs/hana/example/in.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<2> ^hana::in^ hana::make_tuple(2, hana::int_c<2>, hana::int_c<3>, 'x'));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/index_if.cpp b/src/boost/libs/hana/example/index_if.cpp
new file mode 100644
index 000000000..098b2b8c2
--- /dev/null
+++ b/src/boost/libs/hana/example/index_if.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Copyright Jason Rice 2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/is_a.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/index_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.0);
+
+static_assert(hana::index_if(xs, hana::is_an<int>) == hana::just(hana::size_c<0>), "");
+static_assert(hana::index_if(xs, hana::is_a<char>) == hana::just(hana::size_c<1>), "");
+static_assert(hana::index_if(xs, hana::is_a<double>) == hana::just(hana::size_c<2>), "");
+static_assert(hana::index_if(xs, hana::is_a<hana::tuple_tag>) == hana::nothing, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/insert.cpp b/src/boost/libs/hana/example/insert.cpp
new file mode 100644
index 000000000..d2e210a66
--- /dev/null
+++ b/src/boost/libs/hana/example/insert.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/insert.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace hana::literals;
+using namespace std::literals;
+
+
+int main() {
+ auto xs = hana::make_tuple("Hello"s, "world!"s);
+
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::insert(xs, 1_c, " "s) == hana::make_tuple("Hello"s, " "s, "world!"s)
+ );
+}
diff --git a/src/boost/libs/hana/example/insert_range.cpp b/src/boost/libs/hana/example/insert_range.cpp
new file mode 100644
index 000000000..1d78c57ab
--- /dev/null
+++ b/src/boost/libs/hana/example/insert_range.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/insert_range.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace hana::literals;
+using namespace std::literals;
+
+
+int main() {
+ auto xs = hana::make_tuple("Hello"s, "world!"s);
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::insert_range(xs, 1_c, hana::make_tuple(1, 2, 3)) == hana::make_tuple("Hello"s, 1, 2, 3, "world!"s)
+ );
+}
diff --git a/src/boost/libs/hana/example/integral_constant.cpp b/src/boost/libs/hana/example/integral_constant.cpp
new file mode 100644
index 000000000..aaad126da
--- /dev/null
+++ b/src/boost/libs/hana/example/integral_constant.cpp
@@ -0,0 +1,101 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/negate.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+#include <vector>
+namespace hana = boost::hana;
+
+
+int main() {
+
+{
+
+//! [operators]
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<1> + hana::int_c<3> == hana::int_c<4>);
+
+// Mixed-type operations are supported, but only when it involves a
+// promotion, and not a conversion that could be lossy.
+BOOST_HANA_CONSTANT_CHECK(hana::size_c<3> * hana::ushort_c<5> == hana::size_c<15>);
+BOOST_HANA_CONSTANT_CHECK(hana::llong_c<15> == hana::int_c<15>);
+//! [operators]
+
+}{
+
+//! [times_loop_unrolling]
+std::string s;
+for (char c = 'x'; c <= 'z'; ++c)
+ hana::int_<5>::times([&] { s += c; });
+
+BOOST_HANA_RUNTIME_CHECK(s == "xxxxxyyyyyzzzzz");
+//! [times_loop_unrolling]
+
+}{
+
+//! [times_higher_order]
+std::string s;
+auto functions = hana::make_tuple(
+ [&] { s += "x"; },
+ [&] { s += "y"; },
+ [&] { s += "z"; }
+);
+hana::for_each(functions, hana::int_<5>::times);
+BOOST_HANA_RUNTIME_CHECK(s == "xxxxxyyyyyzzzzz");
+//! [times_higher_order]
+
+}{
+
+//! [from_object]
+std::string s;
+for (char c = 'x'; c <= 'z'; ++c)
+ hana::int_c<5>.times([&] { s += c; });
+
+BOOST_HANA_RUNTIME_CHECK(s == "xxxxxyyyyyzzzzz");
+//! [from_object]
+
+}{
+
+//! [times_with_index_runtime]
+std::vector<int> v;
+hana::int_<5>::times.with_index([&](auto index) { v.push_back(index); });
+
+BOOST_HANA_RUNTIME_CHECK(v == std::vector<int>{0, 1, 2, 3, 4});
+//! [times_with_index_runtime]
+
+//! [times_with_index_compile_time]
+constexpr auto xs = hana::tuple_c<int, 0, 1, 2>;
+hana::int_<3>::times.with_index([xs](auto index) {
+ BOOST_HANA_CONSTANT_CHECK(xs[index] == index);
+});
+//! [times_with_index_compile_time]
+
+}{
+
+//! [literals]
+using namespace hana::literals; // contains the _c suffix
+
+BOOST_HANA_CONSTANT_CHECK(1234_c == hana::llong_c<1234>);
+BOOST_HANA_CONSTANT_CHECK(-1234_c == hana::llong_c<-1234>);
+BOOST_HANA_CONSTANT_CHECK(1_c + (3_c * 4_c) == hana::llong_c<1 + (3 * 4)>);
+//! [literals]
+
+}{
+
+//! [integral_c]
+BOOST_HANA_CONSTANT_CHECK(hana::integral_c<int, 2> == hana::int_c<2>);
+static_assert(decltype(hana::integral_c<int, 2>)::value == 2, "");
+//! [integral_c]
+
+}
+
+}
diff --git a/src/boost/libs/hana/example/intersperse.cpp b/src/boost/libs/hana/example/intersperse.cpp
new file mode 100644
index 000000000..3e9566996
--- /dev/null
+++ b/src/boost/libs/hana/example/intersperse.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/intersperse.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::intersperse(hana::make_tuple(1, '2', 3.3), 'x') == hana::make_tuple(1, 'x', '2', 'x', 3.3), "");
+BOOST_HANA_CONSTANT_CHECK(hana::intersperse(hana::make_tuple(), 'x') == hana::make_tuple());
+
+int main() { }
diff --git a/src/boost/libs/hana/example/is_disjoint.cpp b/src/boost/libs/hana/example/is_disjoint.cpp
new file mode 100644
index 000000000..71cde04e5
--- /dev/null
+++ b/src/boost/libs/hana/example/is_disjoint.cpp
@@ -0,0 +1,45 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/is_disjoint.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ // Tuples
+ auto xs = hana::make_tuple(hana::int_c<1>, "alfa"s, hana::type_c<int>);
+ auto ys = hana::make_tuple(hana::type_c<void>, hana::int_c<3>, "bravo"s);
+ BOOST_HANA_RUNTIME_CHECK(hana::is_disjoint(xs, ys));
+
+ // Sets
+ auto s1 = hana::make_set(hana::int_c<1>, hana::type_c<void>, hana::int_c<2>);
+ auto s2 = hana::make_set(hana::type_c<char>, hana::type_c<int>, hana::int_c<1>);
+ BOOST_HANA_CONSTANT_CHECK(!hana::is_disjoint(s1, s2));
+
+ // Maps
+ auto vowels = hana::make_map(
+ hana::make_pair(hana::char_c<'a'>, "alfa"s),
+ hana::make_pair(hana::char_c<'e'>, "echo"s),
+ hana::make_pair(hana::char_c<'i'>, "india"s)
+ // ...
+ );
+
+ auto consonants = hana::make_map(
+ hana::make_pair(hana::char_c<'b'>, "bravo"s),
+ hana::make_pair(hana::char_c<'c'>, "charlie"s),
+ hana::make_pair(hana::char_c<'f'>, "foxtrot"s)
+ // ...
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_disjoint(vowels, consonants));
+}
diff --git a/src/boost/libs/hana/example/is_empty.cpp b/src/boost/libs/hana/example/is_empty.cpp
new file mode 100644
index 000000000..d9893511d
--- /dev/null
+++ b/src/boost/libs/hana/example/is_empty.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(!hana::is_empty(hana::make_tuple(1, '2')));
+BOOST_HANA_CONSTANT_CHECK( hana::is_empty(hana::make_tuple()));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/is_subset.cpp b/src/boost/libs/hana/example/is_subset.cpp
new file mode 100644
index 000000000..064942b52
--- /dev/null
+++ b/src/boost/libs/hana/example/is_subset.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/is_subset.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(
+ hana::is_subset(hana::make_tuple(1, '2', 3.3), hana::make_tuple(3.3, 1, '2', nullptr))
+, "");
+
+// is_subset can be applied in infix notation
+static_assert(
+ hana::make_tuple(1, '2', 3.3) ^hana::is_subset^ hana::make_tuple(3.3, 1, '2', nullptr)
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/iterable/searchable.cpp b/src/boost/libs/hana/example/iterable/searchable.cpp
new file mode 100644
index 000000000..a685361cf
--- /dev/null
+++ b/src/boost/libs/hana/example/iterable/searchable.cpp
@@ -0,0 +1,47 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// First get the type of the object, and then call the trait on it.
+constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::typeid_);
+constexpr auto is_class = hana::compose(hana::trait<std::is_class>, hana::typeid_);
+
+static_assert(
+ hana::find_if(hana::make_tuple(1.0, 2, '3'), is_integral)
+ ==
+ hana::just(2)
+, "");
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find_if(hana::make_tuple(1.0, 2, '3'), is_class)
+ ==
+ hana::nothing
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find(hana::make_tuple(hana::int_c<1>, hana::char_c<'c'>, hana::type_c<void>), hana::type_c<void>)
+ ==
+ hana::just(hana::type_c<void>)
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::find(hana::make_tuple(hana::int_c<1>, hana::char_c<'c'>, hana::type_c<void>), hana::type_c<int>)
+ ==
+ hana::nothing
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/lazy/comonad.cpp b/src/boost/libs/hana/example/lazy/comonad.cpp
new file mode 100644
index 000000000..39bbbea6b
--- /dev/null
+++ b/src/boost/libs/hana/example/lazy/comonad.cpp
@@ -0,0 +1,30 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/eval.hpp>
+#include <boost/hana/extend.hpp>
+#include <boost/hana/extract.hpp>
+#include <boost/hana/lazy.hpp>
+
+#include <sstream>
+namespace hana = boost::hana;
+
+
+int main() {
+ std::stringstream s("1 2 3");
+ auto i = hana::make_lazy([&] {
+ int i;
+ s >> i;
+ return i;
+ })();
+
+ auto i_plus_one = hana::extend(i, [](auto lazy_int) {
+ return hana::eval(lazy_int) + 1;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(hana::extract(i_plus_one) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::extract(i_plus_one) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::extract(i_plus_one) == 4);
+}
diff --git a/src/boost/libs/hana/example/lazy/functor.cpp b/src/boost/libs/hana/example/lazy/functor.cpp
new file mode 100644
index 000000000..5fa20ab3b
--- /dev/null
+++ b/src/boost/libs/hana/example/lazy/functor.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/eval.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/transform.hpp>
+namespace hana = boost::hana;
+using hana::_;
+
+
+int main() {
+ static_assert(hana::eval(hana::transform(hana::make_lazy(4 / _)(1), _ * 3)) == (4 / 1) * 3, "");
+
+ hana::transform(hana::make_lazy(4 / _)(0), _ * 3); // never evaluated
+}
diff --git a/src/boost/libs/hana/example/lazy/make.cpp b/src/boost/libs/hana/example/lazy/make.cpp
new file mode 100644
index 000000000..d602c96d4
--- /dev/null
+++ b/src/boost/libs/hana/example/lazy/make.cpp
@@ -0,0 +1,24 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/eval.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/lazy.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto f = hana::make<hana::lazy_tag>([](auto x) {
+ return 1 / x;
+ });
+
+ BOOST_HANA_CONSTEXPR_LAMBDA auto g = hana::make_lazy([](auto x) {
+ return x + 1;
+ });
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::eval(hana::if_(hana::false_c, f(0), g(0))) == 0 + 1);
+}
diff --git a/src/boost/libs/hana/example/lazy/monad.cpp b/src/boost/libs/hana/example/lazy/monad.cpp
new file mode 100644
index 000000000..f425e2810
--- /dev/null
+++ b/src/boost/libs/hana/example/lazy/monad.cpp
@@ -0,0 +1,47 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/eval.hpp>
+#include <boost/hana/lazy.hpp>
+
+#include <functional>
+#include <iostream>
+#include <sstream>
+namespace hana = boost::hana;
+
+
+template <typename T>
+T read_(std::istream& stream) {
+ T x;
+ stream >> x;
+ std::cout << "read " << x << " from the stream\n";
+ return x;
+}
+
+int main() {
+ std::stringstream ss;
+ int in = 123;
+
+ std::cout << "creating the monadic chain...\n";
+ auto out = hana::make_lazy(read_<int>)(std::ref(ss))
+ | [](auto x) {
+ std::cout << "performing x + 1...\n";
+ return hana::make_lazy(x + 1);
+ }
+ | [](auto x) {
+ std::cout << "performing x / 2...\n";
+ return hana::make_lazy(x / 2);
+ };
+
+ std::cout << "putting " << in << " in the stream...\n";
+ ss << in; // nothing is evaluated yet
+
+ std::cout << "evaluating the monadic chain...\n";
+ auto eout = hana::eval(out);
+
+ std::cout << "the result of the monadic chain is " << eout << "\n";
+ BOOST_HANA_RUNTIME_CHECK(eout == (in + 1) / 2);
+}
diff --git a/src/boost/libs/hana/example/length.cpp b/src/boost/libs/hana/example/length.cpp
new file mode 100644
index 000000000..26246dac0
--- /dev/null
+++ b/src/boost/libs/hana/example/length.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::length(hana::make_tuple()) == hana::size_c<0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::length(hana::make_tuple(1, '2', 3.0)) == hana::size_c<3>);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::length(hana::nothing) == hana::size_c<0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::length(hana::just('x')) == hana::size_c<1>);
+}
diff --git a/src/boost/libs/hana/example/less.cpp b/src/boost/libs/hana/example/less.cpp
new file mode 100644
index 000000000..1762aede3
--- /dev/null
+++ b/src/boost/libs/hana/example/less.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::less(1, 4), "");
+BOOST_HANA_CONSTANT_CHECK(!hana::less(hana::int_c<3>, hana::int_c<2>));
+
+// less.than is syntactic sugar
+static_assert(hana::all_of(hana::tuple_c<int, 1, 2, 3, 4>, hana::less.than(5)), "");
+BOOST_HANA_CONSTANT_CHECK(hana::all_of(hana::tuple_c<int, 1, 2, 3, 4>, hana::less_equal.than(hana::int_c<4>)));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/less_equal.cpp b/src/boost/libs/hana/example/less_equal.cpp
new file mode 100644
index 000000000..368c2e896
--- /dev/null
+++ b/src/boost/libs/hana/example/less_equal.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/less_equal.hpp>
+#include <boost/hana/not.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::less_equal(1, 4), "");
+static_assert(hana::less_equal(1, 1), "");
+BOOST_HANA_CONSTANT_CHECK(!hana::less_equal(hana::int_c<3>, hana::int_c<2>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/lexicographical_compare.cpp b/src/boost/libs/hana/example/lexicographical_compare.cpp
new file mode 100644
index 000000000..5c70f59e8
--- /dev/null
+++ b/src/boost/libs/hana/example/lexicographical_compare.cpp
@@ -0,0 +1,39 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/lexicographical_compare.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // works with elements whose `less` does not return a Constant
+ {
+ constexpr auto xs = hana::make_tuple(1, 2, 3, 4);
+ constexpr auto ys = hana::make_tuple(1, 6, 3, 4);
+ static_assert(hana::lexicographical_compare(xs, ys), "");
+ }
+
+ // and with those that do
+ {
+ auto xs = hana::make_tuple(hana::int_c<1>, hana::int_c<2>, hana::int_c<3>);
+ auto ys = hana::make_tuple(hana::int_c<1>, hana::int_c<5>, hana::int_c<3>);
+ BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare(xs, ys));
+ }
+
+ // it also accepts a custom predicate
+ {
+ auto xs = hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<void*>);
+ auto ys = hana::make_tuple(hana::type_c<int>, hana::type_c<long>, hana::type_c<void*>);
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::lexicographical_compare(xs, ys, [](auto t, auto u) {
+ return hana::sizeof_(t) < hana::sizeof_(u);
+ })
+ );
+ }
+}
diff --git a/src/boost/libs/hana/example/lift.cpp b/src/boost/libs/hana/example/lift.cpp
new file mode 100644
index 000000000..c8f777cbd
--- /dev/null
+++ b/src/boost/libs/hana/example/lift.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::lift<hana::tuple_tag>('x') == hana::make_tuple('x'), "");
+static_assert(hana::lift<hana::optional_tag>('x') == hana::just('x'), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/map/comparable.cpp b/src/boost/libs/hana/example/map/comparable.cpp
new file mode 100644
index 000000000..4c3d348b0
--- /dev/null
+++ b/src/boost/libs/hana/example/map/comparable.cpp
@@ -0,0 +1,28 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::make_map(
+ hana::make_pair(hana::char_c<'a'>, "foobar"s),
+ hana::make_pair(hana::type_c<int&&>, nullptr)
+ )
+ ==
+ hana::make_map(
+ hana::make_pair(hana::type_c<int&&>, (void*)0),
+ hana::make_pair(hana::char_c<'a'>, "foobar"s)
+ )
+ );
+}
diff --git a/src/boost/libs/hana/example/map/difference.cpp b/src/boost/libs/hana/example/map/difference.cpp
new file mode 100644
index 000000000..6b94b0a22
--- /dev/null
+++ b/src/boost/libs/hana/example/map/difference.cpp
@@ -0,0 +1,45 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/difference.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/string.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+static auto m1 = hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>)
+);
+
+static auto m2 = hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
+);
+
+static auto m3 = hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<int>),
+ hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<long long>)
+);
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::difference(m1, m2) == m1);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::difference(m1, m3) == hana::make_map());
+
+ BOOST_HANA_CONSTANT_CHECK(hana::difference(m3, m1) == hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<int>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::difference(m2, m3) == hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
+ ));
+}
diff --git a/src/boost/libs/hana/example/map/erase_key.cpp b/src/boost/libs/hana/example/map/erase_key.cpp
new file mode 100644
index 000000000..2ba407145
--- /dev/null
+++ b/src/boost/libs/hana/example/map/erase_key.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/erase_key.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ auto m = hana::make_map(
+ hana::make_pair(hana::type_c<int>, "abcd"s),
+ hana::make_pair(hana::type_c<void>, 1234),
+ hana::make_pair(BOOST_HANA_STRING("foobar!"), hana::type_c<char>)
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::erase_key(m, BOOST_HANA_STRING("foobar!")) ==
+ hana::make_map(
+ hana::make_pair(hana::type_c<int>, "abcd"s),
+ hana::make_pair(hana::type_c<void>, 1234)
+ )
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(hana::erase_key(m, hana::type_c<char>) == m);
+}
diff --git a/src/boost/libs/hana/example/map/foldable.cpp b/src/boost/libs/hana/example/map/foldable.cpp
new file mode 100644
index 000000000..1884220a3
--- /dev/null
+++ b/src/boost/libs/hana/example/map/foldable.cpp
@@ -0,0 +1,39 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/insert.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // Given a map of (key, value) pairs, returns a map of (value, key) pairs.
+ // This requires both the keys and the values to be compile-time Comparable.
+ auto invert = [](auto map) {
+ return hana::fold_left(map, hana::make_map(), [](auto map, auto pair) {
+ return hana::insert(map, hana::make_pair(hana::second(pair), hana::first(pair)));
+ });
+ };
+
+ auto m = hana::make_map(
+ hana::make_pair(hana::type_c<int>, hana::int_c<1>),
+ hana::make_pair(hana::type_c<float>, hana::int_c<2>),
+ hana::make_pair(hana::int_c<3>, hana::type_c<void>)
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(invert(m) ==
+ hana::make_map(
+ hana::make_pair(hana::int_c<1>, hana::type_c<int>),
+ hana::make_pair(hana::int_c<2>, hana::type_c<float>),
+ hana::make_pair(hana::type_c<void>, hana::int_c<3>)
+ )
+ );
+}
diff --git a/src/boost/libs/hana/example/map/insert.cpp b/src/boost/libs/hana/example/map/insert.cpp
new file mode 100644
index 000000000..80aff7d5f
--- /dev/null
+++ b/src/boost/libs/hana/example/map/insert.cpp
@@ -0,0 +1,32 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/insert.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ auto m = hana::make_map(
+ hana::make_pair(hana::type_c<int>, "abcd"s),
+ hana::make_pair(hana::type_c<void>, 1234)
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::insert(m, hana::make_pair(hana::type_c<float>, 'x')) ==
+ hana::make_map(
+ hana::make_pair(hana::type_c<int>, "abcd"s),
+ hana::make_pair(hana::type_c<void>, 1234),
+ hana::make_pair(hana::type_c<float>, 'x')
+ )
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(hana::insert(m, hana::make_pair(hana::type_c<void>, 'x')) == m);
+}
diff --git a/src/boost/libs/hana/example/map/intersection.cpp b/src/boost/libs/hana/example/map/intersection.cpp
new file mode 100644
index 000000000..1be8bf0b9
--- /dev/null
+++ b/src/boost/libs/hana/example/map/intersection.cpp
@@ -0,0 +1,47 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/intersection.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/string.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+static auto m1 = hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>)
+);
+
+static auto m2 = hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
+);
+
+BOOST_HANA_CONSTANT_CHECK(hana::intersection(m1, m2) == hana::make_map());
+
+static auto m3 = hana::make_map(
+ hana::make_pair(hana::type_c<int>, hana::int_c<1>),
+ hana::make_pair(hana::type_c<bool>, hana::bool_c<true>),
+ hana::make_pair(hana::type_c<std::string>, BOOST_HANA_STRING("hana")),
+ hana::make_pair(hana::type_c<float>, hana::int_c<100>)
+);
+
+static auto m4 = hana::make_map(
+ hana::make_pair(hana::type_c<char>, hana::char_c<'c'>),
+ hana::make_pair(hana::type_c<bool>, hana::bool_c<false>),
+ hana::make_pair(hana::type_c<std::string>, BOOST_HANA_STRING("boost"))
+);
+
+BOOST_HANA_CONSTANT_CHECK(hana::intersection(m3, m4) == hana::make_map(
+ hana::make_pair(hana::type_c<bool>, hana::bool_c<true>),
+ hana::make_pair(hana::type_c<std::string>, BOOST_HANA_STRING("hana"))
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/map/keys.cpp b/src/boost/libs/hana/example/map/keys.cpp
new file mode 100644
index 000000000..073d6dec6
--- /dev/null
+++ b/src/boost/libs/hana/example/map/keys.cpp
@@ -0,0 +1,30 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/keys.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ auto m = hana::make_map(
+ hana::make_pair(hana::int_c<1>, "foobar"s),
+ hana::make_pair(hana::type_c<void>, 1234)
+ );
+
+ // The order of the keys is unspecified.
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::keys(m) ^hana::in^ hana::permutations(hana::make_tuple(hana::int_c<1>, hana::type_c<void>))
+ );
+}
diff --git a/src/boost/libs/hana/example/map/make.cpp b/src/boost/libs/hana/example/map/make.cpp
new file mode 100644
index 000000000..a9660e1cb
--- /dev/null
+++ b/src/boost/libs/hana/example/map/make.cpp
@@ -0,0 +1,29 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::make_map(
+ hana::make_pair(hana::int_c<1>, "foobar"s),
+ hana::make_pair(hana::type_c<void>, 1234)
+ )
+ ==
+ hana::make<hana::map_tag>(
+ hana::make_pair(hana::int_c<1>, "foobar"s),
+ hana::make_pair(hana::type_c<void>, 1234)
+ )
+ );
+}
diff --git a/src/boost/libs/hana/example/map/map.cpp b/src/boost/libs/hana/example/map/map.cpp
new file mode 100644
index 000000000..a04ecfd73
--- /dev/null
+++ b/src/boost/libs/hana/example/map/map.cpp
@@ -0,0 +1,76 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+
+#include <functional>
+#include <string>
+#include <vector>
+namespace hana = boost::hana;
+
+
+template <typename ...Events>
+struct event_system {
+ using Callback = std::function<void()>;
+ hana::map<hana::pair<Events, std::vector<Callback>>...> map_;
+
+ template <typename Event, typename F>
+ void on(Event e, F handler) {
+ auto is_known_event = hana::contains(map_, e);
+ static_assert(is_known_event,
+ "trying to add a handler to an unknown event");
+
+ map_[e].push_back(handler);
+ }
+
+ template <typename Event>
+ void trigger(Event e) const {
+ auto is_known_event = hana::contains(map_, e);
+ static_assert(is_known_event,
+ "trying to trigger an unknown event");
+
+ for (auto& handler : this->map_[e])
+ handler();
+ }
+};
+
+template <typename ...Events>
+event_system<Events...> make_event_system(Events ...events) {
+ return {};
+}
+
+
+int main() {
+ auto events = make_event_system(
+ BOOST_HANA_STRING("foo"),
+ BOOST_HANA_STRING("bar"),
+ BOOST_HANA_STRING("baz")
+ );
+
+ std::vector<std::string> triggered_events;
+ events.on(BOOST_HANA_STRING("foo"), [&] {
+ triggered_events.push_back("foo:1");
+ });
+ events.on(BOOST_HANA_STRING("foo"), [&] {
+ triggered_events.push_back("foo:2");
+ });
+ events.on(BOOST_HANA_STRING("bar"), [&] {
+ triggered_events.push_back("bar:1");
+ });
+ events.on(BOOST_HANA_STRING("baz"), [&] {
+ triggered_events.push_back("baz:1");
+ });
+
+ events.trigger(BOOST_HANA_STRING("foo"));
+ events.trigger(BOOST_HANA_STRING("bar"));
+ events.trigger(BOOST_HANA_STRING("baz"));
+
+ BOOST_HANA_RUNTIME_CHECK(triggered_events == std::vector<std::string>{
+ "foo:1", "foo:2", "bar:1", "baz:1"
+ });
+}
diff --git a/src/boost/libs/hana/example/map/searchable.cpp b/src/boost/libs/hana/example/map/searchable.cpp
new file mode 100644
index 000000000..4f51e704e
--- /dev/null
+++ b/src/boost/libs/hana/example/map/searchable.cpp
@@ -0,0 +1,30 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto m = hana::make_map(
+ hana::make_pair(hana::type_c<int>, 'i'),
+ hana::make_pair(hana::type_c<float>, 'f')
+);
+static_assert(hana::find(m, hana::type_c<int>) == hana::just('i'), "");
+static_assert(hana::find(m, hana::type_c<float>) == hana::just('f'), "");
+BOOST_HANA_CONSTANT_CHECK(hana::find(m, hana::type_c<void>) == hana::nothing);
+BOOST_HANA_CONSTANT_CHECK(hana::find(m, hana::int_c<3>) == hana::nothing);
+
+// operator[] is equivalent to at_key
+static_assert(m[hana::type_c<int>] == 'i', "");
+static_assert(m[hana::type_c<float>] == 'f', "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/map/symmetric_difference.cpp b/src/boost/libs/hana/example/map/symmetric_difference.cpp
new file mode 100644
index 000000000..0f9784756
--- /dev/null
+++ b/src/boost/libs/hana/example/map/symmetric_difference.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/symmetric_difference.hpp>
+
+namespace hana = boost::hana;
+
+
+constexpr auto m1 = hana::make_map(
+ hana::make_pair(hana::type_c<int>, 1),
+ hana::make_pair(hana::type_c<bool>, hana::true_c)
+);
+
+constexpr auto m2 = hana::make_map(
+ hana::make_pair(hana::type_c<float>, 1.0),
+ hana::make_pair(hana::type_c<long long>, 2LL),
+ hana::make_pair(hana::type_c<int>, 3)
+);
+
+constexpr auto result_m = hana::make_map(
+ hana::make_pair(hana::type_c<bool>, hana::true_c),
+ hana::make_pair(hana::type_c<float>, 1.0),
+ hana::make_pair(hana::type_c<long long>, 2LL)
+);
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::symmetric_difference(m1, m2) == result_m
+ );
+}
diff --git a/src/boost/libs/hana/example/map/to.cpp b/src/boost/libs/hana/example/map/to.cpp
new file mode 100644
index 000000000..550c7665e
--- /dev/null
+++ b/src/boost/libs/hana/example/map/to.cpp
@@ -0,0 +1,30 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ auto xs = hana::make_tuple(
+ hana::make_pair(hana::type_c<int>, "abcd"s),
+ hana::make_pair(hana::type_c<void>, 1234),
+ hana::make_pair(hana::type_c<int>, nullptr)
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::to<hana::map_tag>(xs) == hana::make_map(
+ hana::make_pair(hana::type_c<int>, "abcd"s),
+ hana::make_pair(hana::type_c<void>, 1234)
+ )
+ );
+}
diff --git a/src/boost/libs/hana/example/map/union.cpp b/src/boost/libs/hana/example/map/union.cpp
new file mode 100644
index 000000000..d214b34df
--- /dev/null
+++ b/src/boost/libs/hana/example/map/union.cpp
@@ -0,0 +1,53 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/type.hpp>
+#include <boost/hana/union.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+static auto m1 = hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>)
+);
+
+static auto m2 = hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
+);
+
+BOOST_HANA_CONSTANT_CHECK(hana::union_(m1, m2) == hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
+ hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
+));
+
+constexpr auto m3 = hana::make_map(
+ hana::make_pair(hana::type_c<int>, hana::int_c<1>),
+ hana::make_pair(hana::type_c<bool>, hana::bool_c<true>)
+);
+
+constexpr auto m4 = hana::make_map(
+ hana::make_pair(hana::type_c<char>, hana::char_c<'c'>),
+ hana::make_pair(hana::type_c<bool>, hana::bool_c<false>)
+);
+
+BOOST_HANA_CONSTANT_CHECK(hana::union_(m3, m4) == hana::make_map(
+ hana::make_pair(hana::type_c<int>, hana::int_c<1>),
+ hana::make_pair(hana::type_c<bool>, hana::bool_c<false>),
+ hana::make_pair(hana::type_c<char>, hana::char_c<'c'>)
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/map/values.cpp b/src/boost/libs/hana/example/map/values.cpp
new file mode 100644
index 000000000..4bbfb92f5
--- /dev/null
+++ b/src/boost/libs/hana/example/map/values.cpp
@@ -0,0 +1,29 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ auto m = hana::make_map(
+ hana::make_pair(hana::int_c<1>, "foobar"s),
+ hana::make_pair(hana::type_c<void>, 1234)
+ );
+
+ // The order of the values is unspecified.
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::values(m) ^hana::in^ hana::permutations(hana::make_tuple("foobar"s, 1234))
+ );
+}
diff --git a/src/boost/libs/hana/example/max.cpp b/src/boost/libs/hana/example/max.cpp
new file mode 100644
index 000000000..15b1031b3
--- /dev/null
+++ b/src/boost/libs/hana/example/max.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/max.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::max(1, 4) == 4, "");
+BOOST_HANA_CONSTANT_CHECK(hana::max(hana::int_c<7>, hana::int_c<5>) == hana::int_c<7>);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/maximum.cpp b/src/boost/libs/hana/example/maximum.cpp
new file mode 100644
index 000000000..b6d377d55
--- /dev/null
+++ b/src/boost/libs/hana/example/maximum.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/maximum.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // without a predicate
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::maximum(hana::tuple_c<int, -1, 0, 2, -4, 6, 9>) == hana::int_c<9>
+ );
+
+ // with a predicate
+ auto smallest = hana::maximum(hana::tuple_c<int, -1, 0, 2, -4, 6, 9>, [](auto x, auto y) {
+ return x > y; // order is reversed!
+ });
+ BOOST_HANA_CONSTANT_CHECK(smallest == hana::int_c<-4>);
+}
diff --git a/src/boost/libs/hana/example/maximum_by.cpp b/src/boost/libs/hana/example/maximum_by.cpp
new file mode 100644
index 000000000..5ee979c23
--- /dev/null
+++ b/src/boost/libs/hana/example/maximum_by.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/maximum.hpp>
+#include <boost/hana/ordering.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ static_assert(
+ hana::maximum.by(hana::ordering(hana::length), hana::make_tuple(
+ hana::make_tuple(),
+ hana::make_tuple(1, '2'),
+ hana::make_tuple(3.3, nullptr, 4)
+ ))
+ == hana::make_tuple(3.3, nullptr, 4)
+ , "");
+}
diff --git a/src/boost/libs/hana/example/members.cpp b/src/boost/libs/hana/example/members.cpp
new file mode 100644
index 000000000..0353f3aff
--- /dev/null
+++ b/src/boost/libs/hana/example/members.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/members.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (unsigned short, age)
+ );
+};
+
+int main() {
+ Person john{"John", 30};
+ BOOST_HANA_RUNTIME_CHECK(hana::members(john) == hana::make_tuple("John", 30));
+}
diff --git a/src/boost/libs/hana/example/min.cpp b/src/boost/libs/hana/example/min.cpp
new file mode 100644
index 000000000..0449bae41
--- /dev/null
+++ b/src/boost/libs/hana/example/min.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/min.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::min(1, 4) == 1, "");
+BOOST_HANA_CONSTANT_CHECK(hana::min(hana::int_c<7>, hana::int_c<5>) == hana::int_c<5>);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/minimum.cpp b/src/boost/libs/hana/example/minimum.cpp
new file mode 100644
index 000000000..4349f2904
--- /dev/null
+++ b/src/boost/libs/hana/example/minimum.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minimum.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // without a predicate
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::minimum(hana::tuple_c<int, -1, 0, 2, -4, 6, 9>) == hana::int_c<-4>
+ );
+
+ // with a predicate
+ auto largest = hana::minimum(hana::tuple_c<int, -1, 0, 2, -4, 6, 9>, [](auto x, auto y) {
+ return x > y; // order is reversed!
+ });
+ BOOST_HANA_CONSTANT_CHECK(largest == hana::int_c<9>);
+}
diff --git a/src/boost/libs/hana/example/minimum_by.cpp b/src/boost/libs/hana/example/minimum_by.cpp
new file mode 100644
index 000000000..2595744ef
--- /dev/null
+++ b/src/boost/libs/hana/example/minimum_by.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/minimum.hpp>
+#include <boost/hana/ordering.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::minimum.by(hana::ordering(hana::length), hana::make_tuple(
+ hana::make_tuple(),
+ hana::make_tuple(1, '2'),
+ hana::make_tuple(3.3, nullptr, 4)
+ ))
+ == hana::make_tuple()
+ );
+}
diff --git a/src/boost/libs/hana/example/minus.cpp b/src/boost/libs/hana/example/minus.cpp
new file mode 100644
index 000000000..de1aa967e
--- /dev/null
+++ b/src/boost/libs/hana/example/minus.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minus.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::minus(hana::int_c<3>, hana::int_c<5>) == hana::int_c<-2>);
+ static_assert(hana::minus(1, 2) == -1, "");
+}
diff --git a/src/boost/libs/hana/example/misc/dimensional_analysis.cpp b/src/boost/libs/hana/example/misc/dimensional_analysis.cpp
new file mode 100644
index 000000000..40872df9f
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/dimensional_analysis.cpp
@@ -0,0 +1,71 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/zip_with.hpp>
+
+#include <functional>
+namespace hana = boost::hana;
+
+
+//
+// Example of implementing basic dimensional analysis using Hana
+//
+
+
+// base dimensions M L T I K J N
+using mass = decltype(hana::tuple_c<int, 1, 0, 0, 0, 0, 0, 0>);
+using length = decltype(hana::tuple_c<int, 0, 1, 0, 0, 0, 0, 0>);
+using time_ = decltype(hana::tuple_c<int, 0, 0, 1, 0, 0, 0, 0>);
+using charge = decltype(hana::tuple_c<int, 0, 0, 0, 1, 0, 0, 0>);
+using temperature = decltype(hana::tuple_c<int, 0, 0, 0, 0, 1, 0, 0>);
+using intensity = decltype(hana::tuple_c<int, 0, 0, 0, 0, 0, 1, 0>);
+using amount = decltype(hana::tuple_c<int, 0, 0, 0, 0, 0, 0, 1>);
+
+// composite dimensions
+using velocity = decltype(hana::tuple_c<int, 0, 1, -1, 0, 0, 0, 0>); // M/T
+using acceleration = decltype(hana::tuple_c<int, 0, 1, -2, 0, 0, 0, 0>); // M/T^2
+using force = decltype(hana::tuple_c<int, 1, 1, -2, 0, 0, 0, 0>); // ML/T^2
+
+
+template <typename Dimensions>
+struct quantity {
+ double value_;
+
+ explicit quantity(double v) : value_(v) { }
+
+ template <typename OtherDimensions>
+ explicit quantity(quantity<OtherDimensions> other)
+ : value_(other.value_)
+ {
+ static_assert(Dimensions{} == OtherDimensions{},
+ "Constructing quantities with incompatible dimensions!");
+ }
+
+ explicit operator double() const { return value_; }
+};
+
+template <typename D1, typename D2>
+auto operator*(quantity<D1> a, quantity<D2> b) {
+ using D = decltype(hana::zip_with(std::plus<>{}, D1{}, D2{}));
+ return quantity<D>{static_cast<double>(a) * static_cast<double>(b)};
+}
+
+template <typename D1, typename D2>
+auto operator/(quantity<D1> a, quantity<D2> b) {
+ using D = decltype(hana::zip_with(std::minus<>{}, D1{}, D2{}));
+ return quantity<D>{static_cast<double>(a) / static_cast<double>(b)};
+}
+
+int main() {
+ quantity<mass> m{10.3};
+ quantity<length> d{3.6};
+ quantity<time_> t{2.4};
+ quantity<velocity> v{d / t};
+ quantity<acceleration> a{3.9};
+ quantity<force> f{m * a};
+}
diff --git a/src/boost/libs/hana/example/misc/from_json.cpp b/src/boost/libs/hana/example/misc/from_json.cpp
new file mode 100644
index 000000000..a28cac1e5
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/from_json.cpp
@@ -0,0 +1,129 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/concept/struct.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/keys.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <iostream>
+#include <limits>
+#include <sstream>
+#include <string>
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct Car {
+ BOOST_HANA_DEFINE_STRUCT(Car,
+ (std::string, brand),
+ (std::string, model)
+ );
+};
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (std::string, last_name),
+ (int, age)
+ );
+};
+
+template <typename T>
+ std::enable_if_t<std::is_same<T, int>::value,
+T> from_json(std::istream& in) {
+ T result;
+ in >> result;
+ return result;
+}
+
+template <typename T>
+ std::enable_if_t<std::is_same<T, std::string>::value,
+T> from_json(std::istream& in) {
+ char quote;
+ in >> quote;
+
+ T result;
+ char c;
+ while (in.get(c) && c != '"') {
+ result += c;
+ }
+ return result;
+}
+
+
+template <typename T>
+ std::enable_if_t<hana::Struct<T>::value,
+T> from_json(std::istream& in) {
+ T result;
+ char brace;
+ in >> brace;
+
+ // CAREFUL: This only works if the input JSON contains the fields in the
+ // same order as the struct declares them.
+ hana::for_each(hana::keys(result), [&](auto key) {
+ in.ignore(std::numeric_limits<std::streamsize>::max(), ':');
+ auto& member = hana::at_key(result, key);
+ using Member = std::remove_reference_t<decltype(member)>;
+ member = from_json<Member>(in);
+ });
+ in >> brace;
+ return result;
+}
+
+template <typename Xs>
+ std::enable_if_t<hana::Sequence<Xs>::value,
+Xs> from_json(std::istream& in) {
+ Xs result;
+ char bracket;
+ in >> bracket;
+ hana::length(result).times.with_index([&](auto i) {
+ if (i != 0u) {
+ char comma;
+ in >> comma;
+ }
+
+ auto& element = hana::at(result, i);
+ using Element = std::remove_reference_t<decltype(element)>;
+ element = from_json<Element>(in);
+ });
+ in >> bracket;
+ return result;
+}
+
+
+int main() {
+ std::istringstream json(R"EOS(
+ [
+ {
+ "name": "John",
+ "last_name": "Doe",
+ "age": 30
+ },
+ {
+ "brand": "BMW",
+ "model": "Z3"
+ },
+ {
+ "brand": "Audi",
+ "model": "A4"
+ }
+ ]
+ )EOS");
+
+ auto actual = from_json<hana::tuple<Person, Car, Car>>(json);
+
+ auto expected = hana::make_tuple(Person{"John", "Doe", 30},
+ Car{"BMW", "Z3"},
+ Car{"Audi", "A4"});
+
+ BOOST_HANA_RUNTIME_CHECK(actual == expected);
+}
diff --git a/src/boost/libs/hana/example/misc/indexed_sort.cpp b/src/boost/libs/hana/example/misc/indexed_sort.cpp
new file mode 100644
index 000000000..de8308e4d
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/indexed_sort.cpp
@@ -0,0 +1,62 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/at.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/functional/on.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/sort.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+#include <boost/hana/zip.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+auto indexed_sort = [](auto list, auto predicate) {
+ auto indexed_list = hana::zip(
+ list,
+ hana::to_tuple(hana::make_range(0_c, hana::length(list)))
+ );
+ auto sorted = hana::sort.by(predicate ^hana::on^ hana::front, indexed_list);
+ return hana::make_pair(hana::transform(sorted, hana::front),
+ hana::transform(sorted, hana::back));
+};
+
+int main() {
+ auto types = hana::tuple_t<char[4], char[2], char[1], char[5], char[3]>;
+ auto sorted = indexed_sort(types, [](auto t, auto u) {
+ return hana::sizeof_(t) < hana::sizeof_(u);
+ });
+ using Tup = decltype(
+ hana::unpack(hana::first(sorted), hana::template_<hana::tuple>)
+ )::type;
+ auto indices = hana::second(indexed_sort(hana::second(sorted), hana::less));
+
+ // When accessed through the indices sequence, the tuple appears to be
+ // ordered as the `types` above. However, as can be seen in the
+ // static_assert below, the tuple is actually ordered differently.
+ Tup tup;
+ char const(&a)[4] = tup[indices[0_c]];
+ char const(&b)[2] = tup[indices[1_c]];
+ char const(&c)[1] = tup[indices[2_c]];
+ char const(&d)[5] = tup[indices[3_c]];
+ char const(&e)[3] = tup[indices[4_c]];
+
+ static_assert(std::is_same<
+ Tup,
+ hana::tuple<char[1], char[2], char[3], char[4], char[5]>
+ >{}, "");
+
+ (void)a; (void)b; (void)c; (void)d; (void)e;
+}
diff --git a/src/boost/libs/hana/example/misc/infinite_list.cpp b/src/boost/libs/hana/example/misc/infinite_list.cpp
new file mode 100644
index 000000000..b5eecaf18
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/infinite_list.cpp
@@ -0,0 +1,116 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/eval.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/functional/fix.hpp>
+#include <boost/hana/functional/iterate.hpp>
+#include <boost/hana/fwd/at.hpp>
+#include <boost/hana/fwd/empty.hpp>
+#include <boost/hana/fwd/prepend.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/value.hpp>
+
+#include <cstddef>
+namespace hana = boost::hana;
+
+
+// A naive implementation of a lazy compile-time list, i.e. a tuple that can
+// potentially have an infinite number of elements (but that infinity must be
+// determinable at compile-time).
+
+struct LazyList;
+
+template <typename X, typename Xs>
+struct lazy_cons_type {
+ X x;
+ Xs xs;
+ using hana_tag = LazyList;
+};
+
+auto lazy_cons = [](auto x, auto xs) {
+ return lazy_cons_type<decltype(x), decltype(xs)>{x, xs};
+};
+
+struct lazy_nil_type { using hana_tag = LazyList; };
+
+constexpr lazy_nil_type lazy_nil{};
+
+auto repeat = hana::fix([](auto repeat, auto x) {
+ return lazy_cons(x, hana::make_lazy(repeat)(x));
+});
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Iterable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct at_impl<LazyList> {
+ template <typename Xs, typename N>
+ static constexpr auto apply(Xs&& lcons, N const& n) {
+ return hana::drop_front(lcons, n).x;
+ }
+ };
+
+ namespace detail {
+ struct eval_tail {
+ template <typename Xs>
+ constexpr auto operator()(Xs const& lcons) const {
+ return hana::eval(lcons.xs);
+ }
+
+ constexpr auto operator()(lazy_nil_type const&) const {
+ return lazy_nil;
+ }
+ };
+ }
+
+ template <>
+ struct drop_front_impl<LazyList> {
+ template <typename Xs, typename N>
+ static constexpr auto apply(Xs&& lcons, N const&) {
+ return hana::iterate<N::value>(detail::eval_tail{}, lcons);
+ }
+ };
+
+ template <>
+ struct is_empty_impl<LazyList> {
+ template <typename Xs>
+ static constexpr auto apply(Xs const&)
+ { return hana::false_c; }
+
+ static constexpr auto apply(lazy_nil_type const&)
+ { return hana::true_c; }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // MonadPlus
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct prepend_impl<LazyList> {
+ template <typename Xs, typename X>
+ static constexpr auto apply(Xs xs, X x)
+ { return lazy_cons(x, hana::make_lazy(xs)); }
+ };
+
+ template <>
+ struct empty_impl<LazyList> {
+ static constexpr auto apply()
+ { return lazy_nil; }
+ };
+}}
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(!hana::is_empty(repeat(1)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::front(repeat(1)) == 1);
+ BOOST_HANA_CONSTEXPR_CHECK(hana::at(repeat(1), hana::size_c<10>) == 1);
+}
diff --git a/src/boost/libs/hana/example/misc/infinite_set.cpp b/src/boost/libs/hana/example/misc/infinite_set.cpp
new file mode 100644
index 000000000..6bccfd535
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/infinite_set.cpp
@@ -0,0 +1,321 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/and.hpp>
+#include <boost/hana/any_of.hpp>
+#include <boost/hana/flatten.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/fwd/ap.hpp>
+#include <boost/hana/fwd/equal.hpp>
+#include <boost/hana/fwd/find_if.hpp>
+#include <boost/hana/fwd/lift.hpp>
+#include <boost/hana/fwd/union.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/is_subset.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/transform.hpp>
+namespace hana = boost::hana;
+
+
+// A `Monad` for searching infinite sets in finite time.
+//
+// Taken from http://goo.gl/XJeDy8.
+struct infinite_set_tag { };
+
+template <typename Find>
+struct infinite_set {
+ Find find;
+ using hana_tag = infinite_set_tag;
+};
+
+template <typename Pred>
+constexpr infinite_set<Pred> make_infinite_set(Pred pred) {
+ return {pred};
+}
+
+template <typename X>
+constexpr auto singleton(X x) {
+ return make_infinite_set([=](auto /*p*/) { return x; });
+}
+
+template <typename X, typename Y>
+constexpr auto doubleton(X x, Y y) {
+ return make_infinite_set([=](auto p) {
+ return hana::if_(p(x), x, y);
+ });
+}
+
+namespace boost { namespace hana {
+ template <>
+ struct union_impl<infinite_set_tag> {
+ template <typename Xs, typename Ys>
+ static constexpr auto apply(Xs xs, Ys ys) {
+ return flatten(doubleton(xs, ys));
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct equal_impl<infinite_set_tag, infinite_set_tag> {
+ template <typename Xs, typename Ys>
+ static constexpr auto apply(Xs xs, Ys ys)
+ { return and_(is_subset(xs, ys), is_subset(ys, xs)); }
+ };
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Functor
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct transform_impl<infinite_set_tag> {
+ template <typename Set, typename F>
+ static constexpr auto apply(Set set, F f) {
+ return make_infinite_set([=](auto q) {
+ return f(set.find(compose(q, f)));
+ });
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Applicative
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct lift_impl<infinite_set_tag> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return singleton(x); }
+ };
+
+ template <>
+ struct ap_impl<infinite_set_tag> {
+ template <typename F, typename Set>
+ static constexpr auto apply(F fset, Set set) {
+ return flatten(transform(fset, partial(transform, set)));
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Monad
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct flatten_impl<infinite_set_tag> {
+ template <typename Set>
+ static constexpr auto apply(Set set) {
+ return make_infinite_set([=](auto p) {
+ return set.find([=](auto set) {
+ return any_of(set, p);
+ }).find(p);
+ });
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Searchable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct find_if_impl<infinite_set_tag> {
+ template <typename Set, typename Pred>
+ static constexpr auto apply(Set set, Pred p) {
+ auto x = set.find(p);
+ return if_(p(x), hana::just(x), hana::nothing);
+ }
+ };
+
+ template <>
+ struct any_of_impl<infinite_set_tag> {
+ template <typename Set, typename Pred>
+ static constexpr auto apply(Set set, Pred p) {
+ return p(set.find(p));
+ }
+ };
+}} // end namespace boost::hana
+
+//////////////////////////////////////////////////////////////////////////////
+// Tests
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/hana/any_of.hpp>
+#include <boost/hana/ap.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/flatten.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/is_subset.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/union.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+constexpr int n = i;
+
+template <int i>
+constexpr auto c = hana::int_c<i>;
+
+int main() {
+ auto f = [](auto n) { return n + hana::int_c<10>; };
+ auto g = [](auto n) { return n + hana::int_c<100>; };
+
+ // union_
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(singleton(c<0>), singleton(c<0>)),
+ singleton(c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(singleton(c<0>), singleton(c<1>)),
+ doubleton(c<0>, c<1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(singleton(c<0>), doubleton(c<0>, c<1>)),
+ doubleton(c<0>, c<1>)
+ ));
+ }
+
+ // Comparable
+ {
+ // equal
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(singleton(n<0>), singleton(n<0>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(singleton(n<0>), singleton(n<1>))));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(singleton(n<0>), doubleton(n<0>, n<0>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(singleton(n<0>), doubleton(n<0>, n<1>))));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(singleton(n<0>), doubleton(n<1>, n<1>))));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(doubleton(n<0>, n<1>), doubleton(n<0>, n<1>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(doubleton(n<0>, n<1>), doubleton(n<1>, n<0>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(doubleton(n<0>, n<1>), doubleton(n<0>, n<0>))));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(doubleton(n<0>, n<1>), doubleton(n<3>, n<4>))));
+ }
+ }
+
+ // Functor
+ {
+ // transform
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::transform(singleton(n<0>), f),
+ singleton(f(n<0>))
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::transform(doubleton(n<0>, n<1>), f),
+ doubleton(f(n<0>), f(n<1>))
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::transform(doubleton(n<0>, n<0>), f),
+ singleton(f(n<0>))
+ ));
+ }
+ }
+
+ // Applicative
+ {
+ // ap
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(singleton(f), singleton(c<0>)),
+ singleton(f(c<0>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(singleton(f), doubleton(c<0>, c<1>)),
+ doubleton(f(c<0>), f(c<1>))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(doubleton(f, g), singleton(c<0>)),
+ doubleton(f(c<0>), g(c<0>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(doubleton(f, g), doubleton(c<0>, c<1>)),
+ hana::union_(doubleton(f(c<0>), f(c<1>)),
+ doubleton(g(c<0>), g(c<1>)))
+ ));
+ }
+
+ // lift
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::lift<infinite_set_tag>(c<0>),
+ singleton(c<0>)
+ ));
+ }
+ }
+
+ // Monad
+ {
+ // flatten
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(singleton(singleton(c<0>))),
+ singleton(c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(singleton(doubleton(c<0>, c<1>))),
+ doubleton(c<0>, c<1>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(doubleton(singleton(c<0>), singleton(c<1>))),
+ doubleton(c<0>, c<1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(doubleton(doubleton(c<0>, c<1>), singleton(c<2>))),
+ hana::union_(doubleton(c<0>, c<1>), singleton(c<2>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(doubleton(singleton(c<0>), doubleton(c<1>, c<2>))),
+ hana::union_(doubleton(c<0>, c<1>), singleton(c<2>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(doubleton(doubleton(c<0>, c<1>), doubleton(c<2>, c<3>))),
+ hana::union_(doubleton(c<0>, c<1>), doubleton(c<2>, c<3>))
+ ));
+ }
+ }
+
+ // Searchable
+ {
+ // any_of
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::any_of(singleton(n<0>), hana::equal.to(n<0>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::any_of(singleton(n<0>), hana::equal.to(n<1>))));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::any_of(doubleton(n<0>, n<1>), hana::equal.to(n<0>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::any_of(doubleton(n<0>, n<1>), hana::equal.to(n<1>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::any_of(doubleton(n<0>, n<1>), hana::equal.to(n<2>))));
+ }
+
+ // find_if
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::find_if(singleton(c<0>), hana::equal.to(c<0>)) == hana::just(c<0>));
+ BOOST_HANA_CONSTANT_CHECK(hana::find_if(singleton(c<1>), hana::equal.to(c<0>)) == hana::nothing);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::find_if(doubleton(c<0>, c<1>), hana::equal.to(c<0>)) == hana::just(c<0>));
+ BOOST_HANA_CONSTANT_CHECK(hana::find_if(doubleton(c<0>, c<1>), hana::equal.to(c<1>)) == hana::just(c<1>));
+ BOOST_HANA_CONSTANT_CHECK(hana::find_if(doubleton(c<0>, c<1>), hana::equal.to(c<2>)) == hana::nothing);
+ }
+
+ // is_subset
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::is_subset(singleton(n<0>), singleton(n<0>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::is_subset(singleton(n<1>), singleton(n<0>))));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::is_subset(singleton(n<0>), doubleton(n<0>, n<1>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::is_subset(singleton(n<1>), doubleton(n<0>, n<1>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::is_subset(singleton(n<2>), doubleton(n<0>, n<1>))));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::is_subset(doubleton(n<0>, n<1>), doubleton(n<0>, n<1>)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::is_subset(doubleton(n<0>, n<2>), doubleton(n<0>, n<1>))));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::is_subset(doubleton(n<2>, n<3>), doubleton(n<0>, n<1>))));
+ }
+ }
+}
diff --git a/src/boost/libs/hana/example/misc/lambda_tuple.cpp b/src/boost/libs/hana/example/misc/lambda_tuple.cpp
new file mode 100644
index 000000000..d3bcbd191
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/lambda_tuple.cpp
@@ -0,0 +1,244 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/at.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/detail/variadic/at.hpp>
+#include <boost/hana/detail/variadic/drop_into.hpp>
+#include <boost/hana/detail/variadic/take.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/functional/on.hpp>
+#include <boost/hana/fwd/append.hpp>
+#include <boost/hana/fwd/at.hpp>
+#include <boost/hana/fwd/concat.hpp>
+#include <boost/hana/fwd/concept/sequence.hpp>
+#include <boost/hana/fwd/core/make.hpp>
+#include <boost/hana/fwd/drop_front.hpp>
+#include <boost/hana/fwd/empty.hpp>
+#include <boost/hana/fwd/front.hpp>
+#include <boost/hana/fwd/prepend.hpp>
+#include <boost/hana/fwd/take_front.hpp>
+#include <boost/hana/fwd/transform.hpp>
+#include <boost/hana/fwd/unpack.hpp>
+#include <boost/hana/fwd/zip_shortest_with.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/min.hpp>
+#include <boost/hana/minimum.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+// An interesting way of implementing tuple using lambda captures.
+
+struct lambda_tuple_tag { };
+
+template <typename Storage>
+struct lambda_tuple_t {
+ explicit constexpr lambda_tuple_t(Storage&& s)
+ : storage(std::move(s))
+ { }
+
+ using hana_tag = lambda_tuple_tag;
+ Storage storage;
+};
+
+auto lambda_tuple = [](auto ...xs) {
+ auto storage = [=](auto f) -> decltype(auto) { return f(xs...); };
+ return lambda_tuple_t<decltype(storage)>{std::move(storage)};
+};
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Foldable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct unpack_impl<lambda_tuple_tag> {
+ template <typename Xs, typename F>
+ static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
+ return static_cast<Xs&&>(xs).storage(static_cast<F&&>(f));
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Functor
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct transform_impl<lambda_tuple_tag> {
+ template <typename Xs, typename F>
+ static constexpr decltype(auto) apply(Xs&& xs, F f) {
+ return static_cast<Xs&&>(xs).storage(
+ [f(std::move(f))](auto&& ...xs) -> decltype(auto) {
+ return lambda_tuple(f(static_cast<decltype(xs)&&>(xs))...);
+ }
+ );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Iterable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct front_impl<lambda_tuple_tag> {
+ template <typename Xs>
+ static constexpr decltype(auto) apply(Xs&& xs) {
+ return static_cast<Xs&&>(xs).storage(
+ [](auto&& x, auto&& ...) -> decltype(auto) {
+ return id(static_cast<decltype(x)&&>(x));
+ }
+ );
+ }
+ };
+
+ template <>
+ struct is_empty_impl<lambda_tuple_tag> {
+ template <typename Xs>
+ static constexpr decltype(auto) apply(Xs&& xs) {
+ return static_cast<Xs&&>(xs).storage(
+ [](auto const& ...xs) -> decltype(auto) {
+ return hana::bool_c<sizeof...(xs) == 0>;
+ }
+ );
+ }
+ };
+
+ template <>
+ struct at_impl<lambda_tuple_tag> {
+ template <typename Xs, typename Index>
+ static constexpr decltype(auto) apply(Xs&& xs, Index const&) {
+ return static_cast<Xs&&>(xs).storage(
+ detail::variadic::at<Index::value>
+ );
+ }
+ };
+
+ template <>
+ struct drop_front_impl<lambda_tuple_tag> {
+ template <typename Xs, typename N>
+ static constexpr decltype(auto) apply(Xs&& xs, N const& n) {
+ auto m = min(n, length(xs));
+ return static_cast<Xs&&>(xs).storage(
+ detail::variadic::drop_into<hana::value(m)>(lambda_tuple)
+ );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // MonadPlus
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct concat_impl<lambda_tuple_tag> {
+ template <typename Xs, typename Ys>
+ static constexpr decltype(auto) apply(Xs&& xs, Ys&& ys) {
+ return static_cast<Xs&&>(xs).storage(
+ [ys(static_cast<Ys&&>(ys))](auto&& ...xs) -> decltype(auto) {
+ return std::move(ys).storage(
+ // We can't initialize the capture with perfect
+ // forwarding since that's not supported by the
+ // language.
+ [=](auto&& ...ys) -> decltype(auto) {
+ return lambda_tuple(
+ std::move(xs)...,
+ static_cast<decltype(ys)&&>(ys)...
+ );
+ }
+ );
+ }
+ );
+ }
+ };
+
+ template <>
+ struct prepend_impl<lambda_tuple_tag> {
+ template <typename Xs, typename X>
+ static constexpr decltype(auto) apply(Xs&& xs, X&& x) {
+ return static_cast<Xs&&>(xs).storage(
+ [x(static_cast<X&&>(x))](auto&& ...xs) -> decltype(auto) {
+ return lambda_tuple(
+ std::move(x),
+ static_cast<decltype(xs)&&>(xs)...
+ );
+ }
+ );
+ }
+ };
+
+ template <>
+ struct append_impl<lambda_tuple_tag> {
+ template <typename Xs, typename X>
+ static constexpr decltype(auto) apply(Xs&& xs, X&& x) {
+ return static_cast<Xs&&>(xs).storage(
+ [x(static_cast<X&&>(x))](auto&& ...xs) -> decltype(auto) {
+ return lambda_tuple(
+ static_cast<decltype(xs)&&>(xs)...,
+ std::move(x)
+ );
+ }
+ );
+ }
+ };
+
+ template <>
+ struct empty_impl<lambda_tuple_tag> {
+ static BOOST_HANA_CONSTEXPR_LAMBDA decltype(auto) apply() {
+ return lambda_tuple();
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sequence
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct Sequence<lambda_tuple_tag> {
+ static constexpr bool value = true;
+ };
+
+ template <>
+ struct take_front_impl<lambda_tuple_tag> {
+ template <typename Xs, typename N>
+ static constexpr decltype(auto) apply(Xs&& xs, N const& n) {
+ auto m = min(n, length(xs));
+ return static_cast<Xs&&>(xs).storage(
+ detail::variadic::take<decltype(m)::value>
+ )(lambda_tuple);
+ }
+ };
+
+ template <>
+ struct zip_shortest_with_impl<lambda_tuple_tag> {
+ template <typename F, typename ...Xss>
+ static constexpr auto apply(F f, Xss ...tuples) {
+ auto go = [=](auto index, auto ...nothing) {
+ return always(f)(nothing...)(at(tuples, index)...);
+ };
+ auto zip_length = minimum(lambda_tuple(length(tuples)...));
+ return unpack(make_range(size_c<0>, zip_length),
+ on(lambda_tuple, go)
+ );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // make
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct make_impl<lambda_tuple_tag> {
+ template <typename ...Xs>
+ static constexpr decltype(auto) apply(Xs&& ...xs) {
+ return lambda_tuple(static_cast<Xs&&>(xs)...);
+ }
+ };
+}} // end namespace boost::hana
+
+
+int main() {
+ auto xs = lambda_tuple(1, '2', 3.3);
+ static_assert(!decltype(hana::is_empty(xs))::value, "");
+}
diff --git a/src/boost/libs/hana/example/misc/nth.cpp b/src/boost/libs/hana/example/misc/nth.cpp
new file mode 100644
index 000000000..ffbdf1eb8
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/nth.cpp
@@ -0,0 +1,45 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/functional/arg.hpp>
+
+#include <cstddef>
+#include <utility>
+namespace hana = boost::hana;
+
+
+constexpr int to_int(char c)
+{ return static_cast<int>(c) - 48; }
+
+template <std::size_t N>
+constexpr long long parse(const char (&arr)[N]) {
+ long long number = 0, base = 1;
+ for (std::size_t i = 0; i < N; ++i) {
+ number += to_int(arr[N - 1 - i]) * base;
+ base *= 10;
+ }
+ return number;
+}
+
+template <char ...c>
+struct pick {
+ static constexpr unsigned long n = parse<sizeof...(c)>({c...});
+
+ template <typename ...T>
+ constexpr auto operator()(T&& ...args) const
+ { return hana::arg<n>(std::forward<T>(args)...); }
+};
+
+template <char ...c> constexpr pick<c...> operator"" _st() { return {}; }
+template <char ...c> constexpr pick<c...> operator"" _nd() { return {}; }
+template <char ...c> constexpr pick<c...> operator"" _rd() { return {}; }
+template <char ...c> constexpr pick<c...> operator"" _th() { return {}; }
+
+
+static_assert(1_st(1, '2', 3.3, 444) == 1, "");
+static_assert(2_nd(1, '2', 3.3, 444) == '2', "");
+static_assert(3_rd(1, '2', 3.3, 444) == 3.3, "");
+static_assert(4_th(1, '2', 3.3, 444) == 444, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/misc/overload_linearly.cpp b/src/boost/libs/hana/example/misc/overload_linearly.cpp
new file mode 100644
index 000000000..a41174a27
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/overload_linearly.cpp
@@ -0,0 +1,42 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+// We have an utility in the Functional module that does pretty much the
+// same, but is more compile-time efficient. It is still interesting to
+// see this implemented with sequences and the SFINAE combinator.
+
+auto overload_linearly = [](auto ...candidates) {
+ return [=](auto ...args) {
+ auto maybe_function = hana::find_if(hana::make_tuple(candidates...), [=](auto f) {
+ return hana::is_valid(f)(args...);
+ });
+ auto result = hana::transform(maybe_function, [=](auto f) {
+ return f(args...);
+ });
+ return result;
+ };
+};
+
+int main() {
+ auto f = ::overload_linearly(
+ [](std::string s) { return s + "abcd"; },
+ [](int i) { return i + 1; },
+ [](double f) { return f + 2; }
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(f(1) == hana::just(1 + 1));
+ BOOST_HANA_RUNTIME_CHECK(f(2.3) == hana::just(static_cast<int>(2.3) + 1));
+}
diff --git a/src/boost/libs/hana/example/misc/printf.cpp b/src/boost/libs/hana/example/misc/printf.cpp
new file mode 100644
index 000000000..01f5a9abf
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/printf.cpp
@@ -0,0 +1,66 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/adjust_if.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/core/is_a.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/filter.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/prepend.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/sum.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <cstdio>
+namespace hana = boost::hana;
+
+
+constexpr auto formats = hana::make_map(
+ hana::make_pair(hana::type_c<int>, hana::string_c<'%', 'd'>),
+ hana::make_pair(hana::type_c<float>, hana::string_c<'%', 'f'>),
+ hana::make_pair(hana::type_c<char const*>, hana::string_c<'%', 's'>)
+);
+
+template <typename ...Tokens>
+constexpr auto format(Tokens ...tokens_) {
+ auto tokens = hana::make_tuple(tokens_...);
+
+ // If you don't care about constexpr-ness of `format`, you can use
+ // this lambda instead of `compose(partial(...), typeid_)`:
+ //
+ // [](auto token) {
+ // return formats[typeid_(token)];
+ // }
+ auto format_string_tokens = hana::adjust_if(tokens,
+ hana::compose(hana::not_, hana::is_a<hana::string_tag>),
+ hana::compose(hana::partial(hana::at_key, formats), hana::typeid_)
+ );
+
+ auto format_string = hana::sum<hana::string_tag>(format_string_tokens);
+ auto variables = hana::filter(tokens, hana::compose(hana::not_, hana::is_a<hana::string_tag>));
+ return hana::prepend(variables, format_string);
+}
+
+int main() {
+ int a = 1;
+ float b = 1.3;
+ char const* c = "abcdef";
+
+ auto args = format(
+ BOOST_HANA_STRING("first="), a
+ , BOOST_HANA_STRING(" second="), b
+ , BOOST_HANA_STRING(" third="), c
+ );
+
+ hana::unpack(args, [](auto fmt, auto ...args) {
+ std::printf(hana::to<char const*>(fmt), args...);
+ });
+}
diff --git a/src/boost/libs/hana/example/misc/ref_tuple.cpp b/src/boost/libs/hana/example/misc/ref_tuple.cpp
new file mode 100644
index 000000000..488925800
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/ref_tuple.cpp
@@ -0,0 +1,92 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <cstddef>
+#include <functional>
+namespace hana = boost::hana;
+
+
+// A tuple that holds reference_wrappers to its elements, instead of the
+// elements themselves.
+
+struct RefTuple { };
+
+template <typename ...T>
+struct ref_tuple;
+
+template <typename ...T>
+struct ref_tuple<T&...> {
+ hana::tuple<std::reference_wrapper<T>...> storage_;
+};
+
+
+namespace boost { namespace hana {
+ template <typename ...T>
+ struct tag_of<ref_tuple<T...>> {
+ using type = RefTuple;
+ };
+
+ template <>
+ struct make_impl<RefTuple> {
+ template <typename ...T>
+ static constexpr auto apply(T& ...t) {
+ return ref_tuple<T&...>{{std::ref(t)...}};
+ }
+ };
+
+ template <>
+ struct at_impl<RefTuple> {
+ template <typename Xs, typename N>
+ static constexpr decltype(auto) apply(Xs&& xs, N const& n) {
+ return hana::at(static_cast<Xs&&>(xs).storage_, n).get();
+ }
+ };
+
+ template <>
+ struct is_empty_impl<RefTuple> {
+ template <typename Xs>
+ static constexpr auto apply(Xs const& xs) {
+ return hana::is_empty(xs.storage_);
+ }
+ };
+
+ template <>
+ struct drop_front_impl<RefTuple> {
+ template <std::size_t n, typename T, typename ...U, std::size_t ...i>
+ static constexpr auto helper(ref_tuple<T, U...> xs, std::index_sequence<i...>) {
+ return hana::make<RefTuple>(hana::at_c<n + i>(xs.storage_).get()...);
+ }
+
+ template <typename ...T, typename N>
+ static constexpr auto apply(ref_tuple<T...> xs, N const&) {
+ return helper<N::value>(xs, std::make_index_sequence<(
+ N::value < sizeof...(T) ? sizeof...(T) - N::value : 0
+ )>{});
+ }
+ };
+}} // end namespace boost::hana
+
+
+int main() {
+ int i = 0, j = 1, k = 2;
+
+ ref_tuple<int&, int&, int&> refs = hana::make<RefTuple>(i, j, k);
+ hana::at_c<0>(refs) = 3;
+ BOOST_HANA_RUNTIME_CHECK(i == 3);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(refs)));
+
+ ref_tuple<int&, int&> tail = hana::drop_front(refs);
+ hana::at_c<0>(tail) = 4;
+ BOOST_HANA_RUNTIME_CHECK(j == 4);
+}
diff --git a/src/boost/libs/hana/example/misc/restricted_function.cpp b/src/boost/libs/hana/example/misc/restricted_function.cpp
new file mode 100644
index 000000000..6a290489b
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/restricted_function.cpp
@@ -0,0 +1,143 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/cartesian_product.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/demux.hpp>
+#include <boost/hana/fuse.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/or.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+// A function that can have an arbitrary compile-time set of values as a domain
+// and co-domain. This is most likely purely of theoretical interest, but it
+// allows creating functions with very complex domains and co-domains that are
+// computed at compile-time.
+
+struct Function { };
+
+template <typename Domain, typename Codomain, typename F>
+struct function_type {
+ using hana_tag = Function;
+
+ Domain domain_;
+ Codomain codomain_;
+ F f_;
+
+ template <typename X>
+ constexpr auto operator()(X x) const {
+ BOOST_HANA_CONSTANT_ASSERT(boost::hana::contains(domain_, x));
+ return f_(x);
+ }
+};
+
+template <typename ...F, typename ...G>
+constexpr auto operator==(function_type<F...> f, function_type<G...> g)
+{ return hana::equal(f, g); }
+
+template <typename ...F, typename ...G>
+constexpr auto operator!=(function_type<F...> f, function_type<G...> g)
+{ return hana::not_equal(f, g); }
+
+
+auto function = [](auto domain, auto codomain) {
+ return [=](auto definition) {
+ return function_type<decltype(domain), decltype(codomain), decltype(definition)>{
+ domain, codomain, definition
+ };
+ };
+};
+
+template <typename Function>
+constexpr auto domain(Function f)
+{ return f.domain_; }
+
+template <typename Function>
+constexpr auto codomain(Function f)
+{ return f.codomain_; }
+
+template <typename Function>
+constexpr auto range(Function f) {
+ // We must convert to hana::tuple first because hana::set is not a Functor
+ return hana::to_set(hana::transform(hana::to_tuple(domain(f)), f));
+}
+
+template <typename P, typename Q>
+constexpr auto implies(P p, Q q) {
+ return hana::or_(hana::not_(p), q);
+}
+
+template <typename F>
+constexpr auto is_injective(F f) {
+ auto dom = hana::to_tuple(domain(f));
+ auto pairs = hana::cartesian_product(hana::make_tuple(dom, dom));
+ return hana::all_of(pairs, hana::fuse([&](auto x, auto y) {
+ return implies(hana::not_equal(x, y), hana::not_equal(f(x), f(y)));
+ }));
+}
+
+template <typename F>
+constexpr auto is_onto(F f) {
+ return codomain(f) == range(f);
+}
+
+namespace boost { namespace hana {
+ template <>
+ struct equal_impl<Function, Function> {
+ template <typename F, typename G>
+ static constexpr auto apply(F f, G g) {
+ return domain(f) == domain(g) &&
+ hana::all_of(domain(f), hana::demux(hana::equal)(f, g));
+ }
+ };
+}} // end namespace boost::hana
+
+int main() {
+ auto f = function(hana::make_set(1_c, 2_c, 3_c), hana::make_set(1_c, 2_c, 3_c, 4_c, 5_c, 6_c))(
+ [](auto x) { return x + 1_c; }
+ );
+
+ auto g = function(hana::make_set(1_c, 2_c, 3_c), hana::make_set(2_c, 3_c, 4_c))(
+ [](auto x) { return x + 1_c; }
+ );
+
+ auto h = function(hana::make_set(1_c, 2_c, 3_c), hana::make_set(0_c, 1_c, 2_c))(
+ [](auto x) { return x - 1_c; }
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(f == g);
+ BOOST_HANA_CONSTANT_CHECK(f != h);
+ BOOST_HANA_CONSTANT_CHECK(f(1_c) == 2_c);
+
+ BOOST_HANA_CONSTANT_CHECK(range(f) == hana::make_set(4_c, 3_c, 2_c));
+ BOOST_HANA_CONSTANT_CHECK(range(g) == hana::make_set(2_c, 3_c, 4_c));
+ BOOST_HANA_CONSTANT_CHECK(range(h) == hana::make_set(0_c, 1_c, 2_c));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(is_onto(f)));
+ BOOST_HANA_CONSTANT_CHECK(is_onto(g));
+ BOOST_HANA_CONSTANT_CHECK(is_onto(h));
+
+ auto even = function(hana::make_set(1_c, 2_c, 3_c), hana::make_set(hana::true_c, hana::false_c))(
+ [](auto x) { return x % 2_c == 0_c; }
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(is_injective(f));
+ BOOST_HANA_CONSTANT_CHECK(is_injective(g));
+ BOOST_HANA_CONSTANT_CHECK(is_injective(h));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(is_injective(even)));
+}
diff --git a/src/boost/libs/hana/example/misc/tree.cpp b/src/boost/libs/hana/example/misc/tree.cpp
new file mode 100644
index 000000000..c74a3e2c0
--- /dev/null
+++ b/src/boost/libs/hana/example/misc/tree.cpp
@@ -0,0 +1,144 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/and.hpp>
+#include <boost/hana/ap.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concat.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/flatten.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/sum.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct tree_tag;
+
+template <typename X, typename Subforest>
+struct node {
+ X value;
+ Subforest subforest;
+
+ using hana_tag = tree_tag;
+};
+
+constexpr auto make_forest = hana::make_tuple;
+
+template <typename X, typename Subforest>
+constexpr auto make_node(X x, Subforest subforest) {
+ return node<X, Subforest>{x, subforest};
+}
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct equal_impl<tree_tag, tree_tag> {
+ template <typename Node1, typename Node2>
+ static constexpr auto apply(Node1 node1, Node2 node2) {
+ return hana::and_(
+ hana::equal(node1.value, node2.value),
+ hana::equal(node1.subforest, node2.subforest)
+ );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Functor
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct transform_impl<tree_tag> {
+ template <typename Node, typename F>
+ static constexpr auto apply(Node node, F f) {
+ return make_node(
+ f(node.value),
+ hana::transform(node.subforest, [=](auto subtree) {
+ return hana::transform(subtree, f);
+ })
+ );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Applicative
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct lift_impl<tree_tag> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return make_node(x, make_forest()); }
+ };
+
+ template <>
+ struct ap_impl<tree_tag> {
+ template <typename F, typename X>
+ static constexpr auto apply(F f, X x) {
+ return make_node(
+ f.value(x.value),
+ hana::concat(
+ hana::transform(x.subforest, [=](auto subtree) {
+ return hana::transform(subtree, f.value);
+ }),
+ hana::transform(f.subforest, [=](auto subtree) {
+ return hana::ap(subtree, x);
+ })
+ )
+ );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Monad
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct flatten_impl<tree_tag> {
+ template <typename Node>
+ static constexpr auto apply(Node node) {
+ return make_node(
+ node.value.value,
+ hana::concat(
+ node.value.subforest,
+ hana::transform(node.subforest, hana::flatten)
+ )
+ );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Foldable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct fold_left_impl<tree_tag> {
+ template <typename Node, typename State, typename F>
+ static constexpr auto apply(Node node, State state, F f) {
+ return hana::fold_left(node.subforest, f(state, node.value),
+ [=](auto state, auto subtree) {
+ return hana::fold_left(subtree, state, f);
+ });
+ }
+ };
+}}
+
+int main() {
+ constexpr auto tree = make_node(1, make_forest(
+ make_node(2, make_forest()),
+ make_node(3, make_forest()),
+ make_node(4, make_forest())
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::sum<>(tree) == 10);
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::transform(tree, [](int i) { return i + 1; }),
+ make_node(2, make_forest(
+ make_node(3, make_forest()),
+ make_node(4, make_forest()),
+ make_node(5, make_forest())
+ ))
+ ));
+}
diff --git a/src/boost/libs/hana/example/mod.cpp b/src/boost/libs/hana/example/mod.cpp
new file mode 100644
index 000000000..cc0785199
--- /dev/null
+++ b/src/boost/libs/hana/example/mod.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/mod.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::mod(hana::int_c<6>, hana::int_c<4>) == hana::int_c<2>);
+BOOST_HANA_CONSTANT_CHECK(hana::mod(hana::int_c<-6>, hana::int_c<4>) == hana::int_c<-2>);
+static_assert(hana::mod(6, 4) == 2, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/monadic_compose.cpp b/src/boost/libs/hana/example/monadic_compose.cpp
new file mode 100644
index 000000000..9c95ee7f7
--- /dev/null
+++ b/src/boost/libs/hana/example/monadic_compose.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/monadic_compose.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto block = [](auto ...types) {
+ return [=](auto x) {
+ return hana::if_(hana::contains(hana::make_tuple(types...), hana::typeid_(x)),
+ hana::nothing,
+ hana::just(x)
+ );
+ };
+ };
+
+ BOOST_HANA_CONSTEXPR_LAMBDA auto f = block(hana::type_c<double>);
+ BOOST_HANA_CONSTEXPR_LAMBDA auto g = block(hana::type_c<int>);
+ BOOST_HANA_CONSTEXPR_LAMBDA auto h = hana::monadic_compose(g, f);
+ BOOST_HANA_CONSTANT_CHECK(h(1) == hana::nothing); // fails inside g; 1 has type int
+ BOOST_HANA_CONSTANT_CHECK(h(1.2) == hana::nothing); // fails inside f; 1.2 has type double
+ BOOST_HANA_CONSTEXPR_CHECK(h('x') == hana::just('x')); // ok; 'x' has type char
+}
diff --git a/src/boost/libs/hana/example/monadic_fold_left.cpp b/src/boost/libs/hana/example/monadic_fold_left.cpp
new file mode 100644
index 000000000..734c055e0
--- /dev/null
+++ b/src/boost/libs/hana/example/monadic_fold_left.cpp
@@ -0,0 +1,72 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/monadic_fold_left.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/traits.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+auto builtin_common_t = hana::sfinae([](auto&& t, auto&& u) -> hana::type<
+ std::decay_t<decltype(true ? hana::traits::declval(t) : hana::traits::declval(u))>
+> { return {}; });
+
+template <typename ...T>
+struct common_type { };
+
+template <typename T, typename U>
+struct common_type<T, U>
+ : std::conditional_t<std::is_same<std::decay_t<T>, T>{} &&
+ std::is_same<std::decay_t<U>, U>{},
+ decltype(builtin_common_t(hana::type_c<T>, hana::type_c<U>)),
+ common_type<std::decay_t<T>, std::decay_t<U>>
+ >
+{ };
+
+template <typename T1, typename ...Tn>
+struct common_type<T1, Tn...>
+ : decltype(hana::monadic_fold_left<hana::optional_tag>(
+ hana::tuple_t<Tn...>,
+ hana::type_c<std::decay_t<T1>>,
+ hana::sfinae(hana::metafunction<common_type>)
+ ))
+{ };
+
+template <typename ...Ts>
+using common_type_t = typename common_type<Ts...>::type;
+
+BOOST_HANA_CONSTANT_CHECK(
+ builtin_common_t(hana::type_c<int>, hana::type_c<float>)
+ ==
+ hana::just(hana::type_c<float>)
+);
+
+static_assert(std::is_same<
+ common_type_t<char, short, char, short>,
+ int
+>{}, "");
+
+static_assert(std::is_same<
+ common_type_t<char, double, short, char, short, double>,
+ double
+>{}, "");
+
+static_assert(std::is_same<
+ common_type_t<char, short, float, short>,
+ float
+>{}, "");
+
+static_assert(
+ hana::sfinae(hana::metafunction<common_type>)(
+ hana::type_c<int>, hana::type_c<int>, hana::type_c<int*>
+ ) == hana::nothing
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/monadic_fold_right.cpp b/src/boost/libs/hana/example/monadic_fold_right.cpp
new file mode 100644
index 000000000..255962407
--- /dev/null
+++ b/src/boost/libs/hana/example/monadic_fold_right.cpp
@@ -0,0 +1,61 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/div.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/monadic_fold_right.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto safe_div = [](auto x, auto y) {
+ return hana::eval_if(y == hana::int_c<0>,
+ hana::make_lazy(hana::nothing),
+ [=](auto _) {
+ return hana::just(_(x) / y);
+ }
+ );
+ };
+
+ // with an initial state
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::monadic_fold_right<hana::optional_tag>(
+ hana::tuple_c<int, 1000, 8, 4>, hana::int_c<2>, safe_div
+ )
+ ==
+ hana::just(hana::int_c<1000> / (hana::int_c<8> / (hana::int_c<4> / hana::int_c<2>)))
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::monadic_fold_right<hana::optional_tag>(
+ hana::tuple_c<int, 1000, 8, 4>, hana::int_c<0>, safe_div
+ )
+ ==
+ hana::nothing
+ );
+
+ // without an initial state
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::monadic_fold_right<hana::optional_tag>(
+ hana::tuple_c<int, 1000, 8, 4, 2>, safe_div
+ )
+ ==
+ hana::just(hana::int_c<1000> / (hana::int_c<8> / (hana::int_c<4> / hana::int_c<2>)))
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::monadic_fold_right<hana::optional_tag>(
+ hana::tuple_c<int, 1000, 8, 4, 0>, safe_div
+ )
+ ==
+ hana::nothing
+ );
+}
diff --git a/src/boost/libs/hana/example/mult.cpp b/src/boost/libs/hana/example/mult.cpp
new file mode 100644
index 000000000..22522df1b
--- /dev/null
+++ b/src/boost/libs/hana/example/mult.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/mult.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::mult(hana::int_c<3>, hana::int_c<5>) == hana::int_c<15>);
+static_assert(hana::mult(4, 2) == 8, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/negate.cpp b/src/boost/libs/hana/example/negate.cpp
new file mode 100644
index 000000000..1a52322ba
--- /dev/null
+++ b/src/boost/libs/hana/example/negate.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/negate.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::negate(hana::int_c<3>) == hana::int_c<-3>);
+ static_assert(hana::negate(2) == -2, "");
+}
diff --git a/src/boost/libs/hana/example/none.cpp b/src/boost/libs/hana/example/none.cpp
new file mode 100644
index 000000000..38aa012f7
--- /dev/null
+++ b/src/boost/libs/hana/example/none.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/none.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::none(hana::make_tuple(false, hana::false_c, hana::false_c)), "");
+static_assert(!hana::none(hana::make_tuple(false, hana::false_c, true)), "");
+BOOST_HANA_CONSTANT_CHECK(!hana::none(hana::make_tuple(false, hana::false_c, hana::true_c)));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/none_of.cpp b/src/boost/libs/hana/example/none_of.cpp
new file mode 100644
index 000000000..17d24a5b7
--- /dev/null
+++ b/src/boost/libs/hana/example/none_of.cpp
@@ -0,0 +1,35 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/none_of.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto is_odd = [](auto x) {
+ return x % 2_c != 0_c;
+};
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::none_of(hana::make_tuple(2_c, 4_c), is_odd));
+ BOOST_HANA_CONSTEXPR_CHECK(!hana::none_of(hana::make_tuple(1, 2), is_odd));
+
+ BOOST_HANA_CONSTANT_CHECK(
+ !hana::none_of(hana::make_tuple(hana::type_c<void>, hana::type_c<char&>), hana::trait<std::is_void>)
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::none_of(hana::make_tuple(hana::type_c<void>, hana::type_c<char&>), hana::trait<std::is_integral>)
+ );
+}
diff --git a/src/boost/libs/hana/example/not.cpp b/src/boost/libs/hana/example/not.cpp
new file mode 100644
index 000000000..119372c67
--- /dev/null
+++ b/src/boost/libs/hana/example/not.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::true_c) == hana::false_c);
+static_assert(hana::not_(false) == true, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/not_equal.cpp b/src/boost/libs/hana/example/not_equal.cpp
new file mode 100644
index 000000000..5750bf84b
--- /dev/null
+++ b/src/boost/libs/hana/example/not_equal.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ static_assert(hana::not_equal(hana::make_tuple(1, 2), hana::make_tuple(3)), "");
+ static_assert(hana::not_equal('x', 'y'), "");
+ BOOST_HANA_CONSTANT_CHECK(hana::not_equal(hana::make_tuple(1, 2), 'y'));
+
+ static_assert(hana::all_of(hana::make_tuple(1, 2, 3), hana::not_equal.to(5)), "");
+}
diff --git a/src/boost/libs/hana/example/one.cpp b/src/boost/libs/hana/example/one.cpp
new file mode 100644
index 000000000..536300a38
--- /dev/null
+++ b/src/boost/libs/hana/example/one.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/one.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::one<hana::integral_constant_tag<int>>() == hana::int_c<1>);
+static_assert(hana::one<long>() == 1l, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/applicative.complex.cpp b/src/boost/libs/hana/example/optional/applicative.complex.cpp
new file mode 100644
index 000000000..f8eb84a73
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/applicative.complex.cpp
@@ -0,0 +1,50 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/ap.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+template <char op>
+constexpr auto function = hana::nothing;
+
+template <>
+BOOST_HANA_CONSTEXPR_LAMBDA auto function<'+'> = hana::just([](auto x, auto y) {
+ return x + y;
+});
+
+template <>
+BOOST_HANA_CONSTEXPR_LAMBDA auto function<'-'> = hana::just([](auto x, auto y) {
+ return x - y;
+});
+
+// and so on...
+
+template <char n>
+constexpr auto digit = hana::if_(hana::bool_c<(n >= '0' && n <= '9')>,
+ hana::just(static_cast<int>(n - 48)),
+ hana::nothing
+);
+
+template <char x, char op, char y>
+BOOST_HANA_CONSTEXPR_LAMBDA auto evaluate = hana::ap(function<op>, digit<x>, digit<y>);
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(evaluate<'1', '+', '2'> == hana::just(1 + 2));
+ BOOST_HANA_CONSTEXPR_CHECK(evaluate<'4', '-', '2'> == hana::just(4 - 2));
+
+ BOOST_HANA_CONSTANT_CHECK(evaluate<'?', '+', '2'> == hana::nothing);
+ BOOST_HANA_CONSTANT_CHECK(evaluate<'1', '?', '2'> == hana::nothing);
+ BOOST_HANA_CONSTANT_CHECK(evaluate<'1', '+', '?'> == hana::nothing);
+ BOOST_HANA_CONSTANT_CHECK(evaluate<'?', '?', '?'> == hana::nothing);
+
+ static_assert(hana::lift<hana::optional_tag>(123) == hana::just(123), "");
+}
diff --git a/src/boost/libs/hana/example/optional/applicative.cpp b/src/boost/libs/hana/example/optional/applicative.cpp
new file mode 100644
index 000000000..3c67c30e9
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/applicative.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/ap.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+constexpr char next(char c) { return c + 1; }
+
+static_assert(hana::ap(hana::just(next), hana::just('x')) == hana::just('y'), "");
+BOOST_HANA_CONSTANT_CHECK(hana::ap(hana::nothing, hana::just('x')) == hana::nothing);
+BOOST_HANA_CONSTANT_CHECK(hana::ap(hana::just(next), hana::nothing) == hana::nothing);
+BOOST_HANA_CONSTANT_CHECK(hana::ap(hana::nothing, hana::nothing) == hana::nothing);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/comparable.cpp b/src/boost/libs/hana/example/optional/comparable.cpp
new file mode 100644
index 000000000..ba192b852
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/comparable.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::nothing == hana::nothing);
+static_assert(hana::just('x') == hana::just('x'), "");
+static_assert(hana::just('x') != hana::just('y'), "");
+BOOST_HANA_CONSTANT_CHECK(hana::just('x') != hana::nothing);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/foldable.cpp b/src/boost/libs/hana/example/optional/foldable.cpp
new file mode 100644
index 000000000..21fc920c6
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/foldable.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/plus.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::fold_right(hana::nothing, 1, hana::plus) == 1, "");
+static_assert(hana::fold_right(hana::just(4), 1, hana::plus) == 5, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/functor.cpp b/src/boost/libs/hana/example/optional/functor.cpp
new file mode 100644
index 000000000..6faf54a0f
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/functor.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/transform.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::transform(hana::nothing, hana::_ + 1) == hana::nothing);
+static_assert(hana::transform(hana::just(1), hana::_ + 1) == hana::just(2), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/is_just.cpp b/src/boost/libs/hana/example/optional/is_just.cpp
new file mode 100644
index 000000000..7c7216ace
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/is_just.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK( hana::is_just(hana::just('x')));
+BOOST_HANA_CONSTANT_CHECK( hana::is_just(hana::just(hana::nothing)));
+BOOST_HANA_CONSTANT_CHECK(!hana::is_just(hana::nothing));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/is_nothing.cpp b/src/boost/libs/hana/example/optional/is_nothing.cpp
new file mode 100644
index 000000000..ffde02df5
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/is_nothing.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK( hana::is_nothing(hana::nothing));
+BOOST_HANA_CONSTANT_CHECK(!hana::is_nothing(hana::just('x')));
+BOOST_HANA_CONSTANT_CHECK(!hana::is_nothing(hana::just(hana::nothing)));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/just.cpp b/src/boost/libs/hana/example/optional/just.cpp
new file mode 100644
index 000000000..bf7d32042
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/just.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto just_x = hana::just('x');
+BOOST_HANA_CONSTANT_CHECK(hana::is_just(just_x));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/make.cpp b/src/boost/libs/hana/example/optional/make.cpp
new file mode 100644
index 000000000..fd0034a76
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/make.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto x = hana::make<hana::optional_tag>();
+ BOOST_HANA_CONSTANT_CHECK(x == hana::make_optional());
+ BOOST_HANA_CONSTANT_CHECK(hana::is_nothing(x));
+
+ constexpr auto just_x = hana::make<hana::optional_tag>('x');
+ static_assert(just_x == hana::make_optional('x'), "");
+ BOOST_HANA_CONSTANT_CHECK(hana::is_just(just_x));
+}
diff --git a/src/boost/libs/hana/example/optional/maybe.cpp b/src/boost/libs/hana/example/optional/maybe.cpp
new file mode 100644
index 000000000..5e90cb652
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/maybe.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::maybe('x', hana::_ + 1, hana::just(1)) == 2, "");
+static_assert(hana::maybe('x', hana::_ + 1, hana::nothing) == 'x', "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/monad.cpp b/src/boost/libs/hana/example/optional/monad.cpp
new file mode 100644
index 000000000..2be7821a6
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/monad.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/flatten.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto inc = [](auto x) {
+ return hana::just(x + 1);
+ };
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::chain(hana::just(1), inc) == hana::just(2));
+ BOOST_HANA_CONSTANT_CHECK(hana::chain(hana::nothing, inc) == hana::nothing);
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::flatten(hana::just(hana::just(2))) == hana::just(2));
+}
diff --git a/src/boost/libs/hana/example/optional/monad_plus.cpp b/src/boost/libs/hana/example/optional/monad_plus.cpp
new file mode 100644
index 000000000..d32681526
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/monad_plus.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concat.hpp>
+#include <boost/hana/empty.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::concat(hana::nothing, hana::just('x')) == hana::just('x'), "");
+BOOST_HANA_CONSTANT_CHECK(hana::concat(hana::nothing, hana::nothing) == hana::nothing);
+static_assert(hana::concat(hana::just('x'), hana::just('y')) == hana::just('x'), "");
+BOOST_HANA_CONSTANT_CHECK(hana::empty<hana::optional_tag>() == hana::nothing);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/nothing.cpp b/src/boost/libs/hana/example/optional/nothing.cpp
new file mode 100644
index 000000000..81f109e90
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/nothing.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto x = hana::nothing;
+BOOST_HANA_CONSTANT_CHECK(hana::is_nothing(x));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/orderable.cpp b/src/boost/libs/hana/example/optional/orderable.cpp
new file mode 100644
index 000000000..b8cb7e110
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/orderable.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::nothing < hana::just(3));
+BOOST_HANA_CONSTANT_CHECK(hana::just(0) > hana::nothing);
+static_assert(hana::just(1) < hana::just(3), "");
+static_assert(hana::just(3) > hana::just(2), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/searchable.cpp b/src/boost/libs/hana/example/optional/searchable.cpp
new file mode 100644
index 000000000..e95d451af
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/searchable.cpp
@@ -0,0 +1,27 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+auto odd = [](auto x) {
+ return x % hana::int_c<2> != hana::int_c<0>;
+};
+
+BOOST_HANA_CONSTANT_CHECK(hana::find_if(hana::just(hana::int_c<3>), odd) == hana::just(hana::int_c<3>));
+BOOST_HANA_CONSTANT_CHECK(hana::find_if(hana::just(hana::int_c<2>), odd) == hana::nothing);
+BOOST_HANA_CONSTANT_CHECK(hana::find_if(hana::nothing, odd) == hana::nothing);
+
+BOOST_HANA_CONSTANT_CHECK(hana::all_of(hana::just(hana::int_c<3>), odd));
+BOOST_HANA_CONSTANT_CHECK(hana::all_of(hana::nothing, odd));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/sfinae.cpp b/src/boost/libs/hana/example/optional/sfinae.cpp
new file mode 100644
index 000000000..1fe9adf0e
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/sfinae.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto incr = [](auto x) -> decltype(x + 1) {
+ return x + 1;
+ };
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::sfinae(incr)(1) == hana::just(2));
+
+ struct invalid { };
+ BOOST_HANA_CONSTANT_CHECK(hana::sfinae(incr)(invalid{}) == hana::nothing);
+}
diff --git a/src/boost/libs/hana/example/optional/sfinae_friendly_metafunctions.cpp b/src/boost/libs/hana/example/optional/sfinae_friendly_metafunctions.cpp
new file mode 100644
index 000000000..392154b39
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/sfinae_friendly_metafunctions.cpp
@@ -0,0 +1,44 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/traits.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+using void_t = void;
+
+template <typename T, typename = void>
+struct has_type : std::false_type { };
+
+template <typename T>
+struct has_type<T, void_t<typename T::type>>
+ : std::true_type
+{ };
+
+auto common_type_impl = hana::sfinae([](auto t, auto u) -> hana::type<
+ decltype(true ? hana::traits::declval(t) : hana::traits::declval(u))
+> { return {}; });
+
+template <typename T, typename U>
+using common_type = decltype(common_type_impl(hana::type_c<T>, hana::type_c<U>));
+
+BOOST_HANA_CONSTANT_CHECK(
+ common_type_impl(hana::type_c<int>, hana::type_c<float>)
+ ==
+ hana::just(hana::type_c<float>)
+);
+
+static_assert(!has_type<common_type<int, int*>>{}, "");
+static_assert(std::is_same<common_type<int, float>::type, float>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/optional/value.cpp b/src/boost/libs/hana/example/optional/value.cpp
new file mode 100644
index 000000000..adbb7aac5
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/value.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ static_assert(hana::just('x').value() == 'x', "");
+ BOOST_HANA_CONSTANT_CHECK(*hana::just(hana::type_c<int>) == hana::type_c<int>);
+ BOOST_HANA_RUNTIME_CHECK(hana::just(std::string{"abcd"})->size() == 4);
+
+ // hana::nothing.value(); // compile-time error
+}
diff --git a/src/boost/libs/hana/example/optional/value_or.cpp b/src/boost/libs/hana/example/optional/value_or.cpp
new file mode 100644
index 000000000..1d0b22960
--- /dev/null
+++ b/src/boost/libs/hana/example/optional/value_or.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::just(1).value_or('x') == 1, "");
+static_assert(hana::nothing.value_or('x') == 'x', "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/or.cpp b/src/boost/libs/hana/example/or.cpp
new file mode 100644
index 000000000..567aebcfe
--- /dev/null
+++ b/src/boost/libs/hana/example/or.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/or.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::or_(hana::false_c, hana::false_c, hana::true_c));
+BOOST_HANA_CONSTANT_CHECK(!hana::or_(hana::false_c, hana::false_c, hana::false_c));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/ordering.cpp b/src/boost/libs/hana/example/ordering.cpp
new file mode 100644
index 000000000..9f8c18ed6
--- /dev/null
+++ b/src/boost/libs/hana/example/ordering.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ordering.hpp>
+#include <boost/hana/sort.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto sorted = hana::sort.by(hana::ordering(hana::sizeof_),
+ hana::tuple_t<char[3], char[1], char[2], char[15]>
+);
+
+BOOST_HANA_CONSTANT_CHECK(sorted == hana::tuple_t<char[1], char[2], char[3], char[15]>);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/overview.cpp b/src/boost/libs/hana/example/overview.cpp
new file mode 100644
index 000000000..37b802f3b
--- /dev/null
+++ b/src/boost/libs/hana/example/overview.cpp
@@ -0,0 +1,59 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+// Make sure assert always triggers an assertion
+#ifdef NDEBUG
+# undef NDEBUG
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Important: Keep this file in sync with the Overview in the README
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/hana.hpp>
+#include <cassert>
+#include <string>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+
+int main() {
+ // Sequences capable of holding heterogeneous objects, and algorithms
+ // to manipulate them.
+ auto animals = hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});
+ auto names = hana::transform(animals, [](auto a) {
+ return a.name;
+ });
+ assert(hana::reverse(names) == hana::make_tuple("Snoopy", "Garfield", "Nemo"));
+
+ // No compile-time information is lost: even if `animals` can't be a
+ // constant expression because it contains strings, its length is constexpr.
+ static_assert(hana::length(animals) == 3u, "");
+
+ // Computations on types can be performed with the same syntax as that of
+ // normal C++. Believe it or not, everything is done at compile-time.
+ auto animal_types = hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Cat&>, hana::type_c<Dog*>);
+ auto animal_ptrs = hana::filter(animal_types, [](auto a) {
+ return hana::traits::is_pointer(a);
+ });
+ static_assert(animal_ptrs == hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Dog*>), "");
+
+ // And many other goodies to make your life easier, including:
+ // 1. Access to elements in a tuple with a sane syntax.
+ static_assert(animal_ptrs[0_c] == hana::type_c<Fish*>, "");
+ static_assert(animal_ptrs[1_c] == hana::type_c<Dog*>, "");
+
+ // 2. Unroll loops at compile-time without hassle.
+ std::string s;
+ hana::int_c<10>.times([&]{ s += "x"; });
+ // equivalent to s += "x"; s += "x"; ... s += "x";
+
+ // 3. Easily check whether an expression is valid.
+ // This is usually achieved with complex SFINAE-based tricks.
+ auto has_name = hana::is_valid([](auto&& x) -> decltype((void)x.name) { });
+ static_assert(has_name(animals[0_c]), "");
+ static_assert(!has_name(1), "");
+}
diff --git a/src/boost/libs/hana/example/pair/comparable.cpp b/src/boost/libs/hana/example/pair/comparable.cpp
new file mode 100644
index 000000000..63610e2fc
--- /dev/null
+++ b/src/boost/libs/hana/example/pair/comparable.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/pair.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::make_pair(1, 'x') == hana::make_pair(1, 'x'), "");
+static_assert(hana::make_pair(2, 'x') != hana::make_pair(1, 'x'), "");
+static_assert(hana::make_pair(1, 'y') != hana::make_pair(1, 'x'), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/pair/foldable.cpp b/src/boost/libs/hana/example/pair/foldable.cpp
new file mode 100644
index 000000000..e9e92c74d
--- /dev/null
+++ b/src/boost/libs/hana/example/pair/foldable.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/plus.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::fold_left(hana::make_pair(1, 3), 0, hana::plus) == 4, "");
+static_assert(hana::fold_right(hana::make_pair(1, 3), 0, hana::minus) == -2, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/pair/make.cpp b/src/boost/libs/hana/example/pair/make.cpp
new file mode 100644
index 000000000..f13e3de99
--- /dev/null
+++ b/src/boost/libs/hana/example/pair/make.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::first(hana::make<hana::pair_tag>(1, 'x')) == 1, "");
+static_assert(hana::second(hana::make<hana::pair_tag>(1, 'x')) == 'x', "");
+static_assert(hana::make_pair(1, 'x') == hana::make<hana::pair_tag>(1, 'x'), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/pair/orderable.cpp b/src/boost/libs/hana/example/pair/orderable.cpp
new file mode 100644
index 000000000..14c87e5b1
--- /dev/null
+++ b/src/boost/libs/hana/example/pair/orderable.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/less.hpp>
+#include <boost/hana/pair.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::make_pair(1, 'x') < hana::make_pair(1, 'y'), "");
+static_assert(hana::make_pair(1, 'x') < hana::make_pair(10, 'x'), "");
+static_assert(hana::make_pair(1, 'y') < hana::make_pair(10, 'x'), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/pair/product.cpp b/src/boost/libs/hana/example/pair/product.cpp
new file mode 100644
index 000000000..c48db2cef
--- /dev/null
+++ b/src/boost/libs/hana/example/pair/product.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::first(hana::make_pair(1, 'x')) == 1, "");
+static_assert(hana::second(hana::make_pair(1, 'x')) == 'x', "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/partition.cpp b/src/boost/libs/hana/example/partition.cpp
new file mode 100644
index 000000000..708c4eaa4
--- /dev/null
+++ b/src/boost/libs/hana/example/partition.cpp
@@ -0,0 +1,52 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/partition.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::partition(hana::tuple_c<int, 1, 2, 3, 4, 5, 6, 7>, [](auto x) {
+ return x % hana::int_c<2> != hana::int_c<0>;
+ })
+ ==
+ hana::make_pair(
+ hana::tuple_c<int, 1, 3, 5, 7>,
+ hana::tuple_c<int, 2, 4, 6>
+ )
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::partition(hana::tuple_t<void, int, float, char, double>, hana::trait<std::is_floating_point>)
+ ==
+ hana::make_pair(
+ hana::tuple_t<float, double>,
+ hana::tuple_t<void, int, char>
+ )
+);
+
+
+// partition.by is syntactic sugar
+BOOST_HANA_CONSTANT_CHECK(
+ hana::partition.by(hana::trait<std::is_floating_point>,
+ hana::tuple_t<void, int, float, char, double>)
+ ==
+ hana::make_pair(
+ hana::tuple_t<float, double>,
+ hana::tuple_t<void, int, char>
+ )
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/permutations.cpp b/src/boost/libs/hana/example/permutations.cpp
new file mode 100644
index 000000000..413c24c66
--- /dev/null
+++ b/src/boost/libs/hana/example/permutations.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/functional/curry.hpp>
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto is_permutation_of = hana::curry<2>([](auto xs, auto perm) {
+ return hana::contains(hana::permutations(xs), perm);
+});
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::all_of(
+ hana::make_tuple(
+ hana::make_tuple('1', 2, 3.0),
+ hana::make_tuple('1', 3.0, 2),
+ hana::make_tuple(2, '1', 3.0),
+ hana::make_tuple(2, 3.0, '1'),
+ hana::make_tuple(3.0, '1', 2),
+ hana::make_tuple(3.0, 2, '1')
+ ),
+ is_permutation_of(hana::make_tuple('1', 2, 3.0))
+ )
+ );
+}
diff --git a/src/boost/libs/hana/example/plus.cpp b/src/boost/libs/hana/example/plus.cpp
new file mode 100644
index 000000000..7de42fbd9
--- /dev/null
+++ b/src/boost/libs/hana/example/plus.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/plus.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::plus(hana::int_c<3>, hana::int_c<5>) == hana::int_c<8>);
+static_assert(hana::plus(1, 2) == 3, "");
+static_assert(hana::plus(1.5f, 2.4) == 3.9, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/power.cpp b/src/boost/libs/hana/example/power.cpp
new file mode 100644
index 000000000..d869977fa
--- /dev/null
+++ b/src/boost/libs/hana/example/power.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/power.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::power(hana::int_c<3>, hana::int_c<2>) == hana::int_c<3 * 3>);
+static_assert(hana::power(2, hana::int_c<4>) == 16, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/prefix.cpp b/src/boost/libs/hana/example/prefix.cpp
new file mode 100644
index 000000000..0db9eb5d3
--- /dev/null
+++ b/src/boost/libs/hana/example/prefix.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/prefix.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::prefix(hana::make_tuple("dog"s, "car"s, "house"s), "my"s)
+ ==
+ hana::make_tuple("my", "dog", "my", "car", "my", "house")
+ );
+}
diff --git a/src/boost/libs/hana/example/prepend.cpp b/src/boost/libs/hana/example/prepend.cpp
new file mode 100644
index 000000000..3ca19eb77
--- /dev/null
+++ b/src/boost/libs/hana/example/prepend.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/prepend.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::prepend(hana::make_tuple(), 1) == hana::make_tuple(1), "");
+static_assert(hana::prepend(hana::make_tuple('2', 3.3), 1) == hana::make_tuple(1, '2', 3.3), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/product.cpp b/src/boost/libs/hana/example/product.cpp
new file mode 100644
index 000000000..52cb4bc1b
--- /dev/null
+++ b/src/boost/libs/hana/example/product.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/product.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::product<>(hana::make_range(hana::int_c<1>, hana::int_c<6>)) == hana::int_c<1 * 2 * 3 * 4 * 5>
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::product<>(hana::make_tuple(1, hana::int_c<3>, hana::long_c<-5>, 9)) == 1 * 3 * -5 * 9
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::product<unsigned long>(hana::make_tuple(2ul, 3ul)) == 6ul
+ );
+}
diff --git a/src/boost/libs/hana/example/product/comparable.cpp b/src/boost/libs/hana/example/product/comparable.cpp
new file mode 100644
index 000000000..d9b3a43ff
--- /dev/null
+++ b/src/boost/libs/hana/example/product/comparable.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/pair.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(hana::make_pair(1, "234"s) == hana::make_pair(1ll, "234"s));
+ static_assert(hana::make_pair('x', 2) != hana::make_pair('y', 2), "");
+}
diff --git a/src/boost/libs/hana/example/product/make.cpp b/src/boost/libs/hana/example/product/make.cpp
new file mode 100644
index 000000000..5c85f8396
--- /dev/null
+++ b/src/boost/libs/hana/example/product/make.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::first(hana::make<hana::pair_tag>(1, 'x')) == 1, "");
+static_assert(hana::second(hana::make<hana::pair_tag>(1, 'x')) == 'x', "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/range/comparable.cpp b/src/boost/libs/hana/example/range/comparable.cpp
new file mode 100644
index 000000000..a27014cc4
--- /dev/null
+++ b/src/boost/libs/hana/example/range/comparable.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+// empty ranges are equal
+BOOST_HANA_CONSTANT_CHECK(hana::make_range(hana::int_c<6>, hana::int_c<6>) == hana::make_range(hana::int_c<0>, hana::int_c<0>));
+
+// otherwise, ranges are equal if and only if they span the same interval
+BOOST_HANA_CONSTANT_CHECK(hana::make_range(hana::int_c<2>, hana::int_c<5>) == hana::make_range(hana::int_c<2>, hana::int_c<5>));
+BOOST_HANA_CONSTANT_CHECK(hana::make_range(hana::int_c<0>, hana::int_c<3>) != hana::make_range(hana::int_c<-1>, hana::int_c<3>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/range/foldable.cpp b/src/boost/libs/hana/example/range/foldable.cpp
new file mode 100644
index 000000000..e294b543f
--- /dev/null
+++ b/src/boost/libs/hana/example/range/foldable.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::fold_left(hana::make_range(hana::int_c<0>, hana::int_c<4>), hana::int_c<0>, hana::plus) == hana::int_c<6>
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::unpack(hana::make_range(hana::int_c<-2>, hana::int_c<2>), hana::make_tuple) ==
+ hana::make_tuple(hana::int_c<-2>, hana::int_c<-1>, hana::int_c<0>, hana::int_c<1>)
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/range/iterable.cpp b/src/boost/libs/hana/example/range/iterable.cpp
new file mode 100644
index 000000000..f696ebc61
--- /dev/null
+++ b/src/boost/libs/hana/example/range/iterable.cpp
@@ -0,0 +1,24 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto r = hana::make_range(hana::int_c<0>, hana::int_c<1000>);
+BOOST_HANA_CONSTANT_CHECK(hana::front(r) == hana::int_c<0>);
+BOOST_HANA_CONSTANT_CHECK(hana::back(r) == hana::int_c<999>);
+BOOST_HANA_CONSTANT_CHECK(hana::drop_front(r) == hana::make_range(hana::int_c<1>, hana::int_c<1000>));
+BOOST_HANA_CONSTANT_CHECK(!hana::is_empty(r));
+BOOST_HANA_CONSTANT_CHECK(hana::is_empty(hana::make_range(hana::int_c<3>, hana::int_c<3>)));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/range/make.cpp b/src/boost/libs/hana/example/range/make.cpp
new file mode 100644
index 000000000..0c151054f
--- /dev/null
+++ b/src/boost/libs/hana/example/range/make.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto irange = hana::make<hana::range_tag>(hana::int_c<0>, hana::int_c<10>); // [0, 10) int
+BOOST_HANA_CONSTANT_CHECK(irange == hana::make<hana::range_tag>(hana::int_c<0>, hana::int_c<10>));
+
+constexpr auto lrange = hana::make<hana::range_tag>(hana::int_c<0>, hana::long_c<10>); // [0, 10) long
+BOOST_HANA_CONSTANT_CHECK(lrange == hana::make<hana::range_tag>(hana::long_c<0>, hana::long_c<10>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/range/range_c.cpp b/src/boost/libs/hana/example/range/range_c.cpp
new file mode 100644
index 000000000..9b7da7aee
--- /dev/null
+++ b/src/boost/libs/hana/example/range/range_c.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::front(hana::range_c<int, 0, 5>) == hana::int_c<0>);
+BOOST_HANA_CONSTANT_CHECK(hana::back(hana::range_c<unsigned long, 0, 5>) == hana::ulong_c<4>);
+BOOST_HANA_CONSTANT_CHECK(hana::drop_front(hana::range_c<int, 0, 5>) == hana::make_range(hana::int_c<1>, hana::int_c<5>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/range/searchable.cpp b/src/boost/libs/hana/example/range/searchable.cpp
new file mode 100644
index 000000000..4ffb5205d
--- /dev/null
+++ b/src/boost/libs/hana/example/range/searchable.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::find(hana::make_range(hana::int_c<1>, hana::int_c<25>), hana::int_c<10>) == hana::just(hana::int_c<10>));
+BOOST_HANA_CONSTANT_CHECK(hana::find(hana::make_range(hana::int_c<1>, hana::int_c<25>), hana::int_c<200>) == hana::nothing);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/remove.cpp b/src/boost/libs/hana/example/remove.cpp
new file mode 100644
index 000000000..80f96f780
--- /dev/null
+++ b/src/boost/libs/hana/example/remove.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/remove.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::remove(hana::tuple_t<int, char, float>, hana::type_c<char>) == hana::tuple_t<int, float>);
+BOOST_HANA_CONSTANT_CHECK(hana::remove(hana::just(hana::type_c<int>), hana::type_c<char>) == hana::just(hana::type_c<int>));
+BOOST_HANA_CONSTANT_CHECK(hana::remove(hana::just(hana::type_c<int>), hana::type_c<int>) == hana::nothing);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/remove_at.cpp b/src/boost/libs/hana/example/remove_at.cpp
new file mode 100644
index 000000000..b0dc9555a
--- /dev/null
+++ b/src/boost/libs/hana/example/remove_at.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/remove_at.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3u);
+
+static_assert(hana::remove_at(xs, hana::size_c<2>) == hana::make_tuple(0, '1', 3u), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/remove_at_c.cpp b/src/boost/libs/hana/example/remove_at_c.cpp
new file mode 100644
index 000000000..e62117961
--- /dev/null
+++ b/src/boost/libs/hana/example/remove_at_c.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/remove_at.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3u);
+
+static_assert(hana::remove_at_c<2>(xs) == hana::make_tuple(0, '1', 3u), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/remove_if.cpp b/src/boost/libs/hana/example/remove_if.cpp
new file mode 100644
index 000000000..83295bb31
--- /dev/null
+++ b/src/boost/libs/hana/example/remove_if.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/remove_if.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// First get the type of the object, and then call the trait on it.
+constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::typeid_);
+
+static_assert(hana::remove_if(hana::make_tuple(1, 2.0, 3, 4.0), is_integral) == hana::make_tuple(2.0, 4.0), "");
+static_assert(hana::remove_if(hana::just(3.0), is_integral) == hana::just(3.0), "");
+BOOST_HANA_CONSTANT_CHECK(hana::remove_if(hana::just(3), is_integral) == hana::nothing);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/remove_range.cpp b/src/boost/libs/hana/example/remove_range.cpp
new file mode 100644
index 000000000..dc813f0f6
--- /dev/null
+++ b/src/boost/libs/hana/example/remove_range.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/remove_range.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3u, 4, 5.5);
+
+static_assert(hana::remove_range(xs, hana::size_c<2>, hana::size_c<4>) == hana::make_tuple(0, '1', 4, 5.5), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/remove_range_c.cpp b/src/boost/libs/hana/example/remove_range_c.cpp
new file mode 100644
index 000000000..742eb9acc
--- /dev/null
+++ b/src/boost/libs/hana/example/remove_range_c.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/remove_range.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3u, 4, 5.5);
+
+static_assert(hana::remove_range_c<2, 4>(xs) == hana::make_tuple(0, '1', 4, 5.5), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/repeat.cpp b/src/boost/libs/hana/example/repeat.cpp
new file mode 100644
index 000000000..444ac1c84
--- /dev/null
+++ b/src/boost/libs/hana/example/repeat.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/repeat.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ std::string s;
+ for (char letter = 'a'; letter <= 'g'; ++letter)
+ hana::repeat(hana::int_c<3>, [&] { s += letter; });
+
+ BOOST_HANA_RUNTIME_CHECK(s == "aaabbbcccdddeeefffggg");
+}
diff --git a/src/boost/libs/hana/example/replace.cpp b/src/boost/libs/hana/example/replace.cpp
new file mode 100644
index 000000000..9d450a2a3
--- /dev/null
+++ b/src/boost/libs/hana/example/replace.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/replace.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(
+ hana::replace(hana::make_tuple(1, 1, 1, 2, 3, 1, 4, 5), 1, 0)
+ ==
+ hana::make_tuple(0, 0, 0, 2, 3, 0, 4, 5)
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/replace_if.cpp b/src/boost/libs/hana/example/replace_if.cpp
new file mode 100644
index 000000000..6f10c473a
--- /dev/null
+++ b/src/boost/libs/hana/example/replace_if.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/replace_if.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto negative = [](auto x) {
+ return x < 0;
+};
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::replace_if(hana::make_tuple(-3, -2, -1, 0, 1, 2, 3), negative, 0)
+ ==
+ hana::make_tuple(0, 0, 0, 0, 1, 2, 3)
+ );
+}
diff --git a/src/boost/libs/hana/example/replicate.cpp b/src/boost/libs/hana/example/replicate.cpp
new file mode 100644
index 000000000..df9880b6a
--- /dev/null
+++ b/src/boost/libs/hana/example/replicate.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/replicate.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::replicate<hana::tuple_tag>('x', hana::size_c<2>) == hana::make_tuple('x', 'x'), "");
+
+// Of course, there can't be more than one element in an `optional`.
+static_assert(hana::replicate<hana::optional_tag>('x', hana::size_c<2>) == hana::just('x'), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/reverse.cpp b/src/boost/libs/hana/example/reverse.cpp
new file mode 100644
index 000000000..91d3db53d
--- /dev/null
+++ b/src/boost/libs/hana/example/reverse.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/reverse.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::reverse(hana::make_tuple(1, '2', 3.3)) == hana::make_tuple(3.3, '2', 1), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/reverse_fold.cpp b/src/boost/libs/hana/example/reverse_fold.cpp
new file mode 100644
index 000000000..96fd77935
--- /dev/null
+++ b/src/boost/libs/hana/example/reverse_fold.cpp
@@ -0,0 +1,38 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/reverse_fold.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+#include <string>
+namespace hana = boost::hana;
+
+
+auto to_string = [](auto x) {
+ std::ostringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+int main() {
+ auto f = [=](std::string s, auto element) {
+ return "f(" + s + ", " + to_string(element) + ")";
+ };
+
+ // With an initial state
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::reverse_fold(hana::make_tuple(1, '2', 3.0, 4), "5", f)
+ ==
+ "f(f(f(f(5, 4), 3), 2), 1)"
+ );
+
+ // Without an initial state
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::reverse_fold(hana::make_tuple(1, '2', 3.0, 4, "5"), f)
+ ==
+ "f(f(f(f(5, 4), 3), 2), 1)"
+ );
+}
diff --git a/src/boost/libs/hana/example/scan_left.cpp b/src/boost/libs/hana/example/scan_left.cpp
new file mode 100644
index 000000000..0e176ac13
--- /dev/null
+++ b/src/boost/libs/hana/example/scan_left.cpp
@@ -0,0 +1,39 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/scan_left.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+namespace hana = boost::hana;
+
+
+auto to_string = [](auto x) {
+ std::ostringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+auto f = [](auto state, auto element) {
+ return "f(" + to_string(state) + ", " + to_string(element) + ")";
+};
+
+int main() {
+ // with initial state
+ BOOST_HANA_RUNTIME_CHECK(hana::scan_left(hana::make_tuple(2, "3", '4'), 1, f) == hana::make_tuple(
+ 1,
+ "f(1, 2)",
+ "f(f(1, 2), 3)",
+ "f(f(f(1, 2), 3), 4)"
+ ));
+
+ // without initial state
+ BOOST_HANA_RUNTIME_CHECK(hana::scan_left(hana::make_tuple(1, "2", '3'), f) == hana::make_tuple(
+ 1,
+ "f(1, 2)",
+ "f(f(1, 2), 3)"
+ ));
+}
diff --git a/src/boost/libs/hana/example/scan_right.cpp b/src/boost/libs/hana/example/scan_right.cpp
new file mode 100644
index 000000000..42e04d39f
--- /dev/null
+++ b/src/boost/libs/hana/example/scan_right.cpp
@@ -0,0 +1,39 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/scan_right.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+namespace hana = boost::hana;
+
+
+auto to_string = [](auto x) {
+ std::ostringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+auto f = [](auto element, auto state) {
+ return "f(" + to_string(element) + ", " + to_string(state) + ")";
+};
+
+int main() {
+ // with initial state
+ BOOST_HANA_RUNTIME_CHECK(hana::scan_right(hana::make_tuple(1, "2", '3'), 4, f) == hana::make_tuple(
+ "f(1, f(2, f(3, 4)))",
+ "f(2, f(3, 4))",
+ "f(3, 4)",
+ 4
+ ));
+
+ // without initial state
+ BOOST_HANA_RUNTIME_CHECK(hana::scan_right(hana::make_tuple(1, "2", '3'), f) == hana::make_tuple(
+ "f(1, f(2, 3))",
+ "f(2, 3)",
+ '3'
+ ));
+}
diff --git a/src/boost/libs/hana/example/second.cpp b/src/boost/libs/hana/example/second.cpp
new file mode 100644
index 000000000..310c886a7
--- /dev/null
+++ b/src/boost/libs/hana/example/second.cpp
@@ -0,0 +1,12 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/second.hpp>
+#include <boost/hana/pair.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::second(hana::make_pair(1, 'x')) == 'x', "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/sequence/applicative.cpp b/src/boost/libs/hana/example/sequence/applicative.cpp
new file mode 100644
index 000000000..c46ffcea8
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/applicative.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/ap.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/functional/flip.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <tuple>
+namespace hana = boost::hana;
+
+
+static_assert(hana::lift<hana::tuple_tag>('x') == hana::make_tuple('x'), "");
+static_assert(hana::equal(hana::lift<hana::ext::std::tuple_tag>('x'), std::make_tuple('x')), "");
+
+constexpr auto f = hana::make_pair;
+constexpr auto g = hana::flip(hana::make_pair);
+static_assert(
+ hana::ap(hana::make_tuple(f, g), hana::make_tuple(1, 2, 3), hana::make_tuple('a', 'b'))
+ ==
+ hana::make_tuple(
+ f(1, 'a'), f(1, 'b'), f(2, 'a'), f(2, 'b'), f(3, 'a'), f(3, 'b'),
+ g(1, 'a'), g(1, 'b'), g(2, 'a'), g(2, 'b'), g(3, 'a'), g(3, 'b')
+ )
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/sequence/comparable.cpp b/src/boost/libs/hana/example/sequence/comparable.cpp
new file mode 100644
index 000000000..5888a653a
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/comparable.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::make_tuple(1, 2, 3) == hana::make_tuple(1, 2, 3), "");
+BOOST_HANA_CONSTANT_CHECK(hana::make_tuple(1, 2, 3) != hana::make_tuple(1, 2, 3, 4));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/sequence/foldable.cpp b/src/boost/libs/hana/example/sequence/foldable.cpp
new file mode 100644
index 000000000..cdef35f17
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/foldable.cpp
@@ -0,0 +1,27 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+namespace hana = boost::hana;
+
+
+auto to_string = [](auto x) {
+ std::ostringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+auto show = [](auto x, auto y) {
+ return "(" + to_string(x) + " + " + to_string(y) + ")";
+};
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::fold_left(hana::make_tuple(2, "3", '4'), "1", show) == "(((1 + 2) + 3) + 4)"
+ );
+}
diff --git a/src/boost/libs/hana/example/sequence/functor.cpp b/src/boost/libs/hana/example/sequence/functor.cpp
new file mode 100644
index 000000000..0b26e6474
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/functor.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+#include <string>
+namespace hana = boost::hana;
+
+
+auto to_string = [](auto x) {
+ std::ostringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::transform(hana::make_tuple(1, '2', "345", std::string{"67"}), to_string) ==
+ hana::make_tuple("1", "2", "345", "67")
+ );
+}
diff --git a/src/boost/libs/hana/example/sequence/iterable.cpp b/src/boost/libs/hana/example/sequence/iterable.cpp
new file mode 100644
index 000000000..5a9a87944
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/iterable.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::front(hana::make_tuple(1, '2', 3.3)) == 1, "");
+static_assert(hana::drop_front(hana::make_tuple(1, '2', 3.3)) == hana::make_tuple('2', 3.3), "");
+BOOST_HANA_CONSTANT_CHECK(!hana::is_empty(hana::make_tuple(1, '2', 3.3)));
+BOOST_HANA_CONSTANT_CHECK(hana::is_empty(hana::make_tuple()));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/sequence/make.cpp b/src/boost/libs/hana/example/sequence/make.cpp
new file mode 100644
index 000000000..658e4a194
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/make.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::make<hana::tuple_tag>() == hana::make_tuple());
+static_assert(hana::make<hana::tuple_tag>(1, '2', 3.3) == hana::make_tuple(1, '2', 3.3), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/sequence/monad.ints.cpp b/src/boost/libs/hana/example/sequence/monad.ints.cpp
new file mode 100644
index 000000000..3dccdb8a9
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/monad.ints.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/flatten.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(
+ hana::flatten(hana::make_tuple(
+ hana::make_tuple(1, 2),
+ hana::make_tuple(3, 4),
+ hana::make_tuple(hana::make_tuple(5, 6))
+ ))
+ == hana::make_tuple(1, 2, 3, 4, hana::make_tuple(5, 6))
+, "");
+
+
+int main() { }
diff --git a/src/boost/libs/hana/example/sequence/monad.types.cpp b/src/boost/libs/hana/example/sequence/monad.types.cpp
new file mode 100644
index 000000000..27ea46da8
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/monad.types.cpp
@@ -0,0 +1,67 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/traits.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+// Using the `tuple` Monad, we generate all the possible combinations of
+// cv-qualifiers and reference qualifiers. Then, we use the `optional`
+// Monad to make sure that our generic function can be called with
+// arguments of any of those types.
+
+// cv_qualifiers : type -> tuple(type)
+auto cv_qualifiers = [](auto t) {
+ return hana::make_tuple(
+ t,
+ hana::traits::add_const(t),
+ hana::traits::add_volatile(t),
+ hana::traits::add_volatile(hana::traits::add_const(t))
+ );
+};
+
+// ref_qualifiers : type -> tuple(type)
+auto ref_qualifiers = [](auto t) {
+ return hana::make_tuple(
+ hana::traits::add_lvalue_reference(t),
+ hana::traits::add_rvalue_reference(t)
+ );
+};
+
+auto possible_args = cv_qualifiers(hana::type_c<int>) | ref_qualifiers;
+
+BOOST_HANA_CONSTANT_CHECK(
+ possible_args == hana::make_tuple(
+ hana::type_c<int&>,
+ hana::type_c<int&&>,
+ hana::type_c<int const&>,
+ hana::type_c<int const&&>,
+ hana::type_c<int volatile&>,
+ hana::type_c<int volatile&&>,
+ hana::type_c<int const volatile&>,
+ hana::type_c<int const volatile&&>
+ )
+);
+
+struct some_function {
+ template <typename T>
+ void operator()(T&&) const { }
+};
+
+int main() {
+ hana::for_each(possible_args, [](auto t) {
+ using T = typename decltype(t)::type;
+ static_assert(decltype(hana::is_valid(some_function{})(std::declval<T>())){},
+ "some_function should be callable with any type of argument");
+ });
+}
diff --git a/src/boost/libs/hana/example/sequence/monad_plus.cpp b/src/boost/libs/hana/example/sequence/monad_plus.cpp
new file mode 100644
index 000000000..ba2f89a3f
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/monad_plus.cpp
@@ -0,0 +1,27 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/append.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concat.hpp>
+#include <boost/hana/empty.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::string_literals;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::empty<hana::tuple_tag>() == hana::make_tuple());
+
+static_assert(hana::append(hana::make_tuple(1, '2', 3.3), nullptr)
+ == hana::make_tuple(1, '2', 3.3, nullptr), "");
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::concat(hana::make_tuple(1, '2', 3.3), hana::make_tuple("abcdef"s)) ==
+ hana::make_tuple(1, '2', 3.3, "abcdef"s)
+ );
+}
diff --git a/src/boost/libs/hana/example/sequence/orderable.cpp b/src/boost/libs/hana/example/sequence/orderable.cpp
new file mode 100644
index 000000000..00003587d
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/orderable.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/less.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::make_tuple(1, 2, 3) < hana::make_tuple(2, 3, 4), "");
+static_assert(hana::make_tuple(1, 2, 3) < hana::make_tuple(1, 2, 3, 4), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/sequence/searchable.cpp b/src/boost/libs/hana/example/sequence/searchable.cpp
new file mode 100644
index 000000000..568592bfd
--- /dev/null
+++ b/src/boost/libs/hana/example/sequence/searchable.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/core/is_a.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::string_literals;
+
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::find_if(hana::make_tuple(1, '2', 3.3, "abc"s), hana::is_a<std::string>) == hana::just("abc"s)
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(
+ "abc"s ^hana::in^ hana::make_tuple(1, '2', 3.3, "abc"s)
+ );
+}
diff --git a/src/boost/libs/hana/example/set/comparable.cpp b/src/boost/libs/hana/example/set/comparable.cpp
new file mode 100644
index 000000000..4bc2ecadb
--- /dev/null
+++ b/src/boost/libs/hana/example/set/comparable.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_set(hana::int_c<0>, hana::type_c<char>, hana::int_c<1>)
+ ==
+ hana::make_set(hana::int_c<1>, hana::int_c<0>, hana::type_c<char>)
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_set(hana::int_c<0>, hana::type_c<char>)
+ !=
+ hana::make_set(hana::int_c<1>)
+ );
+}
diff --git a/src/boost/libs/hana/example/set/difference.cpp b/src/boost/libs/hana/example/set/difference.cpp
new file mode 100644
index 000000000..e91a9222d
--- /dev/null
+++ b/src/boost/libs/hana/example/set/difference.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/difference.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_set(hana::int_c<1>, hana::int_c<2>, hana::type_c<int>, hana::int_c<3>);
+constexpr auto ys = hana::make_set(hana::int_c<3>, hana::type_c<void>, hana::type_c<int>);
+
+BOOST_HANA_CONSTANT_CHECK(hana::difference(xs, ys) == hana::make_set(hana::int_c<1>, hana::int_c<2>));
+BOOST_HANA_CONSTANT_CHECK(hana::difference(ys, xs) == hana::make_set(hana::type_c<void>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/set/erase_key.cpp b/src/boost/libs/hana/example/set/erase_key.cpp
new file mode 100644
index 000000000..d3bc3cd56
--- /dev/null
+++ b/src/boost/libs/hana/example/set/erase_key.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/erase_key.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto xs = hana::make_set(hana::int_c<0>, hana::type_c<int>, hana::type_c<void>);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::erase_key(xs, hana::type_c<int>) == hana::make_set(hana::int_c<0>, hana::type_c<void>));
+ BOOST_HANA_CONSTANT_CHECK(hana::erase_key(xs, hana::type_c<char>) == xs);
+}
diff --git a/src/boost/libs/hana/example/set/foldable.cpp b/src/boost/libs/hana/example/set/foldable.cpp
new file mode 100644
index 000000000..0f17415eb
--- /dev/null
+++ b/src/boost/libs/hana/example/set/foldable.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/maximum.hpp>
+#include <boost/hana/minimum.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/sum.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto xs = hana::make_set(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>);
+ static_assert(hana::minimum(xs) == hana::int_c<0>, "");
+ static_assert(hana::maximum(xs) == hana::int_c<2>, "");
+ static_assert(hana::sum<>(xs) == hana::int_c<3>, "");
+}
diff --git a/src/boost/libs/hana/example/set/insert.cpp b/src/boost/libs/hana/example/set/insert.cpp
new file mode 100644
index 000000000..47fffc760
--- /dev/null
+++ b/src/boost/libs/hana/example/set/insert.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/insert.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto xs = hana::make_set(hana::int_c<0>, hana::type_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::insert(xs, BOOST_HANA_STRING("abc")) ==
+ hana::make_set(hana::int_c<0>, hana::type_c<int>, BOOST_HANA_STRING("abc"))
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::insert(xs, hana::int_c<0>) == hana::make_set(hana::int_c<0>, hana::type_c<int>)
+ );
+}
diff --git a/src/boost/libs/hana/example/set/intersection.cpp b/src/boost/libs/hana/example/set/intersection.cpp
new file mode 100644
index 000000000..1d080432b
--- /dev/null
+++ b/src/boost/libs/hana/example/set/intersection.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/intersection.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_set(hana::int_c<1>, hana::type_c<void>, hana::int_c<2>);
+constexpr auto ys = hana::make_set(hana::int_c<2>, hana::type_c<int>, hana::int_c<3>);
+
+BOOST_HANA_CONSTANT_CHECK(hana::intersection(xs, ys) == hana::make_set(hana::int_c<2>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/set/make.cpp b/src/boost/libs/hana/example/set/make.cpp
new file mode 100644
index 000000000..08f848340
--- /dev/null
+++ b/src/boost/libs/hana/example/set/make.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_set(hana::int_c<1>, hana::type_c<void>);
+BOOST_HANA_CONSTANT_CHECK(xs == hana::make<hana::set_tag>(hana::int_c<1>, hana::type_c<void>));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/set/searchable.cpp b/src/boost/libs/hana/example/set/searchable.cpp
new file mode 100644
index 000000000..81fa26933
--- /dev/null
+++ b/src/boost/libs/hana/example/set/searchable.cpp
@@ -0,0 +1,25 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/set.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto xs = hana::make_set(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>);
+ BOOST_HANA_CONSTANT_CHECK(hana::find(xs, hana::int_c<0>) == hana::just(hana::int_c<0>));
+ BOOST_HANA_CONSTANT_CHECK(hana::find(xs, hana::int_c<3>) == hana::nothing);
+
+ // operator[] is equivalent to at_key
+ BOOST_HANA_CONSTANT_CHECK(xs[hana::int_c<2>] == hana::int_c<2>);
+
+ // long_c<0> == int_<0>, and therefore int_<0> is found
+ BOOST_HANA_CONSTANT_CHECK(xs[hana::long_c<0>] == hana::int_c<0>);
+}
diff --git a/src/boost/libs/hana/example/set/symmetric_difference.cpp b/src/boost/libs/hana/example/set/symmetric_difference.cpp
new file mode 100644
index 000000000..0e66e73e7
--- /dev/null
+++ b/src/boost/libs/hana/example/set/symmetric_difference.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/symmetric_difference.hpp>
+
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_set(hana::int_c<1>, hana::int_c<2>, hana::type_c<int>, hana::int_c<3>);
+constexpr auto ys = hana::make_set(hana::int_c<3>, hana::type_c<void>, hana::type_c<int>);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::symmetric_difference(xs, ys) == hana::make_set(hana::int_c<1>, hana::int_c<2>, hana::type_c<void>)
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/set/to.cpp b/src/boost/libs/hana/example/set/to.cpp
new file mode 100644
index 000000000..59f0cb919
--- /dev/null
+++ b/src/boost/libs/hana/example/set/to.cpp
@@ -0,0 +1,28 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto xs = hana::make_tuple(
+ hana::int_c<1>,
+ hana::int_c<3>,
+ hana::type_c<int>,
+ hana::long_c<1>
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::to<hana::set_tag>(xs)
+ ==
+ hana::make_set(hana::int_c<1>, hana::int_c<3>, hana::type_c<int>)
+ );
+}
diff --git a/src/boost/libs/hana/example/set/union.cpp b/src/boost/libs/hana/example/set/union.cpp
new file mode 100644
index 000000000..b52d1d4ac
--- /dev/null
+++ b/src/boost/libs/hana/example/set/union.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/type.hpp>
+#include <boost/hana/union.hpp>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+constexpr auto xs = hana::make_set(hana::int_c<1>, hana::type_c<void>, hana::int_c<2>);
+constexpr auto ys = hana::make_set(hana::int_c<2>, hana::type_c<int>, hana::int_c<3>);
+
+BOOST_HANA_CONSTANT_CHECK(hana::union_(xs, ys) == hana::make_set(
+ hana::int_c<1>, hana::int_c<2>, hana::int_c<3>, hana::type_c<void>, hana::type_c<int>
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/size.cpp b/src/boost/libs/hana/example/size.cpp
new file mode 100644
index 000000000..f3f44e01a
--- /dev/null
+++ b/src/boost/libs/hana/example/size.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/size.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::size(hana::make_tuple()) == hana::size_c<0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::size(hana::make_tuple(1, '2', 3.0)) == hana::size_c<3>);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::size(hana::nothing) == hana::size_c<0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::size(hana::just('x')) == hana::size_c<1>);
+}
diff --git a/src/boost/libs/hana/example/slice.cpp b/src/boost/libs/hana/example/slice.cpp
new file mode 100644
index 000000000..954079312
--- /dev/null
+++ b/src/boost/libs/hana/example/slice.cpp
@@ -0,0 +1,43 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/filter.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/slice.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+// Slice a contiguous range
+constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3_c, hana::type_c<float>);
+
+static_assert(
+ hana::slice(xs, hana::tuple_c<std::size_t, 1, 2, 3>) ==
+ hana::make_tuple('1', 2.2, 3_c)
+, "");
+
+
+// A more complex example with a non-contiguous range
+constexpr auto letters = hana::to_tuple(hana::range_c<char, 'a', 'z'>);
+constexpr auto indices = hana::to_tuple(hana::make_range(hana::size_c<0>, hana::length(letters)));
+
+auto even_indices = hana::filter(indices, [](auto n) {
+ return n % hana::size_c<2> == hana::size_c<0>;
+});
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::slice(letters, even_indices) == hana::tuple_c<char,
+ 'a', 'c', 'e', 'g', 'i', 'k', 'm', 'o', 'q', 's', 'u', 'w', 'y'
+ >
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/slice_c.cpp b/src/boost/libs/hana/example/slice_c.cpp
new file mode 100644
index 000000000..8e1e990ae
--- /dev/null
+++ b/src/boost/libs/hana/example/slice_c.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/slice.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(
+ hana::slice_c<1, 3>(hana::make_tuple(1, '2', 3.3, hana::type_c<float>))
+ ==
+ hana::make_tuple('2', 3.3)
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/sort.cpp b/src/boost/libs/hana/example/sort.cpp
new file mode 100644
index 000000000..59161a980
--- /dev/null
+++ b/src/boost/libs/hana/example/sort.cpp
@@ -0,0 +1,47 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/negate.hpp>
+#include <boost/hana/ordering.hpp>
+#include <boost/hana/sort.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace hana::literals;
+using namespace std::literals;
+
+
+// sort without a predicate
+BOOST_HANA_CONSTANT_CHECK(
+ hana::sort(hana::make_tuple(1_c, -2_c, 3_c, 0_c)) ==
+ hana::make_tuple(-2_c, 0_c, 1_c, 3_c)
+);
+
+// sort with a predicate
+BOOST_HANA_CONSTANT_CHECK(
+ hana::sort(hana::make_tuple(1_c, -2_c, 3_c, 0_c), hana::greater) ==
+ hana::make_tuple(3_c, 1_c, 0_c, -2_c)
+);
+
+int main() {
+ // sort.by is syntactic sugar
+ auto tuples = hana::make_tuple(
+ hana::make_tuple(2_c, 'x', nullptr),
+ hana::make_tuple(1_c, "foobar"s, hana::int_c<4>)
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::sort.by(hana::ordering(hana::front), tuples)
+ == hana::make_tuple(
+ hana::make_tuple(1_c, "foobar"s, hana::int_c<4>),
+ hana::make_tuple(2_c, 'x', nullptr)
+ )
+ );
+}
diff --git a/src/boost/libs/hana/example/span.cpp b/src/boost/libs/hana/example/span.cpp
new file mode 100644
index 000000000..c31095635
--- /dev/null
+++ b/src/boost/libs/hana/example/span.cpp
@@ -0,0 +1,44 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/span.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto xs = hana::make_tuple(hana::int_c<1>, hana::int_c<2>, hana::int_c<3>, hana::int_c<4>);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::span(xs, hana::less.than(hana::int_c<3>))
+ ==
+ hana::make_pair(hana::make_tuple(hana::int_c<1>, hana::int_c<2>),
+ hana::make_tuple(hana::int_c<3>, hana::int_c<4>))
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::span(xs, hana::less.than(hana::int_c<0>))
+ ==
+ hana::make_pair(hana::make_tuple(), xs)
+);
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::span(xs, hana::less.than(hana::int_c<5>))
+ ==
+ hana::make_pair(xs, hana::make_tuple())
+);
+
+// span.by is syntactic sugar
+BOOST_HANA_CONSTANT_CHECK(
+ hana::span.by(hana::less.than(hana::int_c<3>), xs)
+ ==
+ hana::make_pair(hana::make_tuple(hana::int_c<1>, hana::int_c<2>),
+ hana::make_tuple(hana::int_c<3>, hana::int_c<4>))
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/string/comparable.cpp b/src/boost/libs/hana/example/string/comparable.cpp
new file mode 100644
index 000000000..e86d4bb0d
--- /dev/null
+++ b/src/boost/libs/hana/example/string/comparable.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abcdef") == BOOST_HANA_STRING("abcdef")
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abcdef") != BOOST_HANA_STRING("abef")
+ );
+}
diff --git a/src/boost/libs/hana/example/string/foldable.cpp b/src/boost/libs/hana/example/string/foldable.cpp
new file mode 100644
index 000000000..d1d4661ec
--- /dev/null
+++ b/src/boost/libs/hana/example/string/foldable.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/value.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto sum_string = [](auto str) {
+ return hana::fold_left(str, hana::int_c<0>, [](auto sum, auto c) {
+ constexpr int i = hana::value(c) - 48; // convert character to decimal
+ return sum + hana::int_c<i>;
+ });
+ };
+
+ BOOST_HANA_CONSTANT_CHECK(
+ sum_string(BOOST_HANA_STRING("1234")) == hana::int_c<1 + 2 + 3 + 4>
+ );
+}
diff --git a/src/boost/libs/hana/example/string/from_c_str.cpp b/src/boost/libs/hana/example/string/from_c_str.cpp
new file mode 100644
index 000000000..3441473ed
--- /dev/null
+++ b/src/boost/libs/hana/example/string/from_c_str.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+constexpr char const hello[] = "hello";
+auto hello_constant = hana::integral_constant<char const*, hello>{};
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::to_string(hello_constant) == hana::string_c<'h', 'e', 'l', 'l', 'o'>
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/string/hashable.cpp b/src/boost/libs/hana/example/string/hashable.cpp
new file mode 100644
index 000000000..a781fdefc
--- /dev/null
+++ b/src/boost/libs/hana/example/string/hashable.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/hash.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+// `hana::hash` returns a type uniquely representing the string. The hash is
+// perfect, meaning no two different strings have the same hash value.
+BOOST_HANA_CONSTANT_CHECK(hana::not_equal(
+ hana::hash(BOOST_HANA_STRING("abcdef")),
+ hana::hash(BOOST_HANA_STRING("abcdefg"))
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/string/iterable.cpp b/src/boost/libs/hana/example/string/iterable.cpp
new file mode 100644
index 000000000..af7a2f383
--- /dev/null
+++ b/src/boost/libs/hana/example/string/iterable.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/drop_while.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(!hana::is_empty(BOOST_HANA_STRING("abcd")));
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(BOOST_HANA_STRING("")));
+
+ BOOST_HANA_CONSTANT_CHECK(BOOST_HANA_STRING("abcd")[hana::size_c<2>] == hana::char_c<'c'>);
+
+ auto is_vowel = [](auto c) {
+ return c ^hana::in^ BOOST_HANA_STRING("aeiouy");
+ };
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::drop_while(BOOST_HANA_STRING("aioubcd"), is_vowel) == BOOST_HANA_STRING("bcd")
+ );
+}
diff --git a/src/boost/libs/hana/example/string/literal.cpp b/src/boost/libs/hana/example/string/literal.cpp
new file mode 100644
index 000000000..feab6f69e
--- /dev/null
+++ b/src/boost/libs/hana/example/string/literal.cpp
@@ -0,0 +1,28 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/core/is_a.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+// By default, this is disabled
+#ifdef BOOST_HANA_CONFIG_ENABLE_STRING_UDL
+
+ constexpr auto str = "Hello world!"_s;
+ BOOST_HANA_CONSTANT_CHECK(str == hana::string_c<'H', 'e', 'l', 'l', 'o', ' ',
+ 'w', 'o', 'r', 'l', 'd', '!'>);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_a<hana::string_tag>(str));
+ BOOST_HANA_CONSTANT_CHECK(hana::length(str) == hana::size_c<12>);
+
+#endif
+
+int main() { }
diff --git a/src/boost/libs/hana/example/string/macro.cpp b/src/boost/libs/hana/example/string/macro.cpp
new file mode 100644
index 000000000..3c2d2ea7d
--- /dev/null
+++ b/src/boost/libs/hana/example/string/macro.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/core/is_a.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto str = BOOST_HANA_STRING("abcdef");
+ BOOST_HANA_CONSTANT_CHECK(str == hana::string_c<'a', 'b', 'c', 'd', 'e', 'f'>);
+ BOOST_HANA_CONSTANT_CHECK(hana::is_a<hana::string_tag>(str));
+}
diff --git a/src/boost/libs/hana/example/string/make.cpp b/src/boost/libs/hana/example/string/make.cpp
new file mode 100644
index 000000000..c7bac05d8
--- /dev/null
+++ b/src/boost/libs/hana/example/string/make.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto vowels = hana::tuple_c<char, 'a', 'e', 'i', 'o', 'u', 'y'>;
+constexpr auto str = hana::unpack(vowels, hana::make<hana::string_tag>);
+BOOST_HANA_CONSTANT_CHECK(str == BOOST_HANA_STRING("aeiouy"));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/string/monoid.cpp b/src/boost/libs/hana/example/string/monoid.cpp
new file mode 100644
index 000000000..305e6351f
--- /dev/null
+++ b/src/boost/libs/hana/example/string/monoid.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+auto hello_world = BOOST_HANA_STRING("Hello ") + BOOST_HANA_STRING("world!");
+BOOST_HANA_CONSTANT_CHECK(hello_world == BOOST_HANA_STRING("Hello world!"));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/string/orderable.cpp b/src/boost/libs/hana/example/string/orderable.cpp
new file mode 100644
index 000000000..21faeaa27
--- /dev/null
+++ b/src/boost/libs/hana/example/string/orderable.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abc") < BOOST_HANA_STRING("bcd")
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abcd") > BOOST_HANA_STRING("abc")
+ );
+}
diff --git a/src/boost/libs/hana/example/string/searchable.cpp b/src/boost/libs/hana/example/string/searchable.cpp
new file mode 100644
index 000000000..b7e2175af
--- /dev/null
+++ b/src/boost/libs/hana/example/string/searchable.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::char_c<'c'> ^hana::in^ BOOST_HANA_STRING("abcde"));
+ BOOST_HANA_CONSTANT_CHECK(!(hana::char_c<'z'> ^hana::in^ BOOST_HANA_STRING("abcde")));
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::find(BOOST_HANA_STRING("abcxefg"), hana::char_c<'x'>) == hana::just(hana::char_c<'x'>)
+ );
+}
diff --git a/src/boost/libs/hana/example/string/string_c.cpp b/src/boost/libs/hana/example/string/string_c.cpp
new file mode 100644
index 000000000..327234078
--- /dev/null
+++ b/src/boost/libs/hana/example/string/string_c.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/is_a.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto str = hana::string_c<'a', 'b', 'c', 'd', 'e', 'f'>;
+BOOST_HANA_CONSTANT_CHECK(hana::is_a<hana::string_tag>(str));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/string/to.cpp b/src/boost/libs/hana/example/string/to.cpp
new file mode 100644
index 000000000..16109a235
--- /dev/null
+++ b/src/boost/libs/hana/example/string/to.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto str = hana::string_c<'h', 'i'>;
+
+// using c_str()
+constexpr char const* s1 = str.c_str();
+static_assert(s1[0] == 'h' && s1[1] == 'i' && s1[2] == '\0', "");
+
+// using hana::to
+constexpr char const* s2 = hana::to<char const*>(str);
+static_assert(s2[0] == 'h' && s2[1] == 'i' && s2[2] == '\0', "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/struct.custom_accessor.cpp b/src/boost/libs/hana/example/struct.custom_accessor.cpp
new file mode 100644
index 000000000..1328d01c9
--- /dev/null
+++ b/src/boost/libs/hana/example/struct.custom_accessor.cpp
@@ -0,0 +1,68 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/fwd/accessors.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+#include <utility>
+namespace hana = boost::hana;
+
+
+//! [main]
+struct Person {
+ Person(std::string const& name, int age) : name_(name), age_(age) { }
+
+ std::string const& get_name() const { return name_; }
+ int get_age() const { return age_; }
+
+private:
+ std::string name_;
+ int age_;
+};
+
+namespace boost { namespace hana {
+ template <>
+ struct accessors_impl<Person> {
+ static BOOST_HANA_CONSTEXPR_LAMBDA auto apply() {
+ return make_tuple(
+ make_pair(BOOST_HANA_STRING("name"), [](auto&& p) -> std::string const& {
+ return p.get_name();
+ }),
+ make_pair(BOOST_HANA_STRING("age"), [](auto&& p) {
+ return p.get_age();
+ })
+ );
+ }
+ };
+}}
+//! [main]
+
+int main() {
+ auto name = BOOST_HANA_STRING("name");
+ auto age = BOOST_HANA_STRING("age");
+
+ Person john{"John", 30}, bob{"Bob", 40};
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(john, john));
+ BOOST_HANA_RUNTIME_CHECK(hana::not_equal(john, bob));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, name) == hana::just("John"));
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, age) == hana::just(30));
+ BOOST_HANA_CONSTANT_CHECK(hana::find(john, BOOST_HANA_STRING("foo")) == hana::nothing);
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to_tuple(john) == hana::make_tuple(
+ hana::make_pair(name, "John"),
+ hana::make_pair(age, 30)
+ ));
+}
diff --git a/src/boost/libs/hana/example/struct.mcd.nested.cpp b/src/boost/libs/hana/example/struct.mcd.nested.cpp
new file mode 100644
index 000000000..3ba10a374
--- /dev/null
+++ b/src/boost/libs/hana/example/struct.mcd.nested.cpp
@@ -0,0 +1,57 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/struct.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+#include <utility>
+namespace hana = boost::hana;
+
+
+//! [main]
+struct Person {
+ std::string name;
+ int age;
+
+ struct hana_accessors_impl {
+ static BOOST_HANA_CONSTEXPR_LAMBDA auto apply() {
+ return boost::hana::make_tuple(
+ boost::hana::make_pair(BOOST_HANA_STRING("name"),
+ [](auto&& p) -> decltype(auto) {
+ return boost::hana::id(std::forward<decltype(p)>(p).name);
+ }),
+ boost::hana::make_pair(BOOST_HANA_STRING("age"),
+ [](auto&& p) -> decltype(auto) {
+ return boost::hana::id(std::forward<decltype(p)>(p).age);
+ })
+ );
+ }
+ };
+};
+//! [main]
+
+int main() {
+ Person john{"John", 30}, bob{"Bob", 40};
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(john, john));
+ BOOST_HANA_RUNTIME_CHECK(hana::not_equal(john, bob));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("name")) == hana::just("John"));
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("age")) == hana::just(30));
+ BOOST_HANA_CONSTANT_CHECK(hana::find(john, BOOST_HANA_STRING("foo")) == hana::nothing);
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to_tuple(john) == hana::make_tuple(
+ hana::make_pair(BOOST_HANA_STRING("name"), "John"),
+ hana::make_pair(BOOST_HANA_STRING("age"), 30)
+ ));
+}
diff --git a/src/boost/libs/hana/example/struct.mcd.tag_dispatching.cpp b/src/boost/libs/hana/example/struct.mcd.tag_dispatching.cpp
new file mode 100644
index 000000000..9788e8305
--- /dev/null
+++ b/src/boost/libs/hana/example/struct.mcd.tag_dispatching.cpp
@@ -0,0 +1,63 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/fwd/accessors.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+#include <utility>
+namespace hana = boost::hana;
+
+
+//! [main]
+struct Person {
+ std::string name;
+ int age;
+};
+
+// The keys can be anything as long as they are compile-time comparable.
+constexpr auto name = hana::integral_c<std::string Person::*, &Person::name>;
+constexpr auto age = hana::string_c<'a', 'g', 'e'>;
+
+namespace boost { namespace hana {
+ template <>
+ struct accessors_impl<Person> {
+ static BOOST_HANA_CONSTEXPR_LAMBDA auto apply() {
+ return make_tuple(
+ make_pair(name, [](auto&& p) -> decltype(auto) {
+ return id(std::forward<decltype(p)>(p).name);
+ }),
+ make_pair(age, [](auto&& p) -> decltype(auto) {
+ return id(std::forward<decltype(p)>(p).age);
+ })
+ );
+ }
+ };
+}}
+//! [main]
+
+int main() {
+ Person john{"John", 30}, bob{"Bob", 40};
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(john, john));
+ BOOST_HANA_RUNTIME_CHECK(hana::not_equal(john, bob));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, name) == hana::just("John"));
+ BOOST_HANA_RUNTIME_CHECK(hana::find(john, age) == hana::just(30));
+ BOOST_HANA_CONSTANT_CHECK(hana::find(john, BOOST_HANA_STRING("foo")) == hana::nothing);
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to_tuple(john) == hana::make_tuple(
+ hana::make_pair(name, "John"),
+ hana::make_pair(age, 30)
+ ));
+}
diff --git a/src/boost/libs/hana/example/struct/comparable.cpp b/src/boost/libs/hana/example/struct/comparable.cpp
new file mode 100644
index 000000000..238f4dc5f
--- /dev/null
+++ b/src/boost/libs/hana/example/struct/comparable.cpp
@@ -0,0 +1,28 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/keys.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/string.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (unsigned short, age)
+ );
+};
+
+int main() {
+ Person john{"John", 30}, kevin{"Kevin", 20};
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(john, john));
+ BOOST_HANA_RUNTIME_CHECK(hana::not_equal(john, kevin));
+}
diff --git a/src/boost/libs/hana/example/struct/foldable.cpp b/src/boost/libs/hana/example/struct/foldable.cpp
new file mode 100644
index 000000000..7f52e9203
--- /dev/null
+++ b/src/boost/libs/hana/example/struct/foldable.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+struct Kitten {
+ BOOST_HANA_DEFINE_STRUCT(Kitten,
+ (int, extremely_cute),
+ (int, cute),
+ (int, not_so_cute)
+ );
+};
+
+int main() {
+ constexpr Kitten kitten{5, 10, 0};
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::fold_left(kitten, 0, [](auto total, auto member) {
+ // first(member) is the name of the member, here
+ // "extremely_cute", or "cute" or "not_so_cute",
+ // and second(member) is its value.
+ return hana::second(member) + total;
+ }) == (5 + 10 + 0)
+ );
+}
diff --git a/src/boost/libs/hana/example/struct/keys.cpp b/src/boost/libs/hana/example/struct/keys.cpp
new file mode 100644
index 000000000..37e97040a
--- /dev/null
+++ b/src/boost/libs/hana/example/struct/keys.cpp
@@ -0,0 +1,29 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/keys.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (unsigned short, age)
+ );
+};
+
+int main() {
+ Person john{"John", 30};
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::keys(john) == hana::make_tuple(BOOST_HANA_STRING("name"),
+ BOOST_HANA_STRING("age"))
+ );
+}
diff --git a/src/boost/libs/hana/example/struct/searchable.cpp b/src/boost/libs/hana/example/struct/searchable.cpp
new file mode 100644
index 000000000..aae5dbfa0
--- /dev/null
+++ b/src/boost/libs/hana/example/struct/searchable.cpp
@@ -0,0 +1,46 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/accessors.hpp>
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/string.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (unsigned short, age)
+ );
+};
+
+int main() {
+ Person john{"John", 30};
+
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::find(john, BOOST_HANA_STRING("name")) == hana::just("John")
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::find(john, BOOST_HANA_STRING("foobar")) == hana::nothing
+ );
+
+
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::all_of(hana::accessors<Person>(), [&](auto a) {
+ return hana::second(a)(john) == hana::second(a)(john);
+ })
+ );
+
+ // the above is equivalent to:
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(john, john));
+}
diff --git a/src/boost/libs/hana/example/struct/to.cpp b/src/boost/libs/hana/example/struct/to.cpp
new file mode 100644
index 000000000..501f72608
--- /dev/null
+++ b/src/boost/libs/hana/example/struct/to.cpp
@@ -0,0 +1,30 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (unsigned short, age)
+ );
+};
+
+int main() {
+ Person john{"John", 30u};
+ BOOST_HANA_RUNTIME_CHECK(hana::to<hana::map_tag>(john) == hana::make_map(
+ hana::make_pair(BOOST_HANA_STRING("name"), "John"),
+ hana::make_pair(BOOST_HANA_STRING("age"), 30u)
+ ));
+}
diff --git a/src/boost/libs/hana/example/suffix.cpp b/src/boost/libs/hana/example/suffix.cpp
new file mode 100644
index 000000000..8d2f51929
--- /dev/null
+++ b/src/boost/libs/hana/example/suffix.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/suffix.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(
+ hana::suffix(hana::make_tuple(1, 2, 3, 4), 0) == hana::make_tuple(1, 0, 2, 0, 3, 0, 4, 0)
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/sum.cpp b/src/boost/libs/hana/example/sum.cpp
new file mode 100644
index 000000000..3fded1a4e
--- /dev/null
+++ b/src/boost/libs/hana/example/sum.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/sum.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::sum<>(hana::make_range(hana::int_c<1>, hana::int_c<6>)) == hana::int_c<15>);
+
+static_assert(hana::sum<>(hana::make_tuple(1, hana::int_c<3>, hana::long_c<-5>, 9)) == 8, "");
+
+static_assert(hana::sum<unsigned long>(hana::make_tuple(1ul, 3ul)) == 4ul, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/take_back.cpp b/src/boost/libs/hana/example/take_back.cpp
new file mode 100644
index 000000000..e4a988b0b
--- /dev/null
+++ b/src/boost/libs/hana/example/take_back.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/take_back.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<0>) == hana::make_tuple());
+static_assert(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<1>) == hana::make_tuple(3.3), "");
+static_assert(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<2>) == hana::make_tuple('2', 3.3), "");
+static_assert(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<3>) == hana::make_tuple(1, '2', 3.3), "");
+static_assert(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<4>) == hana::make_tuple(1, '2', 3.3), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/take_back_c.cpp b/src/boost/libs/hana/example/take_back_c.cpp
new file mode 100644
index 000000000..c4d035dfa
--- /dev/null
+++ b/src/boost/libs/hana/example/take_back_c.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/take_back.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::take_back_c<2>(hana::make_tuple(1, '2', 3.3)) == hana::make_tuple('2', 3.3), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/take_front.cpp b/src/boost/libs/hana/example/take_front.cpp
new file mode 100644
index 000000000..347619a71
--- /dev/null
+++ b/src/boost/libs/hana/example/take_front.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/take_front.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<0>) == hana::make_tuple());
+static_assert(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<1>) == hana::make_tuple(1), "");
+static_assert(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<2>) == hana::make_tuple(1, '2'), "");
+static_assert(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<3>) == hana::make_tuple(1, '2', 3.3), "");
+static_assert(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<4>) == hana::make_tuple(1, '2', 3.3), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/take_front_c.cpp b/src/boost/libs/hana/example/take_front_c.cpp
new file mode 100644
index 000000000..554bb4859
--- /dev/null
+++ b/src/boost/libs/hana/example/take_front_c.cpp
@@ -0,0 +1,13 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/take_front.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::take_front_c<2>(hana::make_tuple(1, '2', 3.3)) == hana::make_tuple(1, '2'), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/take_while.cpp b/src/boost/libs/hana/example/take_while.cpp
new file mode 100644
index 000000000..79f6b21e8
--- /dev/null
+++ b/src/boost/libs/hana/example/take_while.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/take_while.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::take_while(hana::tuple_c<int, 0, 1, 2, 3>, hana::less.than(2_c))
+ ==
+ hana::tuple_c<int, 0, 1>
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/tap.cpp b/src/boost/libs/hana/example/tap.cpp
new file mode 100644
index 000000000..6c93eeb55
--- /dev/null
+++ b/src/boost/libs/hana/example/tap.cpp
@@ -0,0 +1,28 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tap.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <set>
+namespace hana = boost::hana;
+
+
+int main() {
+ // We use a sorted container because the order in which the functions
+ // are called is unspecified.
+ std::set<int> before, after;
+
+ auto xs = hana::make_tuple(1, 2, 3)
+ | hana::tap<hana::tuple_tag>([&](int x) { before.insert(x); })
+ | [](auto x) { return hana::make_tuple(x, -x); }
+ | hana::tap<hana::tuple_tag>([&](int x) { after.insert(x); });
+
+ BOOST_HANA_RUNTIME_CHECK(before == std::set<int>{1, 2, 3});
+ BOOST_HANA_RUNTIME_CHECK(after == std::set<int>{1, -1, 2, -2, 3, -3});
+ BOOST_HANA_RUNTIME_CHECK(xs == hana::make_tuple(1, -1, 2, -2, 3, -3));
+}
diff --git a/src/boost/libs/hana/example/then.cpp b/src/boost/libs/hana/example/then.cpp
new file mode 100644
index 000000000..40c192c1d
--- /dev/null
+++ b/src/boost/libs/hana/example/then.cpp
@@ -0,0 +1,21 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/then.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct undefined { };
+static_assert(
+ hana::then(hana::make_tuple(undefined{}, undefined{}), hana::make_tuple(1, 2, 3))
+ ==
+ hana::make_tuple(
+ 1, 2, 3,
+ 1, 2, 3
+ )
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/transform.cpp b/src/boost/libs/hana/example/transform.cpp
new file mode 100644
index 000000000..0bdf4cb09
--- /dev/null
+++ b/src/boost/libs/hana/example/transform.cpp
@@ -0,0 +1,40 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <sstream>
+#include <string>
+#include <type_traits>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+auto to_string = [](auto x) {
+ std::ostringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::transform(hana::make_tuple(1, '2', "345", std::string{"67"}), to_string)
+ ==
+ hana::make_tuple("1", "2", "345", "67")
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::transform(hana::nothing, to_string) == hana::nothing);
+ BOOST_HANA_RUNTIME_CHECK(hana::transform(hana::just(123), to_string) == hana::just("123"s));
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::transform(hana::tuple_t<void, int(), char[10]>, hana::metafunction<std::add_pointer>)
+ ==
+ hana::tuple_t<void*, int(*)(), char(*)[10]>
+ );
+}
diff --git a/src/boost/libs/hana/example/tuple/foldable.cpp b/src/boost/libs/hana/example/tuple/foldable.cpp
new file mode 100644
index 000000000..8a5354e39
--- /dev/null
+++ b/src/boost/libs/hana/example/tuple/foldable.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/prepend.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+int main() {
+ constexpr auto numbers = hana::tuple_c<int, 5, -1, 0, -7, -2, 0, -5, 4>;
+ constexpr auto negatives = hana::tuple_c<int, -1, -7, -2, -5>;
+
+ BOOST_HANA_CONSTEXPR_LAMBDA auto keep_negatives = [](auto n, auto acc) {
+ return hana::if_(n < 0_c, hana::prepend(acc, n), acc);
+ };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::fold_right(numbers, hana::tuple_c<int>, keep_negatives) == negatives);
+}
diff --git a/src/boost/libs/hana/example/tuple/interop.cpp b/src/boost/libs/hana/example/tuple/interop.cpp
new file mode 100644
index 000000000..cc274aee8
--- /dev/null
+++ b/src/boost/libs/hana/example/tuple/interop.cpp
@@ -0,0 +1,34 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/array.hpp>
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <array>
+#include <tuple>
+namespace hana = boost::hana;
+
+
+int main() {
+ static_assert(
+ hana::to_tuple(std::make_tuple(1, '2', 3.3)) == hana::make_tuple(1, '2', 3.3)
+ , "");
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::to_tuple(hana::make_range(hana::int_c<1>, hana::int_c<4>))
+ ==
+ hana::make_tuple(hana::int_c<1>, hana::int_c<2>, hana::int_c<3>)
+ );
+
+ // std::array's operator[] is not constexpr, so we can't use static_assert
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::to_tuple(std::array<int, 3>{{1, 2, 3}}) == hana::make_tuple(1, 2, 3)
+ );
+}
diff --git a/src/boost/libs/hana/example/tuple/make.cpp b/src/boost/libs/hana/example/tuple/make.cpp
new file mode 100644
index 000000000..e88fe38ac
--- /dev/null
+++ b/src/boost/libs/hana/example/tuple/make.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto xs = hana::make<hana::tuple_tag>(1, 2, '3', std::string{"456"});
+
+ constexpr auto ys = hana::make<hana::tuple_tag>(1, '2', 3.456);
+ static_assert(ys == hana::make_tuple(1, '2', 3.456), "");
+}
diff --git a/src/boost/libs/hana/example/tuple/tuple.cpp b/src/boost/libs/hana/example/tuple/tuple.cpp
new file mode 100644
index 000000000..e16ff8d07
--- /dev/null
+++ b/src/boost/libs/hana/example/tuple/tuple.cpp
@@ -0,0 +1,29 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+
+int main() {
+ hana::tuple<Fish, Cat, Dog> animals{{"Nemo"}, {"Garfield"}, {"Snoopy"}};
+ animals[0_c].name = "Moby Dick"; // can modify elements in place, like std::tuple
+
+ auto names = hana::transform(animals, [](auto a) {
+ return a.name;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(names == hana::make_tuple("Moby Dick", "Garfield", "Snoopy"));
+}
diff --git a/src/boost/libs/hana/example/tuple/tuple_c.cpp b/src/boost/libs/hana/example/tuple/tuple_c.cpp
new file mode 100644
index 000000000..012221745
--- /dev/null
+++ b/src/boost/libs/hana/example/tuple/tuple_c.cpp
@@ -0,0 +1,22 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::tuple_c<int, 0, 1, 2>
+ ==
+ hana::make_tuple(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>)
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::front(hana::tuple_c<int, 0, 1, 2>) == hana::int_c<0>);
+}
diff --git a/src/boost/libs/hana/example/tuple/tuple_t.cpp b/src/boost/libs/hana/example/tuple/tuple_t.cpp
new file mode 100644
index 000000000..7da9107e5
--- /dev/null
+++ b/src/boost/libs/hana/example/tuple/tuple_t.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::to_tuple(hana::tuple_t<int, char, void, int(float)>)
+ ==
+ hana::make_tuple(hana::type_c<int>, hana::type_c<char>, hana::type_c<void>, hana::type_c<int(float)>)
+ );
+}
diff --git a/src/boost/libs/hana/example/tutorial/algorithms.cpp b/src/boost/libs/hana/example/tutorial/algorithms.cpp
new file mode 100644
index 000000000..9afe86b1e
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/algorithms.cpp
@@ -0,0 +1,148 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+
+#include <sstream>
+#include <string>
+#include <tuple>
+#include <type_traits>
+namespace hana = boost::hana;
+using namespace hana::literals;
+using namespace std::literals;
+
+
+int main() {
+
+{
+
+//! [reverse_transform]
+auto to_str = [](auto const& x) {
+ std::stringstream ss;
+ ss << x;
+ return ss.str();
+};
+
+auto xs = hana::make_tuple(1, 2.2, 'a', "bcde");
+
+BOOST_HANA_RUNTIME_CHECK(
+ hana::reverse(hana::transform(xs, to_str)) == hana::make_tuple("bcde", "a", "2.2", "1")
+);
+//! [reverse_transform]
+
+//! [reverse_transform_copy]
+hana::reverse(
+ hana::transform(xs, to_str) // <-- copy into reverse(...) here?
+);
+//! [reverse_transform_copy]
+
+//! [reverse_transform_move]
+hana::reverse(
+ hana::transform(xs, to_str) // <-- nope, move from the temporary instead!
+);
+//! [reverse_transform_move]
+
+}{
+
+//! [effects]
+auto r = hana::any_of(hana::make_tuple("hello"s, 1.2, 3), [](auto x) {
+ return std::is_integral<decltype(x)>{};
+});
+
+BOOST_HANA_CONSTANT_CHECK(r);
+//! [effects]
+
+{
+
+//! [effects.codegen]
+auto xs = hana::make_tuple("hello"s, 1.2, 3);
+auto pred = [](auto x) { return std::is_integral<decltype(x)>{}; };
+
+auto r = hana::bool_c<
+ decltype(pred(xs[0_c]))::value ? true :
+ decltype(pred(xs[1_c]))::value ? true :
+ decltype(pred(xs[2_c]))::value ? true :
+ false
+>;
+
+BOOST_HANA_CONSTANT_CHECK(r);
+//! [effects.codegen]
+
+}
+
+}{
+
+//! [cross_phase.setup]
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+
+auto animals = hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});
+// ^^^^^^^ not a compile-time value
+
+BOOST_HANA_CONSTANT_CHECK(hana::length(animals) == hana::size_c<3>);
+// ^^^^^^^^^^^^^^^^^^^^^ assertion done at compile-time
+//! [cross_phase.setup]
+
+//! [cross_phase.is_empty]
+BOOST_HANA_CONSTANT_CHECK(!hana::is_empty(animals));
+// ^^^^^^^^^^^^^^^^^^^^^^^ assertion done at compile-time
+//! [cross_phase.is_empty]
+
+{
+
+//! [cross_phase.any_of_runtime]
+bool any_garfield = hana::any_of(animals, [](auto animal) {
+ return animal.name == "Garfield"s;
+});
+
+BOOST_HANA_RUNTIME_CHECK(any_garfield);
+//! [cross_phase.any_of_runtime]
+
+}{
+
+//! [cross_phase.any_of_compile_time]
+auto any_cat = hana::any_of(animals, [](auto x) {
+ return std::is_same<decltype(x), Cat>{};
+});
+
+BOOST_HANA_CONSTANT_CHECK(any_cat);
+//! [cross_phase.any_of_compile_time]
+
+}{
+
+//! [cross_phase.any_of_explicit]
+hana::integral_constant<bool, true> any_cat = hana::any_of(animals, [](auto x) {
+ return std::is_same<decltype(x), Cat>{};
+});
+
+BOOST_HANA_CONSTANT_CHECK(any_cat);
+//! [cross_phase.any_of_explicit]
+
+}{
+
+//! [cross_phase.filter]
+auto mammals = hana::filter(animals, [](auto animal) {
+ return hana::type_c<decltype(animal)> != hana::type_c<Fish>;
+});
+//! [cross_phase.filter]
+
+BOOST_HANA_RUNTIME_CHECK(
+ hana::transform(mammals, [](auto x) { return x.name; })
+ == hana::make_tuple("Garfield", "Snoopy")
+);
+
+}
+
+}{
+
+//! [cross_phase.std::tuple_size]
+std::tuple<int, char, std::string> xs{1, '2', std::string{"345"}};
+static_assert(std::tuple_size<decltype(xs)>::value == 3u, "");
+//! [cross_phase.std::tuple_size]
+
+}
+
+}
diff --git a/src/boost/libs/hana/example/tutorial/appendix_mpl.cpp b/src/boost/libs/hana/example/tutorial/appendix_mpl.cpp
new file mode 100644
index 000000000..3174af2ce
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/appendix_mpl.cpp
@@ -0,0 +1,697 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+#include <boost/hana/ext/boost/mpl.hpp>
+#include <boost/hana/ext/std.hpp>
+
+#include <boost/mpl/lambda.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/quote.hpp>
+
+#include <iostream>
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+namespace hpl {
+//////////////////////////////////////////////////////////////////////////////
+// Utilities
+//////////////////////////////////////////////////////////////////////////////
+namespace detail {
+ template <typename Pred>
+ constexpr auto mpl_predicate = hana::integral(hana::metafunction_class<
+ typename mpl::lambda<Pred>::type
+ >);
+
+ template <typename F>
+ constexpr auto mpl_metafunction = hana::metafunction_class<
+ typename mpl::lambda<F>::type
+ >;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// integral_c
+//////////////////////////////////////////////////////////////////////////////
+template <typename T, T v>
+using integral_c = std::integral_constant<T, v>;
+
+template <int i>
+using int_ = integral_c<int, i>;
+
+template <long i>
+using long_ = integral_c<long, i>;
+
+template <bool b>
+using bool_ = integral_c<bool, b>;
+
+using true_ = bool_<true>;
+using false_ = bool_<false>;
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Sequences, compile-time integers & al
+//
+// Differences with the MPL:
+// 1. `pair<...>::first` and `pair<...>::second` won't work;
+// use `first<pair<...>>` instead
+//////////////////////////////////////////////////////////////////////////////
+template <typename ...T>
+using vector = hana::tuple<hana::type<T>...>;
+
+template <typename T, T ...v>
+using vector_c = hana::tuple<hana::integral_constant<T, v>...>;
+
+template <typename T, T from, T to>
+using range_c = decltype(hana::range_c<T, from, to>);
+
+
+template <typename T, typename U>
+using pair = hana::pair<hana::type<T>, hana::type<U>>;
+
+template <typename P>
+struct first : decltype(+hana::first(P{})) { };
+
+template <typename P>
+struct second : decltype(+hana::second(P{})) { };
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Miscellaneous metafunctions
+//////////////////////////////////////////////////////////////////////////////
+template <typename C1, typename C2>
+struct equal_to
+ : bool_<C1::value == C2::value>
+{ };
+
+template <typename C1, typename C2>
+struct less
+ : bool_<(C1::value < C2::value)>
+{ };
+
+template <typename C1, typename C2>
+struct greater
+ : bool_<(C1::value > C2::value)>
+{ };
+
+template <typename N>
+struct next
+ : integral_c<typename N::value_type, N::value + 1>
+{ };
+
+//////////////////////////////////////////////////////////////////////////////
+// Intrinsics
+//
+// Differences with the MPL:
+// 1. `at` does not work for associative sequences; use `find` instead.
+// 2. `begin`, `end`, `clear`, `erase`, `erase_key`, `insert`, `insert_range`,
+// `is_sequence`, `key_type`, `order`, `sequence_tag`, `value_type`: not implemented
+//////////////////////////////////////////////////////////////////////////////
+template <typename Sequence, typename N>
+struct at
+ : decltype(hana::at(Sequence{}, N{}))
+{ };
+
+template <typename Sequence, long n>
+using at_c = at<Sequence, long_<n>>;
+
+template <typename Sequence>
+struct back
+ : decltype(+hana::back(Sequence{}))
+{ };
+
+template <typename Sequence>
+struct empty
+ : decltype(hana::is_empty(Sequence{}))
+{ };
+
+template <typename Sequence>
+struct front
+ : decltype(+hana::front(Sequence{}))
+{ };
+
+template <typename Sequence>
+struct pop_back {
+ using type = decltype(hana::drop_back(
+ hana::to_tuple(Sequence{}), hana::size_c<1>
+ ));
+};
+
+template <typename Sequence>
+struct pop_front {
+ using type = decltype(hana::drop_front(Sequence{}));
+};
+
+template <typename Sequence, typename T>
+struct push_back {
+ using type = decltype(hana::append(Sequence{}, hana::type_c<T>));
+};
+
+template <typename Sequence, typename T>
+struct push_front {
+ using type = decltype(hana::prepend(Sequence{}, hana::type_c<T>));
+};
+
+template <typename Sequence>
+struct size
+ : decltype(hana::length(Sequence{}))
+{ };
+
+//////////////////////////////////////////////////////////////////////////////
+// Iteration algorithms
+//
+// Differences with the MPL:
+// 1. reverse_fold:
+// Does not take an optional additional ForwardOp argument.
+//
+// 2. iter_fold, reverse_iter_fold:
+// Not implemented because we don't use iterators
+//////////////////////////////////////////////////////////////////////////////
+template <typename Sequence, typename State, typename F>
+struct fold
+ : decltype(hana::fold(
+ Sequence{}, hana::type_c<State>, detail::mpl_metafunction<F>
+ ))
+{ };
+
+template <typename Sequence, typename State, typename F>
+struct reverse_fold
+ : decltype(hana::reverse_fold(
+ Sequence{}, hana::type_c<State>, detail::mpl_metafunction<F>
+ ))
+{ };
+
+template <typename Sequence, typename State, typename F>
+using accumulate = fold<Sequence, State, F>;
+
+//////////////////////////////////////////////////////////////////////////////
+// Query algorithms
+//
+// Differences with the MPL:
+// 1. find_if and find:
+// Instead of returning an iterator, they either have a nested `::type`
+// alias to the answer, or they have no nested `::type` at all, which
+// makes them SFINAE-friendly.
+//
+// 2. lower_bound, upper_bound:
+// Not implemented.
+//
+// 3. {min,max}_element:
+// Not returning an iterator, and also won't work on empty sequences.
+//////////////////////////////////////////////////////////////////////////////
+template <typename Sequence, typename Pred>
+struct find_if
+ : decltype(hana::find_if(Sequence{}, detail::mpl_predicate<Pred>))
+{ };
+
+template <typename Sequence, typename T>
+struct find
+ : decltype(hana::find(Sequence{}, hana::type_c<T>))
+{ };
+
+template <typename Sequence, typename T>
+struct contains
+ : decltype(hana::contains(Sequence{}, hana::type_c<T>))
+{ };
+
+template <typename Sequence, typename T>
+struct count
+ : decltype(hana::count(Sequence{}, hana::type_c<T>))
+{ };
+
+template <typename Sequence, typename Pred>
+struct count_if
+ : decltype(hana::count_if(Sequence{}, detail::mpl_predicate<Pred>))
+{ };
+
+template <typename Sequence, typename Pred = mpl::quote2<less>>
+struct min_element
+ : decltype(hana::minimum(Sequence{}, detail::mpl_predicate<Pred>))
+{ };
+
+template <typename Sequence, typename Pred = mpl::quote2<less>>
+struct max_element
+ : decltype(hana::maximum(Sequence{}, detail::mpl_predicate<Pred>))
+{ };
+
+template <typename S1, typename S2, typename Pred = mpl::quote2<std::is_same>>
+struct equal
+ : decltype( // inefficient but whatever
+ hana::length(S1{}) == hana::length(S2{}) &&
+ hana::all(hana::zip_shortest_with(detail::mpl_predicate<Pred>,
+ hana::to_tuple(S1{}),
+ hana::to_tuple(S2{})))
+ )
+{ };
+
+//////////////////////////////////////////////////////////////////////////////
+// Transformation algorithms
+//
+// Differences from the MPL:
+// 1. The algorithms do not accept an optional inserter, and they always
+// return a `vector`.
+// 2. stable_partition: not implemented
+// 3. All the reverse_* algorithms are not implemented.
+//////////////////////////////////////////////////////////////////////////////
+template <typename Sequence>
+struct copy {
+ using type = decltype(hana::to_tuple(Sequence{}));
+};
+
+template <typename Sequence, typename Pred>
+struct copy_if {
+ using type = decltype(hana::filter(
+ hana::to_tuple(Sequence{}),
+ detail::mpl_predicate<Pred>
+ ));
+};
+
+template <typename Sequence, typename Sequence_or_Op, typename = void>
+struct transform;
+
+template <typename Sequence, typename Op>
+struct transform<Sequence, Op> {
+ using type = decltype(hana::transform(
+ hana::to_tuple(Sequence{}), detail::mpl_metafunction<Op>
+ ));
+};
+
+template <typename S1, typename S2, typename Op>
+struct transform {
+ using type = decltype(hana::zip_with(
+ detail::mpl_metafunction<Op>,
+ hana::to_tuple(S1{}),
+ hana::to_tuple(S2{})
+ ));
+};
+
+template <typename Sequence, typename OldType, typename NewType>
+struct replace {
+ using type = decltype(hana::replace(
+ hana::to_tuple(Sequence{}),
+ hana::type_c<OldType>,
+ hana::type_c<NewType>
+ ));
+};
+
+template <typename Sequence, typename Pred, typename NewType>
+struct replace_if {
+ using type = decltype(hana::replace_if(
+ hana::to_tuple(Sequence{}),
+ detail::mpl_predicate<Pred>,
+ hana::type_c<NewType>
+ ));
+};
+
+template <typename Sequence, typename T>
+struct remove {
+ using type = decltype(hana::filter(
+ hana::to_tuple(Sequence{}),
+ hana::not_equal.to(hana::type_c<T>)
+ ));
+};
+
+template <typename Sequence, typename Pred>
+struct remove_if {
+ using type = decltype(hana::filter(
+ hana::to_tuple(Sequence{}),
+ hana::compose(hana::not_, detail::mpl_predicate<Pred>)
+ ));
+};
+
+template <typename Sequence, typename Pred>
+struct unique {
+ using type = decltype(hana::unique(
+ hana::to_tuple(Sequence{}),
+ detail::mpl_predicate<Pred>
+ ));
+};
+
+template <typename Sequence, typename Pred>
+struct partition {
+ using hana_pair = decltype(hana::partition(
+ hana::to_tuple(Sequence{}),
+ detail::mpl_predicate<Pred>
+ ));
+ using type = pair<
+ decltype(hana::first(hana_pair{})),
+ decltype(hana::second(hana_pair{}))
+ >;
+};
+
+template <typename Sequence, typename Pred = mpl::quote2<less>>
+struct sort {
+ using type = decltype(hana::sort(
+ hana::to_tuple(Sequence{}), detail::mpl_predicate<Pred>
+ ));
+};
+
+template <typename Sequence>
+struct reverse {
+ using type = decltype(hana::reverse(hana::to_tuple(Sequence{})));
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Runtime algorithms
+//////////////////////////////////////////////////////////////////////////////
+template <typename Sequence, typename F>
+void for_each(F f) {
+ hana::for_each(Sequence{}, [&f](auto t) {
+ f(typename decltype(t)::type{});
+ });
+}
+
+template <typename Sequence, typename TransformOp, typename F>
+void for_each(F f) {
+ for_each<typename transform<Sequence, TransformOp>::type>(f);
+}
+
+} // end namespace hpl
+
+
+template <typename N>
+struct is_odd
+ : hpl::bool_<(N::value % 2)>
+{ };
+
+
+int main() {
+using namespace hpl;
+
+//////////////////////////////////////////////////////////////////////////////
+// Misc
+//////////////////////////////////////////////////////////////////////////////
+
+// pair
+{
+ static_assert(std::is_same<first<pair<int, float>>::type, int>{}, "");
+ static_assert(std::is_same<second<pair<int, float>>::type, float>{}, "");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Intrinsics
+//////////////////////////////////////////////////////////////////////////////
+
+// at
+{
+ using range = range_c<long,10,50>;
+ static_assert(at<range, int_<0>>::value == 10, "");
+ static_assert(at<range, int_<10>>::value == 20, "");
+ static_assert(at<range, int_<40>>::value == 50, "");
+}
+
+// at_c
+{
+ using range = range_c<long, 10, 50>;
+ static_assert(at_c<range, 0>::value == 10, "");
+ static_assert(at_c<range, 10>::value == 20, "");
+ static_assert(at_c<range, 40>::value == 50, "");
+}
+
+// back
+{
+ using range1 = range_c<int,0,1>;
+ using range2 = range_c<int,0,10>;
+ using range3 = range_c<int,-10,0>;
+ using types = vector<int, char, float>;
+ static_assert(back<range1>::value == 0, "");
+ static_assert(back<range2>::value == 9, "");
+ static_assert(back<range3>::value == -1, "");
+ static_assert(std::is_same<back<types>::type, float>{}, "");
+}
+
+// empty
+{
+ using empty_range = range_c<int,0,0>;
+ using types = vector<long,float,double>;
+ static_assert(empty<empty_range>{}, "");
+ static_assert(!empty<types>{}, "");
+}
+
+// front
+{
+ using types1 = vector<long>;
+ using types2 = vector<int,long>;
+ using types3 = vector<char,int,long>;
+ static_assert(std::is_same<front<types1>::type, long>{}, "");
+ static_assert(std::is_same<front<types2>::type, int>{}, "");
+ static_assert(std::is_same<front<types3>::type, char>{}, "");
+}
+
+// pop_back
+{
+ using types1 = vector<long>;
+ using types2 = vector<long,int>;
+ using types3 = vector<long,int,char>;
+
+
+ using result1 = pop_back<types1>::type;
+ using result2 = pop_back<types2>::type;
+ using result3 = pop_back<types3>::type;
+
+ static_assert(size<result1>::value == 0, "");
+ static_assert(size<result2>::value == 1, "");
+ static_assert(size<result3>::value == 2, "");
+
+ static_assert(std::is_same< back<result2>::type, long>{}, "");
+ static_assert(std::is_same< back<result3>::type, int>{}, "");
+}
+
+// pop_front
+{
+ using types1 = vector<long>;
+ using types2 = vector<int,long>;
+ using types3 = vector<char,int,long>;
+
+ using result1 = pop_front<types1>::type;
+ using result2 = pop_front<types2>::type;
+ using result3 = pop_front<types3>::type;
+
+ static_assert(size<result1>::value == 0, "");
+ static_assert(size<result2>::value == 1, "");
+ static_assert(size<result3>::value == 2, "");
+
+ static_assert(std::is_same<front<result2>::type, long>{}, "");
+ static_assert(std::is_same<front<result3>::type, int>{}, "");
+}
+
+// push_back
+{
+ using bools = vector_c<bool,false,false,false,true,true,true,false,false>;
+ using message = push_back<bools, false_>::type;
+ static_assert(back<message>::type::value == false, "");
+ static_assert(count_if<message, equal_to<mpl::_1, false_>>{} == 6u, "");
+}
+
+// push_front
+{
+ using v = vector_c<int,1,2,3,5,8,13,21>;
+ static_assert(size<v>{} == 7u, "");
+
+ using fibonacci = push_front<v, int_<1>>::type;
+ static_assert(size<fibonacci>{} == 8u, "");
+
+ static_assert(equal<
+ fibonacci,
+ vector_c<int,1,1,2,3,5,8,13,21>,
+ equal_to<mpl::_, mpl::_>
+ >{}, "");
+}
+
+// size
+{
+ using empty_list = vector<>;
+ using numbers = vector_c<int,0,1,2,3,4,5>;
+ using more_numbers = range_c<int,0,100>;
+
+ static_assert(size<empty_list>{} == 0u, "");
+ static_assert(size<numbers>{} == 6u, "");
+ static_assert(size<more_numbers>{} == 100u, "");
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Iteration algorithms
+//////////////////////////////////////////////////////////////////////////////
+
+// fold
+{
+ using types = vector<long,float,short,double,float,long,long double>;
+ using number_of_floats = fold<types, int_<0>,
+ mpl::if_<std::is_floating_point<mpl::_2>,
+ next<mpl::_1>,
+ mpl::_1
+ >
+ >::type;
+ static_assert(number_of_floats{} == 4, "");
+}
+
+// reverse_fold
+{
+ using numbers = vector_c<int,5,-1,0,-7,-2,0,-5,4>;
+ using negatives = vector_c<int,-1,-7,-2,-5>;
+ using result = reverse_fold<numbers, vector_c<int>,
+ mpl::if_<less<mpl::_2, int_<0>>,
+ push_front<mpl::_1, mpl::_2>,
+ mpl::_1
+ >
+ >::type;
+ static_assert(equal<negatives, result>{}, "");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Query algorithms
+//////////////////////////////////////////////////////////////////////////////
+
+// find_if
+{
+ using types = vector<char,int,unsigned,long,unsigned long>;
+ using found = find_if<types, std::is_same<mpl::_1, unsigned>>::type;
+ static_assert(std::is_same<found, unsigned>{}, "");
+}
+
+// find
+{
+ using types = vector<char,int,unsigned,long,unsigned long>;
+ static_assert(std::is_same<find<types, unsigned>::type, unsigned>{}, "");
+}
+
+// contains
+{
+ using types = vector<char,int,unsigned,long,unsigned long>;
+ static_assert(!contains<types, bool>{}, "");
+}
+
+// count
+{
+ using types = vector<int,char,long,short,char,short,double,long>;
+ static_assert(count<types, short>{} == 2u, "");
+}
+
+// count_if
+{
+ using types = vector<int,char,long,short,char,long,double,long>;
+ static_assert(count_if<types, std::is_floating_point<mpl::_>>{} == 1u, "");
+ static_assert(count_if<types, std::is_same<mpl::_, char>>{} == 2u, "");
+ static_assert(count_if<types, std::is_same<mpl::_, void>>{} == 0u, "");
+}
+
+// min_element (MPL's example is completely broken)
+{
+}
+
+// max_element (MPL's example is completely broken)
+{
+}
+
+// equal
+{
+ using s1 = vector<char,int,unsigned,long,unsigned long>;
+ using s2 = vector<char,int,unsigned,long>;
+ static_assert(!equal<s1,s2>{}, "");
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Transformaton algorithms
+//////////////////////////////////////////////////////////////////////////////
+// copy
+{
+ using numbers = vector_c<int,10, 11, 12, 13, 14, 15, 16, 17, 18, 19>;
+ using result = copy<range_c<int, 10, 20>>::type;
+ static_assert(size<result>{} == 10u, "");
+ static_assert(equal<result, numbers, mpl::quote2<equal_to>>{}, "");
+}
+
+// copy_if
+{
+ using result = copy_if<range_c<int, 0, 10>, less<mpl::_1, int_<5>>>::type;
+ static_assert(size<result>{} == 5u, "");
+ static_assert(equal<result, range_c<int, 0, 5>>{}, "");
+}
+
+// transform
+{
+ using types = vector<char,short,int,long,float,double>;
+ using pointers = vector<char*,short*,int*,long*,float*,double*>;
+ using result = transform<types,std::add_pointer<mpl::_1>>::type;
+ static_assert(equal<result, pointers>{}, "");
+}
+
+// replace
+{
+ using types = vector<int,float,char,float,float,double>;
+ using expected = vector<int,double,char,double,double,double>;
+ using result = replace< types,float,double >::type;
+ static_assert(equal<result, expected>{}, "");
+}
+
+// replace_if
+{
+ using numbers = vector_c<int,1,4,5,2,7,5,3,5>;
+ using expected = vector_c<int,1,4,0,2,0,0,3,0>;
+ using result = replace_if<numbers, greater<mpl::_, int_<4>>, int_<0>>::type;
+ static_assert(equal<result, expected, mpl::quote2<equal_to>>{}, "");
+}
+
+// remove
+{
+ using types = vector<int,float,char,float,float,double>;
+ using result = hpl::remove<types, float>::type;
+ static_assert(equal<result, vector<int, char, double>>{}, "");
+}
+
+// remove_if
+{
+ using numbers = vector_c<int,1,4,5,2,7,5,3,5>;
+ using result = remove_if<numbers, greater<mpl::_, int_<4> > >::type;
+ static_assert(equal<result, vector_c<int,1,4,2,3>, mpl::quote2<equal_to>>{}, "");
+}
+
+// unique
+{
+ using types = vector<int,float,float,char,int,int,int,double>;
+ using expected = vector<int,float,char,int,double>;
+ using result = unique<types, std::is_same<mpl::_1, mpl::_2>>::type;
+ static_assert(equal<result, expected>{}, "");
+}
+
+// partition
+{
+ using r = partition<range_c<int,0,10>, is_odd<mpl::_1>>::type;
+ static_assert(equal<first<r>::type, vector_c<int,1,3,5,7,9>>{}, "");
+ static_assert(equal<second<r>::type, vector_c<int,0,2,4,6,8>>{}, "");
+}
+
+// sort
+{
+ using numbers = vector_c<int,3,4,0,-5,8,-1,7>;
+ using expected = vector_c<int,-5,-1,0,3,4,7,8>;
+ using result = sort<numbers>::type;
+ static_assert(equal<result, expected, equal_to<mpl::_, mpl::_>>{}, "");
+}
+
+// reverse
+{
+ using numbers = vector_c<int,9,8,7,6,5,4,3,2,1,0>;
+ using result = reverse<numbers>::type;
+ static_assert(equal<result, range_c<int,0,10>>{}, "");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Runtime algorithms
+//////////////////////////////////////////////////////////////////////////////
+
+// for_each
+{
+ auto value_printer = [](auto x) {
+ std::cout << x << '\n';
+ };
+
+ for_each<range_c<int, 0, 10> >(value_printer);
+}
+
+}
diff --git a/src/boost/libs/hana/example/tutorial/concepts.cpp b/src/boost/libs/hana/example/tutorial/concepts.cpp
new file mode 100644
index 000000000..751b47309
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/concepts.cpp
@@ -0,0 +1,64 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/default.hpp>
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <string>
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+namespace with_special_base_class {
+//! [special_base_class]
+struct special_base_class { };
+
+template <typename T>
+struct print_impl : special_base_class {
+ template <typename ...Args>
+ static constexpr auto apply(Args&& ...) = delete;
+};
+
+template <typename T>
+struct Printable
+ : hana::integral_constant<bool,
+ !std::is_base_of<special_base_class, print_impl<hana::tag_of_t<T>>>::value
+ >
+{ };
+//! [special_base_class]
+
+//! [special_base_class_customize]
+struct Person { std::string name; };
+
+template <>
+struct print_impl<Person> /* don't inherit from special_base_class */ {
+ // ... implementation ...
+};
+
+static_assert(Printable<Person>::value, "");
+static_assert(!Printable<void>::value, "");
+//! [special_base_class_customize]
+}
+
+namespace actual {
+//! [actual]
+template <typename T>
+struct print_impl : hana::default_ {
+ template <typename ...Args>
+ static constexpr auto apply(Args&& ...) = delete;
+};
+
+template <typename T>
+struct Printable
+ : hana::integral_constant<bool,
+ !hana::is_default<print_impl<hana::tag_of_t<T>>>::value
+ >
+{ };
+//! [actual]
+
+static_assert(!Printable<void>::value, "");
+}
+
+int main() { }
diff --git a/src/boost/libs/hana/example/tutorial/constant_side_effects.cpp b/src/boost/libs/hana/example/tutorial/constant_side_effects.cpp
new file mode 100644
index 000000000..ea81ec08e
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/constant_side_effects.cpp
@@ -0,0 +1,36 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/bool.hpp>
+
+#include <iostream>
+namespace hana = boost::hana;
+
+
+namespace pure {
+//! [pure]
+template <typename X>
+auto identity(X x) { return x; }
+
+auto x = identity(hana::bool_c<true>);
+static_assert(hana::value(x), "");
+//! [pure]
+}
+
+namespace impure {
+//! [impure_identity]
+template <typename X>
+auto identity(X x) {
+ std::cout << "Good luck in evaluating this at compile-time!";
+ return x;
+}
+//! [impure_identity]
+
+//! [impure]
+auto x = identity(hana::bool_c<true>);
+static_assert(hana::value(x), "");
+//! [impure]
+}
+
+int main() { }
diff --git a/src/boost/libs/hana/example/tutorial/containers.cpp b/src/boost/libs/hana/example/tutorial/containers.cpp
new file mode 100644
index 000000000..fe9242704
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/containers.cpp
@@ -0,0 +1,106 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+
+#include <functional>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+namespace hana = boost::hana;
+using namespace hana::literals;
+using namespace std::literals;
+
+
+int main() {
+
+{
+
+//! [make<tuple_tag>]
+auto xs = hana::make<hana::tuple_tag>(1, 2.2, 'a', "bcde"s);
+//! [make<tuple_tag>]
+
+}{
+
+//! [make<range_tag>]
+constexpr auto r = hana::make<hana::range_tag>(hana::int_c<3>, hana::int_c<10>);
+static_assert(r == hana::make_range(hana::int_c<3>, hana::int_c<10>), "");
+//! [make<range_tag>]
+
+}{
+
+//! [tuple_constructor]
+hana::tuple<int, double, char, std::string> xs{1, 2.2, 'a', "bcde"s};
+//! [tuple_constructor]
+(void)xs;
+
+}{
+
+//! [types]
+auto xs = hana::make_tuple(1, '2', "345");
+auto ints = hana::make_range(hana::int_c<0>, hana::int_c<100>);
+// what can we say about the types of `xs` and `ints`?
+//! [types]
+(void)xs;
+(void)ints;
+
+}{
+
+//! [types_maximally_specified]
+hana::tuple<int, char, char const*> xs = hana::make_tuple(1, '2', "345");
+auto ints = hana::make_range(hana::int_c<0>, hana::int_c<100>);
+// can't specify the type of ints, however
+//! [types_maximally_specified]
+(void)xs;
+(void)ints;
+
+}{
+
+//! [lifetime]
+std::string hello = "Hello";
+std::vector<char> world = {'W', 'o', 'r', 'l', 'd'};
+
+// hello is copied, world is moved-in
+auto xs = hana::make_tuple(hello, std::move(world));
+
+// s is a reference to the copy of hello inside xs.
+// It becomes a dangling reference as soon as xs is destroyed.
+std::string& s = xs[0_c];
+//! [lifetime]
+(void)s;
+
+}{
+
+//! [reference_wrapper]
+std::vector<int> ints = { /* huge vector of ints */ };
+std::vector<std::string> strings = { /* huge vector of strings */ };
+
+auto map = hana::make_map(
+ hana::make_pair(hana::type_c<int>, std::ref(ints)),
+ hana::make_pair(hana::type_c<std::string>, std::ref(strings))
+);
+
+auto& v = map[hana::type_c<int>].get();
+BOOST_HANA_RUNTIME_CHECK(&v == &ints);
+//! [reference_wrapper]
+
+}
+
+}
+
+
+namespace overloading {
+//! [overloading]
+template <typename T>
+void f(std::vector<T> xs) {
+ // ...
+}
+
+template <typename R, typename = std::enable_if_t<hana::is_a<hana::range_tag, R>()>>
+void f(R r) {
+ // ...
+}
+//! [overloading]
+}
diff --git a/src/boost/libs/hana/example/tutorial/ext/fusion_to_hana.cpp b/src/boost/libs/hana/example/tutorial/ext/fusion_to_hana.cpp
new file mode 100644
index 000000000..8b6a334d4
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/ext/fusion_to_hana.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/ext/boost/fusion/vector.hpp>
+
+#include <boost/fusion/include/vector.hpp>
+
+#include <iostream>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+//! [main]
+// In the old code, this used to receive a Fusion sequence.
+// Now, it can be either a Hana sequence or a Fusion sequence.
+template <typename Sequence>
+void f(Sequence const& seq) {
+ hana::for_each(seq, [](auto const& element) {
+ std::cout << element << std::endl;
+ });
+}
+//! [main]
+
+
+int main() {
+ f(hana::make_tuple(1, 2, 3));
+ f(fusion::make_vector(1, 2, 3));
+}
diff --git a/src/boost/libs/hana/example/tutorial/ext/mpl_vector.cpp b/src/boost/libs/hana/example/tutorial/ext/mpl_vector.cpp
new file mode 100644
index 000000000..2802bafe6
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/ext/mpl_vector.cpp
@@ -0,0 +1,40 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/vector.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+//! [front]
+#include <boost/hana/ext/boost/mpl/vector.hpp> // bridge header
+
+using Vector = mpl::vector<int, char, float>;
+static_assert(hana::front(Vector{}) == hana::type_c<int>, "");
+//! [front]
+
+
+namespace _ns0 {
+//! [size]
+using Size = mpl::size<Vector>::type;
+static_assert(hana::equal(Size{}, hana::int_c<3>), ""); // breaks!
+//! [size]
+}
+
+
+//! [size-fixed]
+#include <boost/hana/ext/boost/mpl/integral_c.hpp>
+
+using Size = mpl::size<Vector>::type;
+static_assert(hana::equal(Size{}, hana::int_c<3>), "");
+//! [size-fixed]
+
+
+int main() { }
diff --git a/src/boost/libs/hana/example/tutorial/ext/ratio_plus.cpp b/src/boost/libs/hana/example/tutorial/ext/ratio_plus.cpp
new file mode 100644
index 000000000..e3c15546f
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/ext/ratio_plus.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+//! [main]
+#include <boost/hana/ext/std/ratio.hpp>
+#include <boost/hana/plus.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+auto r = hana::plus(std::ratio<3, 4>{}, std::ratio<4, 5>{});
+//! [main]
+
+int main() { }
diff --git a/src/boost/libs/hana/example/tutorial/include_ext.cpp b/src/boost/libs/hana/example/tutorial/include_ext.cpp
new file mode 100644
index 000000000..d753d6249
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/include_ext.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+//! [main]
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/front.hpp>
+#include <tuple> // still required to create a tuple
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr std::tuple<int, char, float> xs{1, '2', 3.0f};
+ static_assert(hana::front(xs) == 1, "");
+}
+//! [main]
diff --git a/src/boost/libs/hana/example/tutorial/integral-branching.cpp b/src/boost/libs/hana/example/tutorial/integral-branching.cpp
new file mode 100644
index 000000000..7e93f9402
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/integral-branching.cpp
@@ -0,0 +1,55 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+
+namespace ns1 {
+//! [make_unique.if_]
+template <typename T, typename ...Args>
+std::unique_ptr<T> make_unique(Args&&... args) {
+ return hana::if_(std::is_constructible<T, Args...>{},
+ [](auto&& ...x) { return std::unique_ptr<T>(new T(std::forward<Args>(x)...)); },
+ [](auto&& ...x) { return std::unique_ptr<T>(new T{std::forward<Args>(x)...}); }
+ )(std::forward<Args>(args)...);
+}
+//! [make_unique.if_]
+}
+
+
+namespace ns2 {
+//! [make_unique.eval_if]
+template <typename T, typename ...Args>
+std::unique_ptr<T> make_unique(Args&&... args) {
+ return hana::eval_if(std::is_constructible<T, Args...>{},
+ [&](auto _) { return std::unique_ptr<T>(new T(std::forward<Args>(_(args))...)); },
+ [&](auto _) { return std::unique_ptr<T>(new T{std::forward<Args>(_(args))...}); }
+ );
+}
+//! [make_unique.eval_if]
+}
+
+struct Student {
+ std::string name;
+ int age;
+};
+
+int main() {
+ {
+ std::unique_ptr<int> a = ns1::make_unique<int>(3);
+ std::unique_ptr<Student> b = ns1::make_unique<Student>("Bob", 25);
+ }
+ {
+ std::unique_ptr<int> a = ns2::make_unique<int>(3);
+ std::unique_ptr<Student> b = ns2::make_unique<Student>("Bob", 25);
+ }
+}
diff --git a/src/boost/libs/hana/example/tutorial/integral.cpp b/src/boost/libs/hana/example/tutorial/integral.cpp
new file mode 100644
index 000000000..be285c560
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/integral.cpp
@@ -0,0 +1,128 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+#include <boost/mpl/minus.hpp>
+#include <boost/mpl/multiplies.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/plus.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/constant.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/plus.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+namespace support {
+template <typename T, typename = std::enable_if_t<
+ !hana::Constant<T>::value
+>>
+constexpr T sqrt(T x) {
+ T inf = 0, sup = (x == 1 ? 1 : x/2);
+ while (!((sup - inf) <= 1 || ((sup*sup <= x) && ((sup+1)*(sup+1) > x)))) {
+ T mid = (inf + sup) / 2;
+ bool take_inf = mid*mid > x ? 1 : 0;
+ inf = take_inf ? inf : mid;
+ sup = take_inf ? mid : sup;
+ }
+
+ return sup*sup <= x ? sup : inf;
+}
+
+template <typename T, typename = std::enable_if_t<
+ hana::Constant<T>::value
+>>
+constexpr auto sqrt(T const&) {
+ return hana::integral_c<typename T::value_type, sqrt(T::value)>;
+}
+} // end namespace support
+
+
+namespace then {
+namespace mpl = boost::mpl;
+
+template <typename N>
+struct sqrt
+ : mpl::integral_c<typename N::value_type, support::sqrt(N::value)>
+{ };
+
+template <typename X, typename Y>
+struct point {
+ using x = X;
+ using y = Y;
+};
+
+//! [distance-mpl]
+template <typename P1, typename P2>
+struct distance {
+ using xs = typename mpl::minus<typename P1::x,
+ typename P2::x>::type;
+ using ys = typename mpl::minus<typename P1::y,
+ typename P2::y>::type;
+ using type = typename sqrt<
+ typename mpl::plus<
+ typename mpl::multiplies<xs, xs>::type,
+ typename mpl::multiplies<ys, ys>::type
+ >::type
+ >::type;
+};
+
+static_assert(mpl::equal_to<
+ distance<point<mpl::int_<3>, mpl::int_<5>>,
+ point<mpl::int_<7>, mpl::int_<2>>>::type,
+ mpl::int_<5>
+>::value, "");
+//! [distance-mpl]
+}
+
+
+namespace now {
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+template <typename X, typename Y>
+struct _point {
+ X x;
+ Y y;
+};
+template <typename X, typename Y>
+constexpr _point<X, Y> point(X x, Y y) { return {x, y}; }
+
+using support::sqrt; // avoid conflicts with ::sqrt
+
+//! [distance-hana]
+template <typename P1, typename P2>
+constexpr auto distance(P1 p1, P2 p2) {
+ auto xs = p1.x - p2.x;
+ auto ys = p1.y - p2.y;
+ return sqrt(xs*xs + ys*ys);
+}
+
+BOOST_HANA_CONSTANT_CHECK(distance(point(3_c, 5_c), point(7_c, 2_c)) == 5_c);
+//! [distance-hana]
+
+void test() {
+
+//! [distance-dynamic]
+auto p1 = point(3, 5); // dynamic values now
+auto p2 = point(7, 2); //
+BOOST_HANA_RUNTIME_CHECK(distance(p1, p2) == 5); // same function works!
+//! [distance-dynamic]
+
+}
+}
+
+
+int main() {
+ now::test();
+}
diff --git a/src/boost/libs/hana/example/tutorial/introduction.cpp b/src/boost/libs/hana/example/tutorial/introduction.cpp
new file mode 100644
index 000000000..1cafff047
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/introduction.cpp
@@ -0,0 +1,80 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+// Make sure `assert` always triggers an assertion
+#ifdef NDEBUG
+# undef NDEBUG
+#endif
+
+#include <boost/fusion/include/comparison.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/transform.hpp>
+#include <boost/fusion/include/vector.hpp>
+
+#include <boost/mpl/equal.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/transform.hpp>
+#include <boost/mpl/vector.hpp>
+
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <sstream>
+#include <string>
+#include <vector>
+namespace fusion = boost::fusion;
+namespace mpl = boost::mpl;
+using namespace std::literals;
+
+
+int main() {
+
+{
+
+//! [runtime]
+auto f = [](int i) -> std::string {
+ return std::to_string(i * i);
+};
+
+std::vector<int> ints{1, 2, 3, 4};
+std::vector<std::string> strings;
+std::transform(ints.begin(), ints.end(), std::back_inserter(strings), f);
+
+assert((strings == std::vector<std::string>{"1", "4", "9", "16"}));
+//! [runtime]
+
+}{
+
+//! [heterogeneous]
+auto to_string = [](auto t) {
+ std::stringstream ss;
+ ss << t;
+ return ss.str();
+};
+
+fusion::vector<int, std::string, float> seq{1, "abc", 3.4f};
+fusion::vector<std::string, std::string, std::string>
+ strings = fusion::transform(seq, to_string);
+
+assert(strings == fusion::make_vector("1"s, "abc"s, "3.4"s));
+//! [heterogeneous]
+
+}
+
+}
+
+//! [type-level]
+template <typename T>
+struct add_const_pointer {
+ using type = T const*;
+};
+
+using types = mpl::vector<int, char, float, void>;
+using pointers = mpl::transform<types, add_const_pointer<mpl::_1>>::type;
+
+static_assert(mpl::equal<
+ pointers,
+ mpl::vector<int const*, char const*, float const*, void const*>
+>::value, "");
+//! [type-level]
diff --git a/src/boost/libs/hana/example/tutorial/introspection.adapt.cpp b/src/boost/libs/hana/example/tutorial/introspection.adapt.cpp
new file mode 100644
index 000000000..bfdf4453c
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/introspection.adapt.cpp
@@ -0,0 +1,100 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+
+#include <iostream>
+#include <string>
+namespace hana = boost::hana;
+using namespace hana::literals;
+using namespace std::literals;
+
+
+//! [BOOST_HANA_DEFINE_STRUCT]
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (int, age)
+ );
+};
+//! [BOOST_HANA_DEFINE_STRUCT]
+
+int main() {
+
+//! [for_each]
+Person john{"John", 30};
+
+hana::for_each(john, [](auto pair) {
+ std::cout << hana::to<char const*>(hana::first(pair)) << ": "
+ << hana::second(pair) << std::endl;
+});
+
+// name: John
+// age: 30
+//! [for_each]
+
+//! [for_each.fuse]
+hana::for_each(john, hana::fuse([](auto name, auto member) {
+ std::cout << hana::to<char const*>(name) << ": " << member << std::endl;
+}));
+//! [for_each.fuse]
+
+#ifdef BOOST_HANA_CONFIG_ENABLE_STRING_UDL
+
+{
+
+//! [at_key]
+std::string name = hana::at_key(john, "name"_s);
+BOOST_HANA_RUNTIME_CHECK(name == "John");
+
+int age = hana::at_key(john, "age"_s);
+BOOST_HANA_RUNTIME_CHECK(age == 30);
+//! [at_key]
+
+}{
+
+//! [to<map_tag>]
+auto map = hana::insert(hana::to<hana::map_tag>(john), hana::make_pair("last name"_s, "Doe"s));
+
+std::string name = map["name"_s];
+BOOST_HANA_RUNTIME_CHECK(name == "John");
+
+std::string last_name = map["last name"_s];
+BOOST_HANA_RUNTIME_CHECK(last_name == "Doe");
+
+int age = map["age"_s];
+BOOST_HANA_RUNTIME_CHECK(age == 30);
+//! [to<map_tag>]
+
+}
+
+#endif
+
+}
+
+//! [BOOST_HANA_ADAPT_STRUCT]
+namespace not_my_namespace {
+ struct Person {
+ std::string name;
+ int age;
+ };
+}
+
+BOOST_HANA_ADAPT_STRUCT(not_my_namespace::Person, name, age);
+//! [BOOST_HANA_ADAPT_STRUCT]
+
+
+//! [BOOST_HANA_ADAPT_ADT]
+namespace also_not_my_namespace {
+ struct Person {
+ std::string get_name();
+ int get_age();
+ };
+}
+
+BOOST_HANA_ADAPT_ADT(also_not_my_namespace::Person,
+ (name, [](auto const& p) { return p.get_name(); }),
+ (age, [](auto const& p) { return p.get_age(); })
+);
+//! [BOOST_HANA_ADAPT_ADT]
diff --git a/src/boost/libs/hana/example/tutorial/introspection.cpp b/src/boost/libs/hana/example/tutorial/introspection.cpp
new file mode 100644
index 000000000..3b72db447
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/introspection.cpp
@@ -0,0 +1,158 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+
+#include <string>
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct yes { std::string toString() const { return "yes"; } };
+struct no { };
+
+namespace has_toString_then {
+//! [has_toString.then]
+template <typename T, typename = void>
+struct has_toString
+ : std::false_type
+{ };
+
+template <typename T>
+struct has_toString<T, decltype((void)std::declval<T>().toString())>
+ : std::true_type
+{ };
+//! [has_toString.then]
+
+static_assert(has_toString<yes>::value, "");
+static_assert(!has_toString<no>::value, "");
+}
+
+//! [has_toString.now]
+auto has_toString = hana::is_valid([](auto&& obj) -> decltype(obj.toString()) { });
+//! [has_toString.now]
+
+BOOST_HANA_CONSTANT_CHECK(has_toString(yes{}));
+BOOST_HANA_CONSTANT_CHECK(hana::not_(has_toString(no{})));
+
+namespace optionalToString_then {
+//! [optionalToString.then]
+template <typename T>
+auto optionalToString(T const& obj)
+ -> std::enable_if_t<decltype(has_toString(obj))::value, std::string>
+{ return obj.toString(); }
+
+template <typename T>
+auto optionalToString(T const& obj)
+ -> std::enable_if_t<decltype(!has_toString(obj))::value, std::string>
+{ return "toString not defined"; }
+//! [optionalToString.then]
+
+// make sure they compile
+template std::string optionalToString(yes const&);
+template std::string optionalToString(no const&);
+}
+
+//! [optionalToString]
+template <typename T>
+std::string optionalToString(T const& obj) {
+ return hana::if_(has_toString(obj),
+ [](auto& x) { return x.toString(); },
+ [](auto& x) { return "toString not defined"; }
+ )(obj);
+}
+//! [optionalToString]
+
+
+int main() {
+BOOST_HANA_RUNTIME_CHECK(optionalToString(yes{}) == "yes");
+BOOST_HANA_RUNTIME_CHECK(optionalToString(no{}) == "toString not defined");
+
+
+{
+
+//! [non_static_member_from_object]
+auto has_member = hana::is_valid([](auto&& x) -> decltype((void)x.member) { });
+
+struct Foo { int member[4]; };
+struct Bar { };
+BOOST_HANA_CONSTANT_CHECK(has_member(Foo{}));
+BOOST_HANA_CONSTANT_CHECK(!has_member(Bar{}));
+//! [non_static_member_from_object]
+
+}{
+
+//! [non_static_member_from_type]
+auto has_member = hana::is_valid([](auto t) -> decltype(
+ (void)hana::traits::declval(t).member
+) { });
+
+struct Foo { int member[4]; };
+struct Bar { };
+BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
+BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
+//! [non_static_member_from_type]
+
+}{
+
+//! [nested_type_name]
+auto has_member = hana::is_valid([](auto t) -> hana::type<
+ typename decltype(t)::type::member
+//^^^^^^^^ needed because of the dependent context
+> { });
+
+struct Foo { struct member; /* not defined! */ };
+struct Bar { };
+BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
+BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
+//! [nested_type_name]
+
+}
+
+}
+
+namespace static_member {
+//! [static_member]
+auto has_member = hana::is_valid([](auto t) -> decltype(
+ (void)decltype(t)::type::member
+) { });
+
+struct Foo { static int member[4]; };
+struct Bar { };
+BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
+BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
+//! [static_member]
+}
+
+namespace nested_template {
+//! [nested_template]
+auto has_member = hana::is_valid([](auto t) -> decltype(hana::template_<
+ decltype(t)::type::template member
+ // ^^^^^^^^ needed because of the dependent context
+>) { });
+
+struct Foo { template <typename ...> struct member; };
+struct Bar { };
+BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
+BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
+//! [nested_template]
+}
+
+namespace template_specialization {
+//! [template_specialization]
+template <typename T, typename U>
+struct Foo;
+
+template <typename T>
+struct Bar;
+
+auto is_binary_template = hana::is_valid([](auto trait) -> decltype(
+ trait(hana::type_c<void>, hana::type_c<void>)
+) { });
+
+BOOST_HANA_CONSTANT_CHECK(is_binary_template(hana::template_<Foo>));
+BOOST_HANA_CONSTANT_CHECK(!is_binary_template(hana::template_<Bar>));
+//! [template_specialization]
+}
diff --git a/src/boost/libs/hana/example/tutorial/introspection.json.cpp b/src/boost/libs/hana/example/tutorial/introspection.json.cpp
new file mode 100644
index 000000000..d81dd001a
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/introspection.json.cpp
@@ -0,0 +1,81 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+
+#include <iostream>
+#include <string>
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+//! [utilities]
+template <typename Xs>
+std::string join(Xs&& xs, std::string sep) {
+ return hana::fold(hana::intersperse(std::forward<Xs>(xs), sep), "", hana::_ + hana::_);
+}
+
+std::string quote(std::string s) { return "\"" + s + "\""; }
+
+template <typename T>
+auto to_json(T const& x) -> decltype(std::to_string(x)) {
+ return std::to_string(x);
+}
+
+std::string to_json(char c) { return quote({c}); }
+std::string to_json(std::string s) { return quote(s); }
+//! [utilities]
+
+//! [Struct]
+template <typename T>
+ std::enable_if_t<hana::Struct<T>::value,
+std::string> to_json(T const& x) {
+ auto json = hana::transform(hana::keys(x), [&](auto name) {
+ auto const& member = hana::at_key(x, name);
+ return quote(hana::to<char const*>(name)) + " : " + to_json(member);
+ });
+
+ return "{" + join(std::move(json), ", ") + "}";
+}
+//! [Struct]
+
+//! [Sequence]
+template <typename Xs>
+ std::enable_if_t<hana::Sequence<Xs>::value,
+std::string> to_json(Xs const& xs) {
+ auto json = hana::transform(xs, [](auto const& x) {
+ return to_json(x);
+ });
+
+ return "[" + join(std::move(json), ", ") + "]";
+}
+//! [Sequence]
+
+
+int main() {
+//! [usage]
+struct Car {
+ BOOST_HANA_DEFINE_STRUCT(Car,
+ (std::string, brand),
+ (std::string, model)
+ );
+};
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (std::string, last_name),
+ (int, age)
+ );
+};
+
+Car bmw{"BMW", "Z3"}, audi{"Audi", "A4"};
+Person john{"John", "Doe", 30};
+
+auto tuple = hana::make_tuple(john, audi, bmw);
+std::cout << to_json(tuple) << std::endl;
+//! [usage]
+}
diff --git a/src/boost/libs/hana/example/tutorial/introspection.sfinae.cpp b/src/boost/libs/hana/example/tutorial/introspection.sfinae.cpp
new file mode 100644
index 000000000..9b987ff9b
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/introspection.sfinae.cpp
@@ -0,0 +1,44 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+
+#include <string>
+#include <vector>
+namespace hana = boost::hana;
+
+
+struct yes { std::string toString() const { return "yes"; } };
+struct no { };
+
+//! [optionalToString.sfinae]
+template <typename T>
+std::string optionalToString(T const& obj) {
+ auto maybe_toString = hana::sfinae([](auto&& x) -> decltype(x.toString()) {
+ return x.toString();
+ });
+
+ return maybe_toString(obj).value_or("toString not defined");
+}
+//! [optionalToString.sfinae]
+
+int main() {
+BOOST_HANA_RUNTIME_CHECK(optionalToString(yes{}) == "yes");
+BOOST_HANA_RUNTIME_CHECK(optionalToString(no{}) == "toString not defined");
+
+{
+
+//! [maybe_add]
+auto maybe_add = hana::sfinae([](auto x, auto y) -> decltype(x + y) {
+ return x + y;
+});
+
+maybe_add(1, 2); // hana::just(3)
+
+std::vector<int> v;
+maybe_add(v, "foobar"); // hana::nothing
+//! [maybe_add]
+
+}
+}
diff --git a/src/boost/libs/hana/example/tutorial/mpl_cheatsheet.cpp b/src/boost/libs/hana/example/tutorial/mpl_cheatsheet.cpp
new file mode 100644
index 000000000..d9e87345a
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/mpl_cheatsheet.cpp
@@ -0,0 +1,58 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/boost/mpl/vector.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/vector.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+namespace with_mpl {
+//! [mpl]
+using types = mpl::vector<long, float, short, float, long, long double>;
+using number_of_floats = mpl::fold<
+ types,
+ mpl::int_<0>,
+ mpl::if_<std::is_floating_point<mpl::_2>,
+ mpl::next<mpl::_1>,
+ mpl::_1
+ >
+>::type;
+static_assert(number_of_floats::value == 3, "");
+//! [mpl]
+}
+
+namespace with_hana {
+//! [hana]
+constexpr auto types = hana::tuple_t<long, float, short, float, long, long double>;
+BOOST_HANA_CONSTEXPR_LAMBDA auto number_of_floats = hana::fold_left(
+ types,
+ hana::int_c<0>,
+ [](auto count, auto t) {
+ return hana::if_(hana::trait<std::is_floating_point>(t),
+ count + hana::int_c<1>,
+ count
+ );
+ }
+);
+BOOST_HANA_CONSTANT_CHECK(number_of_floats == hana::int_c<3>);
+//! [hana]
+}
+
+int main() { }
diff --git a/src/boost/libs/hana/example/tutorial/quickstart.cpp b/src/boost/libs/hana/example/tutorial/quickstart.cpp
new file mode 100644
index 000000000..6358e503b
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/quickstart.cpp
@@ -0,0 +1,101 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+// Make sure `assert` always triggers an assertion
+#ifdef NDEBUG
+# undef NDEBUG
+#endif
+
+//! [additional_setup]
+#include <cassert>
+#include <iostream>
+#include <string>
+
+struct Fish { std::string name; };
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+//! [additional_setup]
+
+//! [includes]
+#include <boost/hana.hpp>
+namespace hana = boost::hana;
+//! [includes]
+
+
+int main() {
+
+//! [animals]
+auto animals = hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});
+//! [animals]
+
+//! [algorithms]
+using namespace hana::literals;
+
+// Access tuple elements with operator[] instead of std::get.
+Cat garfield = animals[1_c];
+
+// Perform high level algorithms on tuples (this is like std::transform)
+auto names = hana::transform(animals, [](auto a) {
+ return a.name;
+});
+
+assert(hana::reverse(names) == hana::make_tuple("Snoopy", "Garfield", "Nemo"));
+//! [algorithms]
+
+
+//! [type-level]
+auto animal_types = hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Cat&>, hana::type_c<Dog>);
+
+auto no_pointers = hana::remove_if(animal_types, [](auto a) {
+ return hana::traits::is_pointer(a);
+});
+
+static_assert(no_pointers == hana::make_tuple(hana::type_c<Cat&>, hana::type_c<Dog>), "");
+//! [type-level]
+
+
+//! [has_name]
+auto has_name = hana::is_valid([](auto&& x) -> decltype((void)x.name) { });
+
+static_assert(has_name(garfield), "");
+static_assert(!has_name(1), "");
+//! [has_name]
+
+#if 0
+//! [screw_up]
+auto serialize = [](std::ostream& os, auto const& object) {
+ hana::for_each(os, [&](auto member) {
+ // ^^ oopsie daisy!
+ os << member << std::endl;
+ });
+};
+//! [screw_up]
+#endif
+
+//! [serialization]
+// 1. Give introspection capabilities to 'Person'
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (int, age)
+ );
+};
+
+// 2. Write a generic serializer (bear with std::ostream for the example)
+auto serialize = [](std::ostream& os, auto const& object) {
+ hana::for_each(hana::members(object), [&](auto member) {
+ os << member << std::endl;
+ });
+};
+
+// 3. Use it
+Person john{"John", 30};
+serialize(std::cout, john);
+
+// output:
+// John
+// 30
+//! [serialization]
+
+}
diff --git a/src/boost/libs/hana/example/tutorial/quickstart.switchAny.cpp b/src/boost/libs/hana/example/tutorial/quickstart.switchAny.cpp
new file mode 100644
index 000000000..4456aef32
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/quickstart.switchAny.cpp
@@ -0,0 +1,105 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+// Make sure `assert` always triggers an assertion
+#ifdef NDEBUG
+# undef NDEBUG
+#endif
+
+//! [full]
+#include <boost/hana.hpp>
+
+#include <boost/any.hpp>
+#include <cassert>
+#include <string>
+#include <typeindex>
+#include <typeinfo>
+#include <utility>
+namespace hana = boost::hana;
+
+//! [cases]
+template <typename T>
+auto case_ = [](auto f) {
+ return hana::make_pair(hana::type_c<T>, f);
+};
+
+struct default_t;
+auto default_ = case_<default_t>;
+//! [cases]
+
+//! [process]
+template <typename Any, typename Default>
+auto process(Any&, std::type_index const&, Default& default_) {
+ return default_();
+}
+
+template <typename Any, typename Default, typename Case, typename ...Rest>
+auto process(Any& a, std::type_index const& t, Default& default_,
+ Case& case_, Rest& ...rest)
+{
+ using T = typename decltype(+hana::first(case_))::type;
+ return t == typeid(T) ? hana::second(case_)(*boost::unsafe_any_cast<T>(&a))
+ : process(a, t, default_, rest...);
+}
+//! [process]
+
+//! [switch_]
+template <typename Any>
+auto switch_(Any& a) {
+ return [&a](auto ...cases_) {
+ auto cases = hana::make_tuple(cases_...);
+
+ auto default_ = hana::find_if(cases, [](auto const& c) {
+ return hana::first(c) == hana::type_c<default_t>;
+ });
+ static_assert(default_ != hana::nothing,
+ "switch is missing a default_ case");
+
+ auto rest = hana::filter(cases, [](auto const& c) {
+ return hana::first(c) != hana::type_c<default_t>;
+ });
+
+ return hana::unpack(rest, [&](auto& ...rest) {
+ return process(a, a.type(), hana::second(*default_), rest...);
+ });
+ };
+}
+//! [switch_]
+//! [full]
+
+
+int main() {
+using namespace std::literals;
+
+{
+
+//! [usage]
+boost::any a = 'x';
+std::string r = switch_(a)(
+ case_<int>([](auto i) { return "int: "s + std::to_string(i); }),
+ case_<char>([](auto c) { return "char: "s + std::string{c}; }),
+ default_([] { return "unknown"s; })
+);
+
+assert(r == "char: x"s);
+//! [usage]
+
+}{
+
+//! [result_inference]
+boost::any a = 'x';
+auto r = switch_(a)(
+ case_<int>([](auto) -> int { return 1; }),
+ case_<char>([](auto) -> long { return 2l; }),
+ default_([]() -> long long { return 3ll; })
+);
+
+// r is inferred to be a long long
+static_assert(std::is_same<decltype(r), long long>{}, "");
+assert(r == 2ll);
+//! [result_inference]
+
+}
+
+}
diff --git a/src/boost/libs/hana/example/tutorial/rationale.container.cpp b/src/boost/libs/hana/example/tutorial/rationale.container.cpp
new file mode 100644
index 000000000..9d419af15
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/rationale.container.cpp
@@ -0,0 +1,52 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+
+#include <boost/fusion/include/find_if.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/mpl/quote.hpp>
+
+#include <type_traits>
+namespace fusion = boost::fusion;
+namespace mpl = boost::mpl;
+namespace hana = boost::hana;
+
+
+int main() {
+
+{
+
+//! [hana]
+auto tuple = hana::make_tuple(1, 'x', 3.4f);
+
+auto result = hana::find_if(tuple, [](auto const& x) {
+ return hana::traits::is_integral(hana::typeid_(x));
+});
+//! [hana]
+(void)result;
+
+#if 0
+//! [hana-explicit]
+some_type result = hana::find_if(tuple, [](auto const& x) {
+ return hana::traits::is_integral(hana::typeid_(x));
+});
+//! [hana-explicit]
+#endif
+
+}{
+
+//! [fusion]
+using Container = fusion::result_of::make_vector<int, char, float>::type;
+Container tuple = fusion::make_vector(1, 'x', 3.4f);
+
+using Predicate = mpl::quote1<std::is_integral>;
+using Result = fusion::result_of::find_if<Container, Predicate>::type;
+Result result = fusion::find_if<Predicate>(tuple);
+//! [fusion]
+(void)result;
+
+}
+
+}
diff --git a/src/boost/libs/hana/example/tutorial/tag_dispatching.cpp b/src/boost/libs/hana/example/tutorial/tag_dispatching.cpp
new file mode 100644
index 000000000..19ca9d156
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/tag_dispatching.cpp
@@ -0,0 +1,170 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <cstddef>
+#include <iostream>
+#include <sstream>
+namespace hana = boost::hana;
+
+
+//! [setup]
+template <typename Tag>
+struct print_impl {
+ template <typename X>
+ static void apply(std::ostream&, X const&) {
+ // possibly some default implementation
+ }
+};
+
+template <typename X>
+void print(std::ostream& os, X x) {
+ using Tag = typename hana::tag_of<X>::type;
+ print_impl<Tag>::apply(os, x);
+}
+//! [setup]
+
+//! [vector]
+struct vector_tag;
+
+struct vector0 {
+ using hana_tag = vector_tag;
+ static constexpr std::size_t size = 0;
+};
+
+template <typename T1>
+struct vector1 {
+ T1 t1;
+ using hana_tag = vector_tag;
+ static constexpr std::size_t size = 1;
+
+ template <typename Index>
+ auto const& operator[](Index i) const {
+ static_assert(i == 0u, "index out of bounds");
+ return t1;
+ }
+};
+
+template <typename T1, typename T2>
+struct vector2 {
+ T1 t1; T2 t2;
+ using hana_tag = vector_tag;
+ static constexpr std::size_t size = 2;
+
+ // Using Hana as a backend to simplify the example.
+ template <typename Index>
+ auto const& operator[](Index i) const {
+ return *hana::make_tuple(&t1, &t2)[i];
+ }
+};
+
+// and so on...
+//! [vector]
+
+//! [customize]
+template <>
+struct print_impl<vector_tag> {
+ template <typename vectorN>
+ static void apply(std::ostream& os, vectorN xs) {
+ auto N = hana::size_c<vectorN::size>;
+
+ os << "[";
+ N.times.with_index([&](auto i) {
+ os << xs[i];
+ if (i != N - hana::size_c<1>) os << ", ";
+ });
+ os << "]";
+ }
+};
+//! [customize]
+
+#if 0
+//! [customize-when]
+template <typename Tag>
+struct print_impl<Tag, hana::when<Tag represents some kind of sequence>> {
+ template <typename Seq>
+ static void apply(std::ostream& os, Seq xs) {
+ // Some implementation for any sequence
+ }
+};
+//! [customize-when]
+#endif
+
+int main() {
+ {
+ std::stringstream ss;
+ vector0 v0;
+ print(ss, v0);
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "[]");
+ }
+
+ {
+ std::stringstream ss;
+ vector1<int> v1{1};
+ print(ss, v1);
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "[1]");
+ }
+
+ {
+ std::stringstream ss;
+ vector2<int, char> v2{1, 'x'};
+ print(ss, v2);
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "[1, x]");
+ }
+}
+
+namespace old_way {
+//! [old_way]
+void print(std::ostream& os, vector0)
+{ os << "[]"; }
+
+template <typename T1>
+void print(std::ostream& os, vector1<T1> v)
+{ os << "[" << v.t1 << "]"; }
+
+template <typename T1, typename T2>
+void print(std::ostream& os, vector2<T1, T2> v)
+{ os << "[" << v.t1 << ", " << v.t2 << "]"; }
+
+// and so on...
+//! [old_way]
+}
+
+namespace preconditions {
+//! [preconditions]
+template <typename X>
+void print(std::ostream& os, X x) {
+ // **** check some precondition ****
+
+ // The precondition only has to be checked here; implementations
+ // can assume their arguments to always be sane.
+
+ using Tag = typename hana::tag_of<X>::type;
+ print_impl<Tag>::apply(os, x);
+}
+//! [preconditions]
+}
+
+namespace function_objects {
+//! [function_objects]
+// Defining a function object is only needed once and implementations do not
+// have to worry about static initialization and other painful tricks.
+struct print_t {
+ template <typename X>
+ void operator()(std::ostream& os, X x) const {
+ using Tag = typename hana::tag_of<X>::type;
+ print_impl<Tag>::apply(os, x);
+ }
+};
+constexpr print_t print{};
+//! [function_objects]
+
+static_assert(sizeof(print) || true, "remove unused variable print warning");
+}
diff --git a/src/boost/libs/hana/example/tutorial/type.cpp b/src/boost/libs/hana/example/tutorial/type.cpp
new file mode 100644
index 000000000..92010d499
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/type.cpp
@@ -0,0 +1,260 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+
+#include <boost/mpl/copy_if.hpp>
+#include <boost/mpl/equal.hpp>
+#include <boost/mpl/less.hpp>
+#include <boost/mpl/min_element.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/sizeof.hpp>
+#include <boost/mpl/vector.hpp>
+
+#include <boost/fusion/include/at_key.hpp>
+#include <boost/fusion/include/equal_to.hpp>
+#include <boost/fusion/include/filter_if.hpp>
+#include <boost/fusion/include/make_map.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+
+#include <string>
+#include <type_traits>
+#include <vector>
+namespace fusion = boost::fusion;
+namespace mpl = boost::mpl;
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+template <int n>
+struct storage { char weight[n]; };
+
+int main() {
+
+{
+
+//! [tuple]
+auto types = hana::make_tuple(hana::type_c<int*>, hana::type_c<char&>, hana::type_c<void>);
+auto char_ref = types[1_c];
+
+BOOST_HANA_CONSTANT_CHECK(char_ref == hana::type_c<char&>);
+//! [tuple]
+
+}{
+
+//! [filter.MPL]
+using types = mpl::vector<int, char&, void*>;
+using ts = mpl::copy_if<types, mpl::or_<std::is_pointer<mpl::_1>,
+ std::is_reference<mpl::_1>>>::type;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// placeholder expression
+
+static_assert(mpl::equal<ts, mpl::vector<char&, void*>>::value, "");
+//! [filter.MPL]
+
+}{
+
+using hana::traits::is_pointer; // the traits namespace was not introduced
+using hana::traits::is_reference; // yet, so we use unqualified names for now
+
+//! [filter.Hana]
+auto types = hana::tuple_t<int*, char&, void>;
+
+auto ts = hana::filter(types, [](auto t) {
+ return is_pointer(t) || is_reference(t);
+});
+
+BOOST_HANA_CONSTANT_CHECK(ts == hana::tuple_t<int*, char&>);
+//! [filter.Hana]
+
+}{
+
+//! [single_library.then]
+// types (MPL)
+using types = mpl::vector<int*, char&, void>;
+using ts = mpl::copy_if<types, mpl::or_<std::is_pointer<mpl::_1>,
+ std::is_reference<mpl::_1>>>::type;
+
+// values (Fusion)
+auto values = fusion::make_vector(1, 'c', nullptr, 3.5);
+auto vs = fusion::filter_if<std::is_integral<mpl::_1>>(values);
+//! [single_library.then]
+
+static_assert(mpl::equal<ts, mpl::vector<int*, char&>>::value, "");
+BOOST_HANA_RUNTIME_CHECK(vs == fusion::make_vector(1, 'c'));
+
+}{
+
+using hana::traits::is_pointer;
+using hana::traits::is_reference;
+using hana::traits::is_integral;
+
+//! [single_library.Hana]
+// types
+auto types = hana::tuple_t<int*, char&, void>;
+auto ts = hana::filter(types, [](auto t) {
+ return is_pointer(t) || is_reference(t);
+});
+
+// values
+auto values = hana::make_tuple(1, 'c', nullptr, 3.5);
+auto vs = hana::filter(values, [](auto const& t) {
+ return is_integral(hana::typeid_(t));
+});
+//! [single_library.Hana]
+
+BOOST_HANA_CONSTANT_CHECK(ts == hana::tuple_t<int*, char&>);
+BOOST_HANA_RUNTIME_CHECK(vs == hana::make_tuple(1, 'c'));
+
+}{
+
+//! [make_map.Fusion]
+auto map = fusion::make_map<char, int, long, float, double, void>(
+ "char", "int", "long", "float", "double", "void"
+);
+
+std::string Int = fusion::at_key<int>(map);
+BOOST_HANA_RUNTIME_CHECK(Int == "int");
+//! [make_map.Fusion]
+
+}{
+
+//! [make_map.Hana]
+auto map = hana::make_map(
+ hana::make_pair(hana::type_c<char>, "char"),
+ hana::make_pair(hana::type_c<int>, "int"),
+ hana::make_pair(hana::type_c<long>, "long"),
+ hana::make_pair(hana::type_c<float>, "float"),
+ hana::make_pair(hana::type_c<double>, "double")
+);
+
+std::string Int = map[hana::type_c<int>];
+BOOST_HANA_RUNTIME_CHECK(Int == "int");
+//! [make_map.Hana]
+
+}{
+
+using hana::traits::add_pointer;
+
+//! [skip_first_step]
+auto types = hana::tuple_t<int*, char&, void>; // first step skipped
+
+auto pointers = hana::transform(types, [](auto t) {
+ return add_pointer(t);
+});
+//! [skip_first_step]
+
+BOOST_HANA_CONSTANT_CHECK(pointers == hana::tuple_t<int**, char*, void*>);
+
+}{
+
+//! [traits]
+BOOST_HANA_CONSTANT_CHECK(hana::traits::add_pointer(hana::type_c<int>) == hana::type_c<int*>);
+BOOST_HANA_CONSTANT_CHECK(hana::traits::common_type(hana::type_c<int>, hana::type_c<long>) == hana::type_c<long>);
+BOOST_HANA_CONSTANT_CHECK(hana::traits::is_integral(hana::type_c<int>));
+
+auto types = hana::tuple_t<int, char, long>;
+BOOST_HANA_CONSTANT_CHECK(hana::all_of(types, hana::traits::is_integral));
+//! [traits]
+
+}{
+
+//! [extent]
+auto extent = [](auto t, auto n) {
+ return std::extent<typename decltype(t)::type, hana::value(n)>{};
+};
+
+BOOST_HANA_CONSTANT_CHECK(extent(hana::type_c<char>, hana::int_c<1>) == hana::size_c<0>);
+BOOST_HANA_CONSTANT_CHECK(extent(hana::type_c<char[1][2]>, hana::int_c<1>) == hana::size_c<2>);
+//! [extent]
+
+}
+
+}
+
+namespace mpl_based {
+//! [smallest.MPL]
+template <typename ...T>
+struct smallest
+ : mpl::deref<
+ typename mpl::min_element<
+ mpl::vector<T...>,
+ mpl::less<mpl::sizeof_<mpl::_1>, mpl::sizeof_<mpl::_2>>
+ >::type
+ >
+{ };
+
+template <typename ...T>
+using smallest_t = typename smallest<T...>::type;
+
+static_assert(std::is_same<
+ smallest_t<char, long, long double>,
+ char
+>::value, "");
+//! [smallest.MPL]
+
+static_assert(std::is_same<
+ smallest_t<storage<3>, storage<1>, storage<2>>,
+ storage<1>
+>::value, "");
+} // end namespace mpl_based
+
+namespace hana_based {
+//! [smallest.Hana]
+template <typename ...T>
+auto smallest = hana::minimum(hana::make_tuple(hana::type_c<T>...), [](auto t, auto u) {
+ return hana::sizeof_(t) < hana::sizeof_(u);
+});
+
+template <typename ...T>
+using smallest_t = typename decltype(smallest<T...>)::type;
+
+static_assert(std::is_same<
+ smallest_t<char, long, long double>, char
+>::value, "");
+//! [smallest.Hana]
+
+static_assert(std::is_same<
+ smallest_t<storage<3>, storage<1>, storage<2>>,
+ storage<1>
+>::value, "");
+} // end namespace hana_based
+
+
+namespace metafunction1 {
+//! [metafunction1]
+template <template <typename> class F, typename T>
+constexpr auto metafunction(hana::basic_type<T> const&)
+{ return hana::type_c<typename F<T>::type>; }
+
+auto t = hana::type_c<int>;
+BOOST_HANA_CONSTANT_CHECK(metafunction<std::add_pointer>(t) == hana::type_c<int*>);
+//! [metafunction1]
+}
+
+namespace metafunction2 {
+//! [metafunction2]
+template <template <typename ...> class F, typename ...T>
+constexpr auto metafunction(hana::basic_type<T> const& ...)
+{ return hana::type_c<typename F<T...>::type>; }
+
+BOOST_HANA_CONSTANT_CHECK(
+ metafunction<std::common_type>(hana::type_c<int>, hana::type_c<long>) == hana::type_c<long>
+);
+//! [metafunction2]
+}
+
+namespace _template {
+//! [template_]
+template <template <typename ...> class F, typename ...T>
+constexpr auto template_(hana::basic_type<T> const& ...)
+{ return hana::type_c<F<T...>>; }
+
+BOOST_HANA_CONSTANT_CHECK(
+ template_<std::vector>(hana::type_c<int>) == hana::type_c<std::vector<int>>
+);
+//! [template_]
+}
diff --git a/src/boost/libs/hana/example/type/alignof.cpp b/src/boost/libs/hana/example/type/alignof.cpp
new file mode 100644
index 000000000..b4fb94525
--- /dev/null
+++ b/src/boost/libs/hana/example/type/alignof.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct X { };
+static_assert(hana::alignof_(hana::type_c<X>) == alignof(X), "");
+
+static_assert(hana::alignof_(1) == alignof(decltype(1)), "");
+static_assert(hana::alignof_(hana::type_c<int>) == alignof(int), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/basic_type.cpp b/src/boost/libs/hana/example/type/basic_type.cpp
new file mode 100644
index 000000000..e3104d655
--- /dev/null
+++ b/src/boost/libs/hana/example/type/basic_type.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <boost/core/demangle.hpp>
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+namespace hana = boost::hana;
+
+
+// Using hana::type<T> as a parameter type wouldn't work, since it may be
+// a dependent type, in which case template argument deduction will fail.
+// Using hana::basic_type<T> is fine, since this one is guaranteed to be
+// a non dependent base of hana::type<T>.
+template <typename T>
+std::string const& name_of(hana::basic_type<T>) {
+ static std::string name = boost::core::demangle(typeid(T).name());
+ return name;
+}
+
+int main() {
+ hana::for_each(hana::tuple_t<int, char, void, std::string>, [](auto type) {
+ std::cout << name_of(type) << std::endl;
+ });
+}
diff --git a/src/boost/libs/hana/example/type/comparable.cpp b/src/boost/libs/hana/example/type/comparable.cpp
new file mode 100644
index 000000000..19eb282bd
--- /dev/null
+++ b/src/boost/libs/hana/example/type/comparable.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct T;
+struct U;
+BOOST_HANA_CONSTANT_CHECK(hana::type_c<T> == hana::type_c<T>);
+BOOST_HANA_CONSTANT_CHECK(hana::type_c<T> != hana::type_c<U>);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/decltype.cpp b/src/boost/libs/hana/example/type/decltype.cpp
new file mode 100644
index 000000000..45110f1ac
--- /dev/null
+++ b/src/boost/libs/hana/example/type/decltype.cpp
@@ -0,0 +1,20 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct X { };
+BOOST_HANA_CONSTANT_CHECK(hana::decltype_(X{}) == hana::type_c<X>);
+BOOST_HANA_CONSTANT_CHECK(hana::decltype_(hana::type_c<X>) == hana::type_c<X>);
+
+BOOST_HANA_CONSTANT_CHECK(hana::decltype_(1) == hana::type_c<int>);
+
+static int const& i = 1;
+BOOST_HANA_CONSTANT_CHECK(hana::decltype_(i) == hana::type_c<int const>);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/hashable.cpp b/src/boost/libs/hana/example/type/hashable.cpp
new file mode 100644
index 000000000..eaecfff12
--- /dev/null
+++ b/src/boost/libs/hana/example/type/hashable.cpp
@@ -0,0 +1,23 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/hash.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+// `hana::hash` is the identity on `hana::type`s.
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::hash(hana::type_c<int>),
+ hana::type_c<int>
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::hash(hana::type_c<void>),
+ hana::type_c<void>
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/integral.cpp b/src/boost/libs/hana/example/type/integral.cpp
new file mode 100644
index 000000000..612665de9
--- /dev/null
+++ b/src/boost/libs/hana/example/type/integral.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+constexpr auto is_void = hana::integral(hana::metafunction<std::is_void>);
+BOOST_HANA_CONSTANT_CHECK(is_void(hana::type_c<void>));
+BOOST_HANA_CONSTANT_CHECK(hana::not_(is_void(hana::type_c<int>)));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/is_valid.cpp b/src/boost/libs/hana/example/type/is_valid.cpp
new file mode 100644
index 000000000..a683e78f1
--- /dev/null
+++ b/src/boost/libs/hana/example/type/is_valid.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+#include <vector>
+namespace hana = boost::hana;
+
+
+int main() {
+ // Checking for a member
+ struct Person { std::string name; };
+ auto has_name = hana::is_valid([](auto&& p) -> decltype((void)p.name) { });
+
+ Person joe{"Joe"};
+ static_assert(has_name(joe), "");
+ static_assert(!has_name(1), "");
+
+
+ // Checking for a nested type
+ auto has_value_type = hana::is_valid([](auto t) -> hana::type<
+ typename decltype(t)::type::value_type
+ > { });
+
+ static_assert(has_value_type(hana::type_c<std::vector<int>>), "");
+ static_assert(!has_value_type(hana::type_c<Person>), "");
+}
diff --git a/src/boost/libs/hana/example/type/make.cpp b/src/boost/libs/hana/example/type/make.cpp
new file mode 100644
index 000000000..97bb4a11f
--- /dev/null
+++ b/src/boost/libs/hana/example/type/make.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct X { };
+BOOST_HANA_CONSTANT_CHECK(hana::make<hana::type_tag>(X{}) == hana::type_c<X>);
+BOOST_HANA_CONSTANT_CHECK(hana::make<hana::type_tag>(hana::type_c<X>) == hana::type_c<X>);
+
+BOOST_HANA_CONSTANT_CHECK(hana::make_type(X{}) == hana::type_c<X>);
+BOOST_HANA_CONSTANT_CHECK(hana::make_type(hana::type_c<X>) == hana::type_c<X>);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/metafunction.cpp b/src/boost/libs/hana/example/type/metafunction.cpp
new file mode 100644
index 000000000..a60d60778
--- /dev/null
+++ b/src/boost/libs/hana/example/type/metafunction.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename ...> struct f { struct type; };
+struct x;
+struct y;
+
+BOOST_HANA_CONSTANT_CHECK(hana::metafunction<f>() == hana::type_c<f<>::type>);
+BOOST_HANA_CONSTANT_CHECK(hana::metafunction<f>(hana::type_c<x>) == hana::type_c<f<x>::type>);
+BOOST_HANA_CONSTANT_CHECK(hana::metafunction<f>(hana::type_c<x>, hana::type_c<y>) == hana::type_c<f<x, y>::type>);
+
+static_assert(std::is_same<
+ decltype(hana::metafunction<f>)::apply<x, y>::type,
+ f<x, y>::type
+>::value, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/metafunction_class.cpp b/src/boost/libs/hana/example/type/metafunction_class.cpp
new file mode 100644
index 000000000..f01e26719
--- /dev/null
+++ b/src/boost/libs/hana/example/type/metafunction_class.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct f { template <typename ...> struct apply { struct type; }; };
+struct x;
+struct y;
+
+BOOST_HANA_CONSTANT_CHECK(hana::metafunction_class<f>() == hana::type_c<f::apply<>::type>);
+BOOST_HANA_CONSTANT_CHECK(hana::metafunction_class<f>(hana::type_c<x>) == hana::type_c<f::apply<x>::type>);
+BOOST_HANA_CONSTANT_CHECK(hana::metafunction_class<f>(hana::type_c<x>, hana::type_c<y>) == hana::type_c<f::apply<x, y>::type>);
+
+static_assert(std::is_same<
+ decltype(hana::metafunction_class<f>)::apply<x, y>::type,
+ f::apply<x, y>::type
+>::value, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/sizeof.cpp b/src/boost/libs/hana/example/type/sizeof.cpp
new file mode 100644
index 000000000..300015dd2
--- /dev/null
+++ b/src/boost/libs/hana/example/type/sizeof.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct X { };
+static_assert(hana::sizeof_(hana::type_c<X>) == sizeof(X), "");
+
+static_assert(hana::sizeof_(1) == sizeof(1), "");
+static_assert(hana::sizeof_(hana::type_c<int>) == sizeof(int), "");
+
+int main() {}
diff --git a/src/boost/libs/hana/example/type/template.cpp b/src/boost/libs/hana/example/type/template.cpp
new file mode 100644
index 000000000..3840cc7c0
--- /dev/null
+++ b/src/boost/libs/hana/example/type/template.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename ...> struct f;
+struct x;
+struct y;
+
+BOOST_HANA_CONSTANT_CHECK(hana::template_<f>() == hana::type_c<f<>>);
+BOOST_HANA_CONSTANT_CHECK(hana::template_<f>(hana::type_c<x>) == hana::type_c<f<x>>);
+BOOST_HANA_CONSTANT_CHECK(hana::template_<f>(hana::type_c<x>, hana::type_c<y>) == hana::type_c<f<x, y>>);
+
+static_assert(std::is_same<
+ decltype(hana::template_<f>)::apply<x, y>::type,
+ f<x, y>
+>::value, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/trait.cpp b/src/boost/libs/hana/example/type/trait.cpp
new file mode 100644
index 000000000..31064bc7b
--- /dev/null
+++ b/src/boost/libs/hana/example/type/trait.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::trait<std::is_integral>(hana::type_c<int>));
+BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::trait<std::is_integral>(hana::type_c<float>)));
+
+int main() { }
diff --git a/src/boost/libs/hana/example/type/typeid.cpp b/src/boost/libs/hana/example/type/typeid.cpp
new file mode 100644
index 000000000..f219aec39
--- /dev/null
+++ b/src/boost/libs/hana/example/type/typeid.cpp
@@ -0,0 +1,36 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/remove_if.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Cat { std::string name; };
+struct Dog { std::string name; };
+struct Fish { std::string name; };
+
+bool operator==(Cat const& a, Cat const& b) { return a.name == b.name; }
+bool operator!=(Cat const& a, Cat const& b) { return a.name != b.name; }
+bool operator==(Dog const& a, Dog const& b) { return a.name == b.name; }
+bool operator!=(Dog const& a, Dog const& b) { return a.name != b.name; }
+bool operator==(Fish const& a, Fish const& b) { return a.name == b.name; }
+bool operator!=(Fish const& a, Fish const& b) { return a.name != b.name; }
+
+int main() {
+ hana::tuple<Cat, Fish, Dog, Fish> animals{
+ Cat{"Garfield"}, Fish{"Jaws"}, Dog{"Beethoven"}, Fish{"Nemo"}
+ };
+
+ auto mammals = hana::remove_if(animals, [](auto const& a) {
+ return hana::typeid_(a) == hana::type<Fish>{};
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(mammals == hana::make_tuple(Cat{"Garfield"}, Dog{"Beethoven"}));
+}
diff --git a/src/boost/libs/hana/example/unfold_left.cpp b/src/boost/libs/hana/example/unfold_left.cpp
new file mode 100644
index 000000000..4d77d01cf
--- /dev/null
+++ b/src/boost/libs/hana/example/unfold_left.cpp
@@ -0,0 +1,28 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unfold_left.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::unfold_left<hana::tuple_tag>(hana::int_c<10>, [](auto x) {
+ return hana::if_(x == hana::int_c<0>,
+ hana::nothing,
+ hana::just(hana::make_pair(x - hana::int_c<1>, x))
+ );
+ })
+ ==
+ hana::tuple_c<int, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10>
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/unfold_right.cpp b/src/boost/libs/hana/example/unfold_right.cpp
new file mode 100644
index 000000000..f4599ddcb
--- /dev/null
+++ b/src/boost/libs/hana/example/unfold_right.cpp
@@ -0,0 +1,28 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unfold_right.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(
+ hana::unfold_right<hana::tuple_tag>(hana::int_c<10>, [](auto x) {
+ return hana::if_(x == hana::int_c<0>,
+ hana::nothing,
+ hana::just(hana::make_pair(x, x - hana::int_c<1>))
+ );
+ })
+ ==
+ hana::tuple_c<int, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1>
+);
+
+int main() { }
diff --git a/src/boost/libs/hana/example/unique.cpp b/src/boost/libs/hana/example/unique.cpp
new file mode 100644
index 000000000..4f3b67c66
--- /dev/null
+++ b/src/boost/libs/hana/example/unique.cpp
@@ -0,0 +1,38 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/comparing.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+#include <boost/hana/unique.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+// unique without a predicate
+constexpr auto types = hana::tuple_t<int, float, float, char, int, int, int, double>;
+BOOST_HANA_CONSTANT_CHECK(
+ hana::unique(types) == hana::tuple_t<int, float, char, int, double>
+);
+
+int main() {
+ // unique with a predicate
+ auto objects = hana::make_tuple(1, 2, "abc"s, 'd', "efg"s, "hij"s, 3.4f);
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::unique(objects, [](auto const& t, auto const& u) {
+ return hana::typeid_(t) == hana::typeid_(u);
+ })
+ == hana::make_tuple(1, "abc"s, 'd', "efg"s, 3.4f)
+ );
+
+ // unique.by is syntactic sugar
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::unique.by(hana::comparing(hana::typeid_), objects) ==
+ hana::make_tuple(1, "abc"s, 'd', "efg"s, 3.4f)
+ );
+}
diff --git a/src/boost/libs/hana/example/unpack.cpp b/src/boost/libs/hana/example/unpack.cpp
new file mode 100644
index 000000000..f2ceb5da0
--- /dev/null
+++ b/src/boost/libs/hana/example/unpack.cpp
@@ -0,0 +1,18 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto add = [](auto x, auto y, auto z) {
+ return x + y + z;
+ };
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::unpack(hana::make_tuple(1, 2, 3), add) == 6);
+}
diff --git a/src/boost/libs/hana/example/value.cpp b/src/boost/libs/hana/example/value.cpp
new file mode 100644
index 000000000..d78f2878c
--- /dev/null
+++ b/src/boost/libs/hana/example/value.cpp
@@ -0,0 +1,14 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/value.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto i = hana::integral_c<int, 3>; // notice no constexpr
+ static_assert(hana::value<decltype(i)>() == 3, "");
+ static_assert(hana::value(i) == 3, "value(i) is always a constant expression!");
+}
diff --git a/src/boost/libs/hana/example/value_of.cpp b/src/boost/libs/hana/example/value_of.cpp
new file mode 100644
index 000000000..413cf6d00
--- /dev/null
+++ b/src/boost/libs/hana/example/value_of.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/value.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto xs = hana::tuple_c<int, 1, 2, 3, 4, 5>;
+ constexpr auto vs = hana::transform(xs, hana::value_of);
+ static_assert(vs == hana::make_tuple(1, 2, 3, 4, 5), "");
+}
diff --git a/src/boost/libs/hana/example/version.cpp b/src/boost/libs/hana/example/version.cpp
new file mode 100644
index 000000000..9d18fa9e7
--- /dev/null
+++ b/src/boost/libs/hana/example/version.cpp
@@ -0,0 +1,16 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+//! [main]
+#include <boost/hana/version.hpp>
+
+
+#if BOOST_HANA_VERSION < 0x01020003
+ // Hana's version is < 1.2.3
+#else
+ // Hana's version is >= 1.2.3
+#endif
+//! [main]
+
+int main() { }
diff --git a/src/boost/libs/hana/example/wandbox.cpp b/src/boost/libs/hana/example/wandbox.cpp
new file mode 100644
index 000000000..b56465d69
--- /dev/null
+++ b/src/boost/libs/hana/example/wandbox.cpp
@@ -0,0 +1,88 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana.hpp>
+
+#include <functional>
+#include <iostream>
+#include <string>
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+using namespace hana::literals;
+using namespace std::literals;
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Welcome to Hana!
+//
+// You can play around and press 'Run' at the bottom of this file to compile
+// and run this code.
+//
+// To get you started, here's a small JSON generator written with Hana
+// (this is explained in the tutorial if you're interested):
+//////////////////////////////////////////////////////////////////////////////
+
+// 1. Define some utilities
+template <typename Xs>
+std::string join(Xs&& xs, std::string sep) {
+ return hana::fold(hana::intersperse(std::forward<Xs>(xs), sep), "", std::plus<>{});
+}
+
+std::string quote(std::string s) { return "\"" + s + "\""; }
+
+template <typename T>
+auto to_json(T const& x) -> decltype(std::to_string(x)) {
+ return std::to_string(x);
+}
+
+std::string to_json(char c) { return quote({c}); }
+std::string to_json(std::string s) { return quote(s); }
+
+
+// 2. Define how to print user-defined types
+template <typename T>
+ std::enable_if_t<hana::Struct<T>::value,
+std::string> to_json(T const& x) {
+ auto json = hana::transform(hana::keys(x), [&](auto name) {
+ auto const& member = hana::at_key(x, name);
+ return quote(hana::to<char const*>(name)) + " : " + to_json(member);
+ });
+
+ return "{" + join(std::move(json), ", ") + "}";
+}
+
+// 3. Define how to print Sequences
+template <typename Xs>
+ std::enable_if_t<hana::Sequence<Xs>::value,
+std::string> to_json(Xs const& xs) {
+ auto json = hana::transform(xs, [](auto const& x) {
+ return to_json(x);
+ });
+
+ return "[" + join(std::move(json), ", ") + "]";
+}
+
+
+// 4. Create your own types and make them compatible with Hana.
+// This can be done intrusively or non-intrusively.
+struct Car {
+ BOOST_HANA_DEFINE_STRUCT(Car,
+ (std::string, brand),
+ (std::string, model)
+ );
+};
+
+int main() {
+ // 5. Generate beautiful JSON without hassle. Enjoy!
+ auto cars = hana::make_tuple(
+ Car{"BMW", "Z3"},
+ Car{"Audi", "A4"},
+ Car{"Ferrari", "F40"},
+ Car{"Lamborghini", "Diablo"}
+ // ...
+ );
+
+ std::cout << to_json(cars) << std::endl;
+}
diff --git a/src/boost/libs/hana/example/while.cpp b/src/boost/libs/hana/example/while.cpp
new file mode 100644
index 000000000..73dc27f91
--- /dev/null
+++ b/src/boost/libs/hana/example/while.cpp
@@ -0,0 +1,45 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/while.hpp>
+
+#include <vector>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+int main() {
+ // while_ with a Constant condition (loop is unrolled at compile-time)
+ {
+ std::vector<int> ints;
+ auto final_state = hana::while_(hana::less.than(10_c), 0_c, [&](auto i) {
+ ints.push_back(i);
+ return i + 1_c;
+ });
+
+ // The state is known at compile-time
+ BOOST_HANA_CONSTANT_CHECK(final_state == 10_c);
+
+ BOOST_HANA_RUNTIME_CHECK(ints == std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
+ }
+
+ // while_ with a constexpr or runtime condition (loop is not unrolled)
+ {
+ std::vector<int> ints;
+ int final_state = hana::while_(hana::less.than(10), 0, [&](int i) {
+ ints.push_back(i);
+ return i + 1;
+ });
+
+ // The state is known only at runtime, or at compile-time if constexpr
+ BOOST_HANA_RUNTIME_CHECK(final_state == 10);
+
+ BOOST_HANA_RUNTIME_CHECK(ints == std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
+ }
+}
diff --git a/src/boost/libs/hana/example/zero.cpp b/src/boost/libs/hana/example/zero.cpp
new file mode 100644
index 000000000..d6f92383b
--- /dev/null
+++ b/src/boost/libs/hana/example/zero.cpp
@@ -0,0 +1,15 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/zero.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTANT_CHECK(hana::zero<hana::integral_constant_tag<int>>() == hana::int_c<0>);
+static_assert(hana::zero<long>() == 0l, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/zip.cpp b/src/boost/libs/hana/example/zip.cpp
new file mode 100644
index 000000000..4c03c49af
--- /dev/null
+++ b/src/boost/libs/hana/example/zip.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/zip.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(
+ hana::zip(hana::make_tuple(1, 'a'), hana::make_tuple(2, 3.3))
+ ==
+ hana::make_tuple(hana::make_tuple(1, 2), hana::make_tuple('a', 3.3))
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/zip_shortest.cpp b/src/boost/libs/hana/example/zip_shortest.cpp
new file mode 100644
index 000000000..860a27e12
--- /dev/null
+++ b/src/boost/libs/hana/example/zip_shortest.cpp
@@ -0,0 +1,17 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/zip_shortest.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(
+ hana::zip_shortest(hana::make_tuple(1, 'a'), hana::make_tuple(2, 3.3), hana::make_tuple(3, 'c', "ignored"))
+ ==
+ hana::make_tuple(hana::make_tuple(1, 2, 3), hana::make_tuple('a', 3.3, 'c'))
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/example/zip_shortest_with.cpp b/src/boost/libs/hana/example/zip_shortest_with.cpp
new file mode 100644
index 000000000..ea5a40fa5
--- /dev/null
+++ b/src/boost/libs/hana/example/zip_shortest_with.cpp
@@ -0,0 +1,19 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/zip_shortest_with.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(
+ hana::zip_shortest_with(hana::mult, hana::make_tuple(1, 2, 3, 4), hana::make_tuple(5, 6, 7, 8, "ignored"))
+ ==
+ hana::make_tuple(5, 12, 21, 32)
+, "");
+
+
+int main() { }
diff --git a/src/boost/libs/hana/example/zip_with.cpp b/src/boost/libs/hana/example/zip_with.cpp
new file mode 100644
index 000000000..55ae01026
--- /dev/null
+++ b/src/boost/libs/hana/example/zip_with.cpp
@@ -0,0 +1,51 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+#include <boost/hana/unpack.hpp>
+#include <boost/hana/zip_with.hpp>
+
+#include <tuple>
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+// Basic usage:
+static_assert(
+ hana::zip_with(hana::mult, hana::make_tuple(1, 2, 3, 4), hana::make_tuple(5, 6, 7, 8))
+ ==
+ hana::make_tuple(5, 12, 21, 32)
+, "");
+
+
+
+// Example of computing a tuple of all the common types of several tuples:
+template<typename... Ts>
+using common_tuple_t = typename decltype(
+ hana::unpack(
+ hana::zip_with(
+ hana::metafunction<std::common_type>,
+ hana::transform(std::declval<Ts>(), hana::decltype_)...
+ ),
+ hana::template_<std::tuple>
+ )
+)::type;
+
+
+static_assert(std::is_same<
+ common_tuple_t<
+ std::tuple<bool, int, unsigned>,
+ std::tuple<char, long, long>,
+ std::tuple<int, long long, double>
+ >,
+ std::tuple<int, long long, double>
+>::value, "");
+
+int main() { }