summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/hana
parentInitial commit. (diff)
downloadceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz
ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/hana')
-rw-r--r--src/boost/libs/hana/CMakeLists.txt189
-rw-r--r--src/boost/libs/hana/CONTRIBUTING.md63
-rw-r--r--src/boost/libs/hana/LICENSE.md25
-rw-r--r--src/boost/libs/hana/README.md203
-rw-r--r--src/boost/libs/hana/RELEASE_NOTES.md5
-rw-r--r--src/boost/libs/hana/benchmark/CMakeLists.txt91
-rw-r--r--src/boost/libs/hana/benchmark/chart.html40
-rw-r--r--src/boost/libs/hana/benchmark/find_if/compile.erb.json53
-rw-r--r--src/boost/libs/hana/benchmark/find_if/compile.fusion.list.erb.cpp30
-rw-r--r--src/boost/libs/hana/benchmark/find_if/compile.fusion.vector.erb.cpp30
-rw-r--r--src/boost/libs/hana/benchmark/find_if/compile.hana.map.erb.cpp29
-rw-r--r--src/boost/libs/hana/benchmark/find_if/compile.hana.set.erb.cpp25
-rw-r--r--src/boost/libs/hana/benchmark/find_if/compile.hana.tuple.erb.cpp24
-rw-r--r--src/boost/libs/hana/benchmark/find_if/compile.meta.list.erb.cpp21
-rw-r--r--src/boost/libs/hana/benchmark/find_if/compile.mpl.vector.erb.cpp27
-rw-r--r--src/boost/libs/hana/benchmark/find_if/compile.std.integer_sequence.erb.cpp27
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/bloat.erb.json38
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.cexpr.recursive.erb.cpp53
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.cexpr.unrolled.erb.cpp43
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.erb.json61
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.fusion.list.erb.cpp31
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.fusion.vector.erb.cpp31
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.hana.basic_tuple.erb.cpp26
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.hana.tuple.erb.cpp25
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.meta.list.erb.cpp25
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.mpl.vector.erb.cpp24
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/compile.mpl11.list.erb.cpp26
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/execute.erb.json32
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/execute.fusion.list.erb.cpp32
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/execute.fusion.vector.erb.cpp32
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/execute.hana.tuple.erb.cpp26
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/execute.std.array.erb.cpp22
-rw-r--r--src/boost/libs/hana/benchmark/fold_left/execute.std.vector.erb.cpp22
-rw-r--r--src/boost/libs/hana/benchmark/including/baseline.erb.cpp6
-rw-r--r--src/boost/libs/hana/benchmark/including/compile.erb.json73
-rw-r--r--src/boost/libs/hana/benchmark/including/fusion.erb.cpp16
-rw-r--r--src/boost/libs/hana/benchmark/including/hana.erb.cpp8
-rw-r--r--src/boost/libs/hana/benchmark/including/meta.erb.cpp8
-rw-r--r--src/boost/libs/hana/benchmark/including/mpl.erb.cpp155
-rw-r--r--src/boost/libs/hana/benchmark/including/mpl11.erb.cpp8
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.erb.json58
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.fusion.list.erb.cpp15
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.fusion.vector.erb.cpp15
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.hana.basic_tuple.erb.cpp16
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.hana.tuple.erb.cpp16
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.meta.list.erb.cpp17
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.mpl.vector.erb.cpp14
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.mpl11.list.erb.cpp17
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.std.array.erb.cpp16
-rw-r--r--src/boost/libs/hana/benchmark/make/compile.std.tuple.erb.cpp16
-rw-r--r--src/boost/libs/hana/benchmark/measure.hpp29
-rwxr-xr-xsrc/boost/libs/hana/benchmark/measure.in.rb161
-rw-r--r--src/boost/libs/hana/benchmark/reverse/move.erb.json23
-rw-r--r--src/boost/libs/hana/benchmark/reverse/move.fusion.vector.erb.cpp33
-rw-r--r--src/boost/libs/hana/benchmark/reverse/move.hana.tuple.erb.cpp27
-rw-r--r--src/boost/libs/hana/benchmark/reverse/nomove.erb.json23
-rw-r--r--src/boost/libs/hana/benchmark/reverse/nomove.fusion.vector.erb.cpp33
-rw-r--r--src/boost/libs/hana/benchmark/reverse/nomove.hana.tuple.erb.cpp27
-rw-r--r--src/boost/libs/hana/benchmark/sort/compile.erb.json31
-rw-r--r--src/boost/libs/hana/benchmark/sort/compile.hana.tuple.rand.erb.cpp14
-rw-r--r--src/boost/libs/hana/benchmark/sort/compile.hana.tuple.reversed.erb.cpp14
-rw-r--r--src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted.erb.cpp14
-rw-r--r--src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted_but_first.erb.cpp14
-rw-r--r--src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted_but_last.erb.cpp14
-rw-r--r--src/boost/libs/hana/benchmark/transform/bloat.erb.json42
-rw-r--r--src/boost/libs/hana/benchmark/transform/compile.erb.json49
-rw-r--r--src/boost/libs/hana/benchmark/transform/compile.fusion.list.erb.cpp30
-rw-r--r--src/boost/libs/hana/benchmark/transform/compile.fusion.vector.erb.cpp30
-rw-r--r--src/boost/libs/hana/benchmark/transform/compile.hana.tuple.erb.cpp23
-rw-r--r--src/boost/libs/hana/benchmark/transform/compile.hana.types.erb.cpp26
-rw-r--r--src/boost/libs/hana/benchmark/transform/compile.meta.list.erb.cpp23
-rw-r--r--src/boost/libs/hana/benchmark/transform/compile.mpl.vector.erb.cpp22
-rw-r--r--src/boost/libs/hana/benchmark/transform/compile.mpl11.list.erb.cpp24
-rw-r--r--src/boost/libs/hana/benchmark/transform/execute.erb.json36
-rw-r--r--src/boost/libs/hana/benchmark/transform/execute.fusion.list.erb.cpp33
-rw-r--r--src/boost/libs/hana/benchmark/transform/execute.fusion.vector.erb.cpp33
-rw-r--r--src/boost/libs/hana/benchmark/transform/execute.hana.tuple.erb.cpp26
-rw-r--r--src/boost/libs/hana/benchmark/transform/execute.std.array.erb.cpp26
-rw-r--r--src/boost/libs/hana/benchmark/transform/execute.std.vector.erb.cpp27
-rw-r--r--src/boost/libs/hana/cmake/CheckCxxCompilerSupport.cmake85
-rw-r--r--src/boost/libs/hana/cmake/FindMPL11.cmake48
-rw-r--r--src/boost/libs/hana/cmake/FindMeta.cmake52
-rw-r--r--src/boost/libs/hana/cmake/TestHeaders.cmake128
-rw-r--r--src/boost/libs/hana/cmake/hana.pc.in5
-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
-rw-r--r--src/boost/libs/hana/hana.sublime-project38
-rw-r--r--src/boost/libs/hana/index.html17
-rw-r--r--src/boost/libs/hana/meta/libraries.json10
-rw-r--r--src/boost/libs/hana/test/CMakeLists.txt143
-rw-r--r--src/boost/libs/hana/test/Jamfile.v251
-rw-r--r--src/boost/libs/hana/test/_include/auto/README.md44
-rw-r--r--src/boost/libs/hana/test/_include/auto/all_of.hpp120
-rw-r--r--src/boost/libs/hana/test/_include/auto/any_of.hpp173
-rw-r--r--src/boost/libs/hana/test/_include/auto/ap.hpp76
-rw-r--r--src/boost/libs/hana/test/_include/auto/at.hpp91
-rw-r--r--src/boost/libs/hana/test/_include/auto/cartesian_product.hpp234
-rw-r--r--src/boost/libs/hana/test/_include/auto/drop_back.hpp99
-rw-r--r--src/boost/libs/hana/test/_include/auto/drop_front.hpp160
-rw-r--r--src/boost/libs/hana/test/_include/auto/drop_while.hpp72
-rw-r--r--src/boost/libs/hana/test/_include/auto/for_each.hpp64
-rw-r--r--src/boost/libs/hana/test/_include/auto/group.hpp150
-rw-r--r--src/boost/libs/hana/test/_include/auto/index_if.hpp81
-rw-r--r--src/boost/libs/hana/test/_include/auto/insert.hpp84
-rw-r--r--src/boost/libs/hana/test/_include/auto/insert_range.hpp105
-rw-r--r--src/boost/libs/hana/test/_include/auto/intersperse.hpp54
-rw-r--r--src/boost/libs/hana/test/_include/auto/is_empty.hpp55
-rw-r--r--src/boost/libs/hana/test/_include/auto/length.hpp48
-rw-r--r--src/boost/libs/hana/test/_include/auto/lexicographical_compare.hpp109
-rw-r--r--src/boost/libs/hana/test/_include/auto/make.hpp41
-rw-r--r--src/boost/libs/hana/test/_include/auto/none_of.hpp90
-rw-r--r--src/boost/libs/hana/test/_include/auto/partition.hpp74
-rw-r--r--src/boost/libs/hana/test/_include/auto/permutations.hpp87
-rw-r--r--src/boost/libs/hana/test/_include/auto/remove_at.hpp130
-rw-r--r--src/boost/libs/hana/test/_include/auto/remove_range.hpp114
-rw-r--r--src/boost/libs/hana/test/_include/auto/reverse.hpp55
-rw-r--r--src/boost/libs/hana/test/_include/auto/scans.hpp216
-rw-r--r--src/boost/libs/hana/test/_include/auto/sequence.hpp13
-rw-r--r--src/boost/libs/hana/test/_include/auto/slice.hpp182
-rw-r--r--src/boost/libs/hana/test/_include/auto/sort.hpp111
-rw-r--r--src/boost/libs/hana/test/_include/auto/span.hpp84
-rw-r--r--src/boost/libs/hana/test/_include/auto/take_back.hpp82
-rw-r--r--src/boost/libs/hana/test/_include/auto/take_front.hpp77
-rw-r--r--src/boost/libs/hana/test/_include/auto/take_while.hpp68
-rw-r--r--src/boost/libs/hana/test/_include/auto/test_case.hpp13
-rw-r--r--src/boost/libs/hana/test/_include/auto/transform.hpp74
-rw-r--r--src/boost/libs/hana/test/_include/auto/unfolds.hpp170
-rw-r--r--src/boost/libs/hana/test/_include/auto/unique.hpp158
-rw-r--r--src/boost/libs/hana/test/_include/auto/zips.hpp342
-rw-r--r--src/boost/libs/hana/test/_include/laws/applicative.hpp196
-rw-r--r--src/boost/libs/hana/test/_include/laws/base.hpp369
-rw-r--r--src/boost/libs/hana/test/_include/laws/comonad.hpp53
-rw-r--r--src/boost/libs/hana/test/_include/laws/comparable.hpp167
-rw-r--r--src/boost/libs/hana/test/_include/laws/constant.hpp106
-rw-r--r--src/boost/libs/hana/test/_include/laws/euclidean_ring.hpp99
-rw-r--r--src/boost/libs/hana/test/_include/laws/foldable.hpp1104
-rw-r--r--src/boost/libs/hana/test/_include/laws/functor.hpp250
-rw-r--r--src/boost/libs/hana/test/_include/laws/group.hpp93
-rw-r--r--src/boost/libs/hana/test/_include/laws/hashable.hpp60
-rw-r--r--src/boost/libs/hana/test/_include/laws/iterable.hpp195
-rw-r--r--src/boost/libs/hana/test/_include/laws/logical.hpp137
-rw-r--r--src/boost/libs/hana/test/_include/laws/monad.hpp222
-rw-r--r--src/boost/libs/hana/test/_include/laws/monad_plus.hpp616
-rw-r--r--src/boost/libs/hana/test/_include/laws/monoid.hpp86
-rw-r--r--src/boost/libs/hana/test/_include/laws/orderable.hpp182
-rw-r--r--src/boost/libs/hana/test/_include/laws/product.hpp46
-rw-r--r--src/boost/libs/hana/test/_include/laws/ring.hpp125
-rw-r--r--src/boost/libs/hana/test/_include/laws/searchable.hpp611
-rw-r--r--src/boost/libs/hana/test/_include/laws/sequence.hpp133
-rw-r--r--src/boost/libs/hana/test/_include/laws/templates/seq.hpp132
-rw-r--r--src/boost/libs/hana/test/_include/support/cnumeric.hpp66
-rw-r--r--src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp41
-rw-r--r--src/boost/libs/hana/test/_include/support/counter.hpp56
-rw-r--r--src/boost/libs/hana/test/_include/support/equivalence_class.hpp34
-rw-r--r--src/boost/libs/hana/test/_include/support/identity.hpp159
-rw-r--r--src/boost/libs/hana/test/_include/support/minimal_product.hpp61
-rw-r--r--src/boost/libs/hana/test/_include/support/numeric.hpp175
-rw-r--r--src/boost/libs/hana/test/_include/support/seq.hpp122
-rw-r--r--src/boost/libs/hana/test/_include/support/tracked.hpp120
-rw-r--r--src/boost/libs/hana/test/_include/support/tracked_move_only.hpp45
-rw-r--r--src/boost/libs/hana/test/assert/commas.cpp35
-rw-r--r--src/boost/libs/hana/test/assert/constant.cpp53
-rw-r--r--src/boost/libs/hana/test/assert/constexpr.cpp30
-rw-r--r--src/boost/libs/hana/test/assert/flexible.cpp34
-rw-r--r--src/boost/libs/hana/test/assert/lambdas.cpp25
-rw-r--r--src/boost/libs/hana/test/assert/runtime.cpp22
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/_specs.hpp15
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/all_of.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/any_of.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/ap.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/at.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/cartesian_product.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/drop_back.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/drop_front.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/drop_while.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/for_each.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/group.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/index_if.cpp9
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/insert.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/insert_range.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/intersperse.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/is_empty.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/length.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/lexicographical_compare.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/make.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/none_of.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/partition.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/permutations.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/remove_at.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/remove_range.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/reverse.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/scans.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/sequence.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/slice.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/sort.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/span.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/take_back.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/take_front.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/take_while.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/transform.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/unfolds.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/unique.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/auto/zips.cpp8
-rw-r--r--src/boost/libs/hana/test/basic_tuple/cnstr.copy.cpp86
-rw-r--r--src/boost/libs/hana/test/basic_tuple/construct.cpp19
-rw-r--r--src/boost/libs/hana/test/basic_tuple/laws.cpp35
-rw-r--r--src/boost/libs/hana/test/basic_tuple/length.cpp41
-rw-r--r--src/boost/libs/hana/test/basic_tuple/make.cpp18
-rw-r--r--src/boost/libs/hana/test/basic_tuple/unpack.cpp37
-rw-r--r--src/boost/libs/hana/test/builtin_array.cpp121
-rw-r--r--src/boost/libs/hana/test/comparable.cpp70
-rw-r--r--src/boost/libs/hana/test/concept/constant/arithmetic.cpp29
-rw-r--r--src/boost/libs/hana/test/concept/constant/comparable.cpp23
-rw-r--r--src/boost/libs/hana/test/concept/constant/laws.cpp25
-rw-r--r--src/boost/libs/hana/test/concept/constant/logical.cpp191
-rw-r--r--src/boost/libs/hana/test/concept/constant/mcd.cpp31
-rw-r--r--src/boost/libs/hana/test/concept/constant/minimal.hpp45
-rw-r--r--src/boost/libs/hana/test/concept/constant/orderable.cpp23
-rw-r--r--src/boost/libs/hana/test/concept/constant/to.cpp21
-rw-r--r--src/boost/libs/hana/test/concept/integral_constant.cpp52
-rw-r--r--src/boost/libs/hana/test/concept/sequence/iterable.cpp6
-rw-r--r--src/boost/libs/hana/test/concept/sequence/monad.cpp6
-rw-r--r--src/boost/libs/hana/test/concept/sequence/monad_plus.cpp6
-rw-r--r--src/boost/libs/hana/test/concept/sequence/orderable.cpp6
-rw-r--r--src/boost/libs/hana/test/concept/sequence/searchable.cpp6
-rw-r--r--src/boost/libs/hana/test/concept/sequence/sequence.cpp6
-rw-r--r--src/boost/libs/hana/test/concept/struct/any_of.cpp46
-rw-r--r--src/boost/libs/hana/test/concept/struct/at_key.cpp55
-rw-r--r--src/boost/libs/hana/test/concept/struct/equal.cpp47
-rw-r--r--src/boost/libs/hana/test/concept/struct/find_if.cpp48
-rw-r--r--src/boost/libs/hana/test/concept/struct/fold_left.cpp59
-rw-r--r--src/boost/libs/hana/test/concept/struct/fold_right.cpp59
-rw-r--r--src/boost/libs/hana/test/concept/struct/keys.cpp46
-rw-r--r--src/boost/libs/hana/test/concept/struct/laws.cpp43
-rw-r--r--src/boost/libs/hana/test/concept/struct/macro.adapt_adt.cpp61
-rw-r--r--src/boost/libs/hana/test/concept/struct/macro.adapt_struct.cpp58
-rw-r--r--src/boost/libs/hana/test/concept/struct/macro.define_struct.cpp57
-rw-r--r--src/boost/libs/hana/test/concept/struct/member_function.cpp43
-rw-r--r--src/boost/libs/hana/test/concept/struct/members.cpp51
-rw-r--r--src/boost/libs/hana/test/concept/struct/minimal_struct.hpp54
-rw-r--r--src/boost/libs/hana/test/concept/struct/unpack.cpp44
-rw-r--r--src/boost/libs/hana/test/core/common.cpp32
-rw-r--r--src/boost/libs/hana/test/core/default.cpp18
-rw-r--r--src/boost/libs/hana/test/core/is_a.cpp18
-rw-r--r--src/boost/libs/hana/test/core/is_embedded.cpp62
-rw-r--r--src/boost/libs/hana/test/core/make.cpp16
-rw-r--r--src/boost/libs/hana/test/core/tag_of.cpp74
-rw-r--r--src/boost/libs/hana/test/core/to.cpp106
-rw-r--r--src/boost/libs/hana/test/core/when.cpp24
-rw-r--r--src/boost/libs/hana/test/deploy/CMakeLists.txt10
-rw-r--r--src/boost/libs/hana/test/deploy/main.cpp8
-rw-r--r--src/boost/libs/hana/test/detail/algorithm.cpp56
-rw-r--r--src/boost/libs/hana/test/detail/any_of.cpp45
-rw-r--r--src/boost/libs/hana/test/detail/canonical_constant/laws.cpp56
-rw-r--r--src/boost/libs/hana/test/detail/create.cpp38
-rw-r--r--src/boost/libs/hana/test/detail/decay.cpp54
-rw-r--r--src/boost/libs/hana/test/detail/ebo.cpp95
-rw-r--r--src/boost/libs/hana/test/detail/fast_and.cpp32
-rw-r--r--src/boost/libs/hana/test/detail/first_unsatisfied_index.cpp47
-rw-r--r--src/boost/libs/hana/test/detail/has_duplicates.cpp57
-rw-r--r--src/boost/libs/hana/test/detail/preprocessor.cpp65
-rw-r--r--src/boost/libs/hana/test/detail/struct_macros.cpp108
-rw-r--r--src/boost/libs/hana/test/detail/type_at.cpp102
-rw-r--r--src/boost/libs/hana/test/detail/type_foldl1.cpp64
-rw-r--r--src/boost/libs/hana/test/detail/type_foldr1.cpp64
-rw-r--r--src/boost/libs/hana/test/detail/unpack_flatten.cpp114
-rw-r--r--src/boost/libs/hana/test/detail/variadic/at.cpp93
-rw-r--r--src/boost/libs/hana/test/detail/variadic/drop_into.cpp78
-rw-r--r--src/boost/libs/hana/test/detail/variadic/foldl1.cpp212
-rw-r--r--src/boost/libs/hana/test/detail/variadic/foldr1.cpp207
-rw-r--r--src/boost/libs/hana/test/detail/variadic/reverse_apply.cpp70
-rw-r--r--src/boost/libs/hana/test/detail/variadic/split_at.cpp168
-rw-r--r--src/boost/libs/hana/test/detail/variadic/take.cpp62
-rw-r--r--src/boost/libs/hana/test/euclidean_ring.cpp28
-rw-r--r--src/boost/libs/hana/test/experimental/printable/map.cpp51
-rw-r--r--src/boost/libs/hana/test/experimental/printable/metafunction.cpp45
-rw-r--r--src/boost/libs/hana/test/experimental/printable/optional.cpp29
-rw-r--r--src/boost/libs/hana/test/experimental/printable/pair.cpp38
-rw-r--r--src/boost/libs/hana/test/experimental/printable/set.cpp48
-rw-r--r--src/boost/libs/hana/test/experimental/printable/string.cpp45
-rw-r--r--src/boost/libs/hana/test/experimental/printable/tuple.cpp50
-rw-r--r--src/boost/libs/hana/test/experimental/printable/type.cpp35
-rw-r--r--src/boost/libs/hana/test/experimental/type_name.cpp50
-rw-r--r--src/boost/libs/hana/test/experimental/types/at.cpp80
-rw-r--r--src/boost/libs/hana/test/experimental/types/contains.cpp81
-rw-r--r--src/boost/libs/hana/test/experimental/types/drop_front.cpp100
-rw-r--r--src/boost/libs/hana/test/experimental/types/equal.cpp59
-rw-r--r--src/boost/libs/hana/test/experimental/types/is_empty.cpp34
-rw-r--r--src/boost/libs/hana/test/experimental/types/transform.cpp74
-rw-r--r--src/boost/libs/hana/test/experimental/types/unpack.cpp83
-rw-r--r--src/boost/libs/hana/test/experimental/view/empty/is_empty.cpp16
-rw-r--r--src/boost/libs/hana/test/experimental/view/empty/length.cpp21
-rw-r--r--src/boost/libs/hana/test/experimental/view/empty/unpack.cpp24
-rw-r--r--src/boost/libs/hana/test/experimental/view/joined/at.cpp97
-rw-r--r--src/boost/libs/hana/test/experimental/view/joined/is_empty.cpp43
-rw-r--r--src/boost/libs/hana/test/experimental/view/joined/length.cpp89
-rw-r--r--src/boost/libs/hana/test/experimental/view/joined/unpack.cpp81
-rw-r--r--src/boost/libs/hana/test/experimental/view/single/at.cpp24
-rw-r--r--src/boost/libs/hana/test/experimental/view/single/is_empty.cpp19
-rw-r--r--src/boost/libs/hana/test/experimental/view/single/length.cpp23
-rw-r--r--src/boost/libs/hana/test/experimental/view/single/unpack.cpp25
-rw-r--r--src/boost/libs/hana/test/experimental/view/sliced/at.cpp91
-rw-r--r--src/boost/libs/hana/test/experimental/view/sliced/is_empty.cpp49
-rw-r--r--src/boost/libs/hana/test/experimental/view/sliced/length.cpp68
-rw-r--r--src/boost/libs/hana/test/experimental/view/sliced/unpack.cpp135
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/ap.cpp122
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/at.cpp73
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/drop_front.cpp98
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/equal.cpp50
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/is_empty.cpp36
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/laziness.cpp20
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/length.cpp49
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/less.cpp58
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/transform.cpp57
-rw-r--r--src/boost/libs/hana/test/experimental/view/transformed/unpack.cpp34
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/_specs.hpp18
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/all_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/any_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/ap.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/cartesian_product.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/for_each.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/group.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/index_if.cpp9
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/insert.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/insert_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/intersperse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/is_empty.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/length.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/lexicographical_compare.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/make.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/none_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/partition.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/permutations.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/remove_at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/remove_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/reverse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/scans.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/sequence.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/slice.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/sort.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/span.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/transform.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/unfolds.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/unique.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/deque/auto/zips.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/_specs.hpp18
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/all_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/any_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/ap.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/cartesian_product.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/for_each.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/group.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/index_if.cpp9
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/insert.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/insert_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/intersperse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/is_empty.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/length.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/lexicographical_compare.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/make.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/none_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/partition.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/permutations.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/remove_at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/remove_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/reverse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/scans.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/sequence.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/slice.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/sort.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/span.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/transform.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/unfolds.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/unique.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/list/auto/zips.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/_specs.hpp19
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/all_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/any_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/ap.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/cartesian_product.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/for_each.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/group.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/index_if.cpp9
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/insert.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/insert_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/intersperse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/is_empty.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/length.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/lexicographical_compare.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/make.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/none_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/partition.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/permutations.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/remove_at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/remove_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/reverse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/scans.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/sequence.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/slice.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/sort.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/span.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/transform.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/unfolds.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/unique.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/zips.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/_specs.hpp19
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/all_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/any_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/ap.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/cartesian_product.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/for_each.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/group.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/index_if.cpp9
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/insert.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/insert_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/intersperse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/is_empty.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/length.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/lexicographical_compare.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/make.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/none_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/partition.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/permutations.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/remove_at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/remove_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/reverse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/scans.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/sequence.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/slice.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/sort.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/span.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/transform.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/unfolds.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/unique.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/fusion/vector/auto/zips.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/integral_c/arithmetic.cpp30
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/integral_c/comparable.cpp26
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/integral_c/constant.cpp32
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/integral_c/interop.cpp23
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/integral_c/logical.cpp66
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/integral_c/orderable.cpp24
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/integral_c/tag.cpp52
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/list/comparable.cpp28
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/list/foldable.cpp57
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/list/iterable.cpp95
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/list/searchable.cpp30
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/list/tag.cpp62
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/list/to.cpp49
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/vector/comparable.cpp28
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/vector/foldable.cpp57
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/vector/iterable.cpp95
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/vector/searchable.cpp30
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/vector/tag.cpp62
-rw-r--r--src/boost/libs/hana/test/ext/boost/mpl/vector/to.cpp49
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/_specs.hpp18
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/all_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/any_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/ap.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/cartesian_product.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/drop_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/drop_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/drop_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/for_each.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/group.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/index_if.cpp9
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/insert.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/insert_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/intersperse.broken.cpp10
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/is_empty.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/length.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/lexicographical_compare.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/make.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/none_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/partition.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/permutations.broken.cpp10
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/remove_at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/remove_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/reverse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/scans.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/sequence.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/slice.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/sort.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/span.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/take_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/take_front.broken.cpp10
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/take_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/transform.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/unfolds.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/unique.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/auto/zips.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/iterable.cpp36
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/monad.cpp52
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/monad_plus.cpp42
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/orderable.cpp47
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/searchable.cpp54
-rw-r--r--src/boost/libs/hana/test/ext/boost/tuple/tag_of.cpp63
-rw-r--r--src/boost/libs/hana/test/ext/std/array/at.cpp43
-rw-r--r--src/boost/libs/hana/test/ext/std/array/comparable.cpp29
-rw-r--r--src/boost/libs/hana/test/ext/std/array/foldable.cpp29
-rw-r--r--src/boost/libs/hana/test/ext/std/array/issue_304.cpp21
-rw-r--r--src/boost/libs/hana/test/ext/std/array/iterable.cpp83
-rw-r--r--src/boost/libs/hana/test/ext/std/array/orderable.cpp29
-rw-r--r--src/boost/libs/hana/test/ext/std/array/searchable.cpp31
-rw-r--r--src/boost/libs/hana/test/ext/std/bugs/libcxx_19616.cpp21
-rw-r--r--src/boost/libs/hana/test/ext/std/bugs/libcxx_22806.cpp21
-rw-r--r--src/boost/libs/hana/test/ext/std/integer_sequence/drop_front_exactly.cpp44
-rw-r--r--src/boost/libs/hana/test/ext/std/integer_sequence/equal.cpp52
-rw-r--r--src/boost/libs/hana/test/ext/std/integer_sequence/find_if.cpp101
-rw-r--r--src/boost/libs/hana/test/ext/std/integer_sequence/front.cpp31
-rw-r--r--src/boost/libs/hana/test/ext/std/integer_sequence/is_empty.cpp18
-rw-r--r--src/boost/libs/hana/test/ext/std/integer_sequence/laws.cpp37
-rw-r--r--src/boost/libs/hana/test/ext/std/integer_sequence/unpack.cpp47
-rw-r--r--src/boost/libs/hana/test/ext/std/integral_constant/arithmetic.cpp31
-rw-r--r--src/boost/libs/hana/test/ext/std/integral_constant/comparable.cpp27
-rw-r--r--src/boost/libs/hana/test/ext/std/integral_constant/constant.cpp33
-rw-r--r--src/boost/libs/hana/test/ext/std/integral_constant/interop.cpp22
-rw-r--r--src/boost/libs/hana/test/ext/std/integral_constant/logical.cpp63
-rw-r--r--src/boost/libs/hana/test/ext/std/integral_constant/orderable.cpp25
-rw-r--r--src/boost/libs/hana/test/ext/std/integral_constant/tag.cpp53
-rw-r--r--src/boost/libs/hana/test/ext/std/pair/first_second.cpp30
-rw-r--r--src/boost/libs/hana/test/ext/std/pair/issue_90.cpp44
-rw-r--r--src/boost/libs/hana/test/ext/std/pair/laws.cpp41
-rw-r--r--src/boost/libs/hana/test/ext/std/pair/make.cpp26
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/div.cpp24
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/equal.cpp34
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/laws.cpp37
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/less.cpp29
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/minus.cpp19
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/mod.cpp24
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/mult.cpp19
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/one.cpp24
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/plus.cpp19
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/to.cpp36
-rw-r--r--src/boost/libs/hana/test/ext/std/ratio/zero.cpp24
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/_specs.hpp17
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/all_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/any_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/ap.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/cartesian_product.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/drop_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/drop_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/drop_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/for_each.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/group.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/index_if.cpp9
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/insert.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/insert_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/intersperse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/is_empty.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/length.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/lexicographical_compare.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/make.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/none_of.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/partition.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/permutations.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/remove_at.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/remove_range.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/reverse.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/scans.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/sequence.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/slice.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/sort.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/span.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/take_back.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/take_front.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/take_while.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/transform.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/unfolds.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/unique.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/auto/zips.cpp8
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/issue_90.cpp73
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/laws.cpp43
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/laws.functor.cpp55
-rw-r--r--src/boost/libs/hana/test/ext/std/tuple/laws.searchable.cpp38
-rw-r--r--src/boost/libs/hana/test/ext/std/vector.cpp44
-rw-r--r--src/boost/libs/hana/test/fold_left/ref.cpp40
-rw-r--r--src/boost/libs/hana/test/fold_right/ref.cpp39
-rw-r--r--src/boost/libs/hana/test/foldable/fold_left_mcd/iterable.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/fold_left_mcd/monad.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/fold_left_mcd/monad_plus.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/fold_left_mcd/orderable.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/fold_left_mcd/searchable.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/fold_left_mcd/sequence.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/iterable_mcd/iterable.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/iterable_mcd/monad.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/iterable_mcd/monad_plus.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/iterable_mcd/orderable.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/iterable_mcd/searchable.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/iterable_mcd/sequence.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/unpack_mcd/iterable.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/unpack_mcd/monad.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/unpack_mcd/monad_plus.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/unpack_mcd/orderable.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/unpack_mcd/searchable.cpp7
-rw-r--r--src/boost/libs/hana/test/foldable/unpack_mcd/sequence.cpp7
-rw-r--r--src/boost/libs/hana/test/functional.cpp503
-rw-r--r--src/boost/libs/hana/test/functional/apply.cpp262
-rw-r--r--src/boost/libs/hana/test/functional/capture.cpp100
-rw-r--r--src/boost/libs/hana/test/functional/demux.cpp64
-rw-r--r--src/boost/libs/hana/test/functional/fix.cpp41
-rw-r--r--src/boost/libs/hana/test/functional/iterate.cpp151
-rw-r--r--src/boost/libs/hana/test/functional/lockstep.cpp36
-rw-r--r--src/boost/libs/hana/test/functional/overload_linearly.cpp122
-rw-r--r--src/boost/libs/hana/test/functional/partial.cpp64
-rw-r--r--src/boost/libs/hana/test/functional/placeholder.cpp119
-rw-r--r--src/boost/libs/hana/test/functional/reverse_partial.cpp65
-rw-r--r--src/boost/libs/hana/test/group.cpp24
-rw-r--r--src/boost/libs/hana/test/identity/applicative.full_mcd.cpp6
-rw-r--r--src/boost/libs/hana/test/identity/applicative.monad_mcd.cpp6
-rw-r--r--src/boost/libs/hana/test/identity/functor.adjust_mcd.cpp6
-rw-r--r--src/boost/libs/hana/test/identity/functor.transform_mcd.cpp6
-rw-r--r--src/boost/libs/hana/test/identity/main.hpp150
-rw-r--r--src/boost/libs/hana/test/identity/monad.chain_mcd.cpp6
-rw-r--r--src/boost/libs/hana/test/identity/monad.flatten_mcd.cpp6
-rw-r--r--src/boost/libs/hana/test/if_/non_copyable.cpp53
-rw-r--r--src/boost/libs/hana/test/index_if.cpp31
-rw-r--r--src/boost/libs/hana/test/integral_constant/arithmetic.cpp29
-rw-r--r--src/boost/libs/hana/test/integral_constant/comparable.cpp23
-rw-r--r--src/boost/libs/hana/test/integral_constant/constant.cpp38
-rw-r--r--src/boost/libs/hana/test/integral_constant/constexpr_init.cpp50
-rw-r--r--src/boost/libs/hana/test/integral_constant/github_354.cpp20
-rw-r--r--src/boost/libs/hana/test/integral_constant/hash.cpp110
-rw-r--r--src/boost/libs/hana/test/integral_constant/hashable.cpp26
-rw-r--r--src/boost/libs/hana/test/integral_constant/logical.cpp55
-rw-r--r--src/boost/libs/hana/test/integral_constant/operators.cpp57
-rw-r--r--src/boost/libs/hana/test/integral_constant/orderable.cpp23
-rw-r--r--src/boost/libs/hana/test/integral_constant/std_api.cpp44
-rw-r--r--src/boost/libs/hana/test/integral_constant/tag.cpp26
-rw-r--r--src/boost/libs/hana/test/integral_constant/times.cpp61
-rw-r--r--src/boost/libs/hana/test/integral_constant/udl.cpp75
-rw-r--r--src/boost/libs/hana/test/issues/clang_20046.cpp20
-rw-r--r--src/boost/libs/hana/test/issues/github_112.cpp29
-rw-r--r--src/boost/libs/hana/test/issues/github_113.cpp22
-rw-r--r--src/boost/libs/hana/test/issues/github_149.cpp12
-rw-r--r--src/boost/libs/hana/test/issues/github_15.cpp21
-rw-r--r--src/boost/libs/hana/test/issues/github_165.cpp34
-rw-r--r--src/boost/libs/hana/test/issues/github_202.cpp26
-rw-r--r--src/boost/libs/hana/test/issues/github_221.cpp452
-rw-r--r--src/boost/libs/hana/test/issues/github_234.cpp31
-rw-r--r--src/boost/libs/hana/test/issues/github_252.cpp38
-rw-r--r--src/boost/libs/hana/test/issues/github_260.cpp35
-rw-r--r--src/boost/libs/hana/test/issues/github_266.cpp17
-rw-r--r--src/boost/libs/hana/test/issues/github_269.cpp35
-rw-r--r--src/boost/libs/hana/test/issues/github_297.cpp22
-rw-r--r--src/boost/libs/hana/test/issues/github_31.cpp53
-rw-r--r--src/boost/libs/hana/test/issues/github_331.cpp57
-rw-r--r--src/boost/libs/hana/test/issues/github_362.cpp13
-rw-r--r--src/boost/libs/hana/test/issues/github_365.cpp61
-rw-r--r--src/boost/libs/hana/test/issues/github_75/tu1.cpp7
-rw-r--r--src/boost/libs/hana/test/issues/github_75/tu2.cpp5
-rw-r--r--src/boost/libs/hana/test/issues/github_91.cpp24
-rw-r--r--src/boost/libs/hana/test/lazy.cpp342
-rw-r--r--src/boost/libs/hana/test/logical.cpp84
-rw-r--r--src/boost/libs/hana/test/map/any_of.cpp52
-rw-r--r--src/boost/libs/hana/test/map/assign.copy.cpp57
-rw-r--r--src/boost/libs/hana/test/map/assign.move.cpp92
-rw-r--r--src/boost/libs/hana/test/map/at_key.collisions.cpp149
-rw-r--r--src/boost/libs/hana/test/map/at_key.cpp60
-rw-r--r--src/boost/libs/hana/test/map/at_key.ref.cpp84
-rw-r--r--src/boost/libs/hana/test/map/at_key.stackoverflow.cpp38
-rw-r--r--src/boost/libs/hana/test/map/cnstr.copy.cpp114
-rw-r--r--src/boost/libs/hana/test/map/cnstr.default.cpp74
-rw-r--r--src/boost/libs/hana/test/map/cnstr.move.cpp123
-rw-r--r--src/boost/libs/hana/test/map/cnstr.trap.cpp72
-rw-r--r--src/boost/libs/hana/test/map/cnstr.variadic.cpp186
-rw-r--r--src/boost/libs/hana/test/map/contains.cpp117
-rw-r--r--src/boost/libs/hana/test/map/difference.cpp106
-rw-r--r--src/boost/libs/hana/test/map/equal.cpp97
-rw-r--r--src/boost/libs/hana/test/map/erase_key.cpp70
-rw-r--r--src/boost/libs/hana/test/map/find_if.cpp52
-rw-r--r--src/boost/libs/hana/test/map/fold_left.cpp58
-rw-r--r--src/boost/libs/hana/test/map/fold_right.cpp58
-rw-r--r--src/boost/libs/hana/test/map/insert.cpp68
-rw-r--r--src/boost/libs/hana/test/map/intersection.cpp99
-rw-r--r--src/boost/libs/hana/test/map/is_subset.cpp51
-rw-r--r--src/boost/libs/hana/test/map/keys.cpp49
-rw-r--r--src/boost/libs/hana/test/map/laws.cpp37
-rw-r--r--src/boost/libs/hana/test/map/map.cpp33
-rw-r--r--src/boost/libs/hana/test/map/symmetric_difference.cpp80
-rw-r--r--src/boost/libs/hana/test/map/to.cpp92
-rw-r--r--src/boost/libs/hana/test/map/union.cpp82
-rw-r--r--src/boost/libs/hana/test/map/unpack.cpp50
-rw-r--r--src/boost/libs/hana/test/map/values.cpp48
-rw-r--r--src/boost/libs/hana/test/minimal_product.cpp55
-rw-r--r--src/boost/libs/hana/test/monoid.cpp26
-rw-r--r--src/boost/libs/hana/test/numeric/main.hpp511
-rw-r--r--src/boost/libs/hana/test/numeric/minus_mcd.cpp6
-rw-r--r--src/boost/libs/hana/test/numeric/negate_mcd.cpp6
-rw-r--r--src/boost/libs/hana/test/optional/any_of.cpp23
-rw-r--r--src/boost/libs/hana/test/optional/ap.cpp34
-rw-r--r--src/boost/libs/hana/test/optional/chain.cpp40
-rw-r--r--src/boost/libs/hana/test/optional/concat.cpp55
-rw-r--r--src/boost/libs/hana/test/optional/copy.trap_construct.cpp21
-rw-r--r--src/boost/libs/hana/test/optional/empty.cpp17
-rw-r--r--src/boost/libs/hana/test/optional/equal.cpp30
-rw-r--r--src/boost/libs/hana/test/optional/find_if.cpp38
-rw-r--r--src/boost/libs/hana/test/optional/flatten.cpp28
-rw-r--r--src/boost/libs/hana/test/optional/fold_left.cpp28
-rw-r--r--src/boost/libs/hana/test/optional/fold_right.cpp28
-rw-r--r--src/boost/libs/hana/test/optional/is_just.cpp16
-rw-r--r--src/boost/libs/hana/test/optional/is_nothing.cpp17
-rw-r--r--src/boost/libs/hana/test/optional/laws.cpp72
-rw-r--r--src/boost/libs/hana/test/optional/less.cpp52
-rw-r--r--src/boost/libs/hana/test/optional/lift.cpp20
-rw-r--r--src/boost/libs/hana/test/optional/make.cpp36
-rw-r--r--src/boost/libs/hana/test/optional/maybe.cpp28
-rw-r--r--src/boost/libs/hana/test/optional/nested_type.cpp33
-rw-r--r--src/boost/libs/hana/test/optional/operator_arrow.cpp37
-rw-r--r--src/boost/libs/hana/test/optional/operator_deref.cpp33
-rw-r--r--src/boost/libs/hana/test/optional/representation.cpp19
-rw-r--r--src/boost/libs/hana/test/optional/sfinae.cpp71
-rw-r--r--src/boost/libs/hana/test/optional/transform.cpp29
-rw-r--r--src/boost/libs/hana/test/optional/unpack.cpp34
-rw-r--r--src/boost/libs/hana/test/optional/value.cpp33
-rw-r--r--src/boost/libs/hana/test/optional/value_or.cpp26
-rw-r--r--src/boost/libs/hana/test/orderable.cpp126
-rw-r--r--src/boost/libs/hana/test/pair/assign.copy.cpp40
-rw-r--r--src/boost/libs/hana/test/pair/assign.move.cpp70
-rw-r--r--src/boost/libs/hana/test/pair/cnstr.copy.cpp94
-rw-r--r--src/boost/libs/hana/test/pair/cnstr.default.cpp71
-rw-r--r--src/boost/libs/hana/test/pair/cnstr.memberwise.cpp87
-rw-r--r--src/boost/libs/hana/test/pair/cnstr.move.cpp97
-rw-r--r--src/boost/libs/hana/test/pair/comparable.cpp33
-rw-r--r--src/boost/libs/hana/test/pair/empty_storage.cpp34
-rw-r--r--src/boost/libs/hana/test/pair/foldable.cpp31
-rw-r--r--src/boost/libs/hana/test/pair/issue_90.cpp43
-rw-r--r--src/boost/libs/hana/test/pair/make.cpp57
-rw-r--r--src/boost/libs/hana/test/pair/orderable.cpp46
-rw-r--r--src/boost/libs/hana/test/pair/product.cpp29
-rw-r--r--src/boost/libs/hana/test/pair/tag_of.cpp36
-rw-r--r--src/boost/libs/hana/test/range/at.cpp36
-rw-r--r--src/boost/libs/hana/test/range/back.cpp31
-rw-r--r--src/boost/libs/hana/test/range/contains.cpp56
-rw-r--r--src/boost/libs/hana/test/range/drop_front.cpp75
-rw-r--r--src/boost/libs/hana/test/range/drop_front_exactly.cpp63
-rw-r--r--src/boost/libs/hana/test/range/equal.cpp65
-rw-r--r--src/boost/libs/hana/test/range/find.cpp57
-rw-r--r--src/boost/libs/hana/test/range/front.cpp36
-rw-r--r--src/boost/libs/hana/test/range/is_empty.cpp26
-rw-r--r--src/boost/libs/hana/test/range/laws.cpp38
-rw-r--r--src/boost/libs/hana/test/range/length.cpp35
-rw-r--r--src/boost/libs/hana/test/range/make.cpp21
-rw-r--r--src/boost/libs/hana/test/range/maximum.cpp27
-rw-r--r--src/boost/libs/hana/test/range/minimum.cpp27
-rw-r--r--src/boost/libs/hana/test/range/product.cpp85
-rw-r--r--src/boost/libs/hana/test/range/range_c.cpp40
-rw-r--r--src/boost/libs/hana/test/range/sum.cpp85
-rw-r--r--src/boost/libs/hana/test/range/unpack.cpp45
-rw-r--r--src/boost/libs/hana/test/repeat.cpp45
-rw-r--r--src/boost/libs/hana/test/ring.cpp24
-rw-r--r--src/boost/libs/hana/test/searchable.cpp44
-rw-r--r--src/boost/libs/hana/test/set/any_of.cpp43
-rw-r--r--src/boost/libs/hana/test/set/cnstr.copy.cpp52
-rw-r--r--src/boost/libs/hana/test/set/cnstr.default.cpp77
-rw-r--r--src/boost/libs/hana/test/set/cnstr.move.cpp63
-rw-r--r--src/boost/libs/hana/test/set/cnstr.trap.cpp67
-rw-r--r--src/boost/libs/hana/test/set/difference.cpp67
-rw-r--r--src/boost/libs/hana/test/set/equal.cpp56
-rw-r--r--src/boost/libs/hana/test/set/erase_key.cpp62
-rw-r--r--src/boost/libs/hana/test/set/find_if.cpp50
-rw-r--r--src/boost/libs/hana/test/set/insert.cpp45
-rw-r--r--src/boost/libs/hana/test/set/intersection.cpp90
-rw-r--r--src/boost/libs/hana/test/set/is_subset.cpp45
-rw-r--r--src/boost/libs/hana/test/set/laws.cpp33
-rw-r--r--src/boost/libs/hana/test/set/make.cpp34
-rw-r--r--src/boost/libs/hana/test/set/symmetric_difference.cpp67
-rw-r--r--src/boost/libs/hana/test/set/to.cpp84
-rw-r--r--src/boost/libs/hana/test/set/union.cpp84
-rw-r--r--src/boost/libs/hana/test/set/unpack.cpp38
-rw-r--r--src/boost/libs/hana/test/string/any_of.cpp29
-rw-r--r--src/boost/libs/hana/test/string/at.cpp53
-rw-r--r--src/boost/libs/hana/test/string/c_str.cpp51
-rw-r--r--src/boost/libs/hana/test/string/cnstr.c_str.cpp59
-rw-r--r--src/boost/libs/hana/test/string/cnstr.copy.cpp16
-rw-r--r--src/boost/libs/hana/test/string/cnstr.default.cpp13
-rw-r--r--src/boost/libs/hana/test/string/contains.cpp32
-rw-r--r--src/boost/libs/hana/test/string/drop_front_exactly.cpp44
-rw-r--r--src/boost/libs/hana/test/string/equal.cpp52
-rw-r--r--src/boost/libs/hana/test/string/find.cpp29
-rw-r--r--src/boost/libs/hana/test/string/find_if.cpp36
-rw-r--r--src/boost/libs/hana/test/string/front.cpp28
-rw-r--r--src/boost/libs/hana/test/string/hash.cpp33
-rw-r--r--src/boost/libs/hana/test/string/is_empty.cpp21
-rw-r--r--src/boost/libs/hana/test/string/laws.cpp95
-rw-r--r--src/boost/libs/hana/test/string/length.cpp30
-rw-r--r--src/boost/libs/hana/test/string/less.cpp65
-rw-r--r--src/boost/libs/hana/test/string/macro.cpp31
-rw-r--r--src/boost/libs/hana/test/string/make.cpp39
-rw-r--r--src/boost/libs/hana/test/string/plus.cpp35
-rw-r--r--src/boost/libs/hana/test/string/to.cpp47
-rw-r--r--src/boost/libs/hana/test/string/udl.cpp24
-rw-r--r--src/boost/libs/hana/test/string/unpack.cpp42
-rw-r--r--src/boost/libs/hana/test/string/zero.cpp17
-rw-r--r--src/boost/libs/hana/test/tuple/any_of.clang_ice.cpp19
-rw-r--r--src/boost/libs/hana/test/tuple/assign.convert_copy.cpp59
-rw-r--r--src/boost/libs/hana/test/tuple/assign.convert_move.cpp73
-rw-r--r--src/boost/libs/hana/test/tuple/assign.copy.cpp43
-rw-r--r--src/boost/libs/hana/test/tuple/assign.move.cpp58
-rw-r--r--src/boost/libs/hana/test/tuple/at.const.cpp50
-rw-r--r--src/boost/libs/hana/test/tuple/at.non_const.cpp81
-rw-r--r--src/boost/libs/hana/test/tuple/at.rv.cpp40
-rw-r--r--src/boost/libs/hana/test/tuple/auto/_specs.hpp15
-rw-r--r--src/boost/libs/hana/test/tuple/auto/all_of.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/any_of.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/ap.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/at.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/cartesian_product.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/drop_back.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/drop_front.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/drop_while.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/for_each.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/group.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/index_if.cpp9
-rw-r--r--src/boost/libs/hana/test/tuple/auto/insert.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/insert_range.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/intersperse.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/is_empty.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/length.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/lexicographical_compare.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/make.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/none_of.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/partition.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/permutations.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/remove_at.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/remove_range.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/reverse.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/scans.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/sequence.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/slice.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/sort.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/span.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/take_back.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/take_front.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/take_while.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/transform.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/unfolds.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/unique.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/zips.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.convert_copy.cpp93
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.convert_move.cpp68
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.copy.cpp68
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.default.cpp138
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.move.cpp73
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.nested.cpp19
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.trap.cpp120
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.variadic_array.cpp19
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.variadic_copy.cpp125
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.variadic_forward.cpp114
-rw-r--r--src/boost/libs/hana/test/tuple/empty_member.cpp33
-rw-r--r--src/boost/libs/hana/test/tuple/hold_refs.cpp78
-rw-r--r--src/boost/libs/hana/test/tuple/issue_90.cpp72
-rw-r--r--src/boost/libs/hana/test/tuple/laws.cpp43
-rw-r--r--src/boost/libs/hana/test/tuple/laws.functor.cpp64
-rw-r--r--src/boost/libs/hana/test/tuple/laws.searchable.cpp40
-rw-r--r--src/boost/libs/hana/test/tuple/move_only.cpp55
-rw-r--r--src/boost/libs/hana/test/tuple/pair_interop.cpp75
-rw-r--r--src/boost/libs/hana/test/tuple/smart_ptr.cpp23
-rw-r--r--src/boost/libs/hana/test/tuple/special.drop_front_exactly.cpp46
-rw-r--r--src/boost/libs/hana/test/tuple/special.empty.cpp25
-rw-r--r--src/boost/libs/hana/test/tuple/special.equal.cpp76
-rw-r--r--src/boost/libs/hana/test/tuple/special.fill.cpp36
-rw-r--r--src/boost/libs/hana/test/tuple/special.fold_left.cpp68
-rw-r--r--src/boost/libs/hana/test/tuple/special.fold_right.cpp68
-rw-r--r--src/boost/libs/hana/test/tuple/special.front.cpp46
-rw-r--r--src/boost/libs/hana/test/tuple/special.is_empty.cpp28
-rw-r--r--src/boost/libs/hana/test/tuple/special.prepend.cpp30
-rw-r--r--src/boost/libs/hana/test/tuple/special.transform.cpp52
-rw-r--r--src/boost/libs/hana/test/tuple/to.cpp18
-rw-r--r--src/boost/libs/hana/test/tuple/unpack.cpp89
-rw-r--r--src/boost/libs/hana/test/tuple/usability_of_types.cpp41
-rw-r--r--src/boost/libs/hana/test/type/adl.cpp24
-rw-r--r--src/boost/libs/hana/test/type/alignof.cpp32
-rw-r--r--src/boost/libs/hana/test/type/decltype.cpp182
-rw-r--r--src/boost/libs/hana/test/type/equal.cpp35
-rw-r--r--src/boost/libs/hana/test/type/hash.cpp24
-rw-r--r--src/boost/libs/hana/test/type/inherit_basic_type.cpp17
-rw-r--r--src/boost/libs/hana/test/type/integral.cpp83
-rw-r--r--src/boost/libs/hana/test/type/is_valid.cpp206
-rw-r--r--src/boost/libs/hana/test/type/laws.cpp28
-rw-r--r--src/boost/libs/hana/test/type/make.cpp41
-rw-r--r--src/boost/libs/hana/test/type/metafunction.cpp72
-rw-r--r--src/boost/libs/hana/test/type/metafunction_class.cpp73
-rw-r--r--src/boost/libs/hana/test/type/nested_type.cpp18
-rw-r--r--src/boost/libs/hana/test/type/sizeof.cpp32
-rw-r--r--src/boost/libs/hana/test/type/template.cpp61
-rw-r--r--src/boost/libs/hana/test/type/traits.cpp154
-rw-r--r--src/boost/libs/hana/test/type/typeid.cpp182
-rw-r--r--src/boost/libs/hana/test/type/unary_plus.cpp39
1286 files changed, 53446 insertions, 0 deletions
diff --git a/src/boost/libs/hana/CMakeLists.txt b/src/boost/libs/hana/CMakeLists.txt
new file mode 100644
index 00000000..c025ba3f
--- /dev/null
+++ b/src/boost/libs/hana/CMakeLists.txt
@@ -0,0 +1,189 @@
+# Copyright Louis Dionne 2013-2017
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+cmake_minimum_required(VERSION 3.9)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+##############################################################################
+# Setup CMake options
+##############################################################################
+option(BOOST_HANA_ENABLE_CONCEPT_CHECKS "Enable concept checking in the interface methods." ON)
+option(BOOST_HANA_ENABLE_DEBUG_MODE "Enable Hana's debug mode." OFF)
+
+option(BOOST_HANA_ENABLE_STRING_UDL
+"Enable the GNU extension allowing the special string literal operator\
+ template, which enables the _s suffix for creating compile-time strings." ON)
+
+option(BOOST_HANA_ENABLE_EXCEPTIONS
+"Build with exceptions enabled. Note that Hana does not make use of exceptions,\
+ but this switch can be disabled when building the tests to assess that it is\
+ really the case." ON)
+
+
+##############################################################################
+# Setup project
+#
+# We parse the canonical version number located in <boost/hana/version.hpp>.
+# This is done to allow the library to be used without requiring a proper
+# installation during which the version would be written to this header.
+##############################################################################
+foreach(level MAJOR MINOR PATCH)
+ file(STRINGS include/boost/hana/version.hpp
+ _define_${level}
+ REGEX "#define BOOST_HANA_${level}_VERSION")
+ string(REGEX MATCH "([0-9]+)" _version_${level} "${_define_${level}}")
+endforeach()
+
+set(Boost.Hana_VERSION_STRING "${_version_MAJOR}.${_version_MINOR}.${_version_PATCH}")
+project(Boost.Hana VERSION ${Boost.Hana_VERSION_STRING} LANGUAGES CXX)
+
+# Perform checks to make sure we support the current compiler
+include(CheckCxxCompilerSupport)
+
+
+##############################################################################
+# Setup the 'hana' header-only library target, along with its install target
+# and exports.
+##############################################################################
+include(CheckCXXCompilerFlag)
+add_library(hana INTERFACE)
+target_include_directories(hana INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>")
+target_compile_features(hana INTERFACE cxx_std_14)
+
+# Export the `hana` library into a HanaConfig.cmake file
+install(TARGETS hana
+ EXPORT HanaConfig
+ INCLUDES DESTINATION include)
+install(EXPORT HanaConfig
+ DESTINATION lib/cmake/hana)
+install(DIRECTORY include/boost
+ DESTINATION include
+ FILES_MATCHING PATTERN "*.hpp")
+
+# Also install an optional pkg-config file
+configure_file(cmake/hana.pc.in hana.pc @ONLY)
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/hana.pc" DESTINATION lib/pkgconfig)
+
+
+##############################################################################
+# Function to setup common compiler flags on tests and examples
+##############################################################################
+function(boost_hana_set_test_properties target)
+ target_link_libraries(${target} PRIVATE hana)
+ set_target_properties(${target} PROPERTIES CXX_EXTENSIONS NO)
+
+ macro(setflag testname flag)
+ check_cxx_compiler_flag(${flag} ${testname})
+ if (${testname})
+ target_compile_options(${target} PRIVATE ${flag})
+ endif()
+ endmacro()
+
+ if (NOT MSVC)
+ setflag(BOOST_HANA_HAS_FDIAGNOSTICS_COLOR -fdiagnostics-color)
+ setflag(BOOST_HANA_HAS_FTEMPLATE_BACKTRACE_LIMIT -ftemplate-backtrace-limit=0)
+ setflag(BOOST_HANA_HAS_PEDANTIC -pedantic)
+ setflag(BOOST_HANA_HAS_WALL -Wall)
+ setflag(BOOST_HANA_HAS_WERROR -Werror)
+ setflag(BOOST_HANA_HAS_WEXTRA -Wextra)
+ setflag(BOOST_HANA_HAS_WNO_SELF_ASSIGN_OVERLOADED -Wno-self-assign-overloaded)
+ setflag(BOOST_HANA_HAS_WNO_UNUSED_LOCAL_TYPEDEFS -Wno-unused-local-typedefs)
+ setflag(BOOST_HANA_HAS_WWRITE_STRINGS -Wwrite-strings)
+ else()
+ setflag(BOOST_HANA_HAS_MSVC_EHSC -EHsc)
+ setflag(BOOST_HANA_HAS_MSVC_BIGOBJ -bigobj)
+ setflag(BOOST_HANA_HAS_MSVC_TERNARY -Zc:ternary)
+ endif()
+
+ if (NOT BOOST_HANA_ENABLE_EXCEPTIONS)
+ setflag(BOOST_HANA_HAS_FNO_EXCEPTIONS -fno-exceptions)
+ endif()
+
+ if (NOT BOOST_HANA_ENABLE_CONCEPT_CHECKS)
+ target_compile_definitions(${target} PRIVATE -DBOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS)
+ endif()
+
+ if (BOOST_HANA_ENABLE_DEBUG_MODE)
+ target_compile_definitions(${target} PRIVATE -DBOOST_HANA_CONFIG_ENABLE_DEBUG_MODE)
+ endif()
+
+ if (BOOST_HANA_ENABLE_STRING_UDL)
+ if (NOT MSVC)
+ target_compile_definitions(${target} PRIVATE -DBOOST_HANA_CONFIG_ENABLE_STRING_UDL)
+ # GCC pretends to have the flag, but produces a "unrecognized command line option"
+ # warning when we use it.
+ if (NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
+ setflag(BOOST_HANA_HAS_WNO_GNU_STRING_UDL -Wno-gnu-string-literal-operator-template)
+ endif()
+ endif()
+ endif()
+endfunction()
+
+
+##############################################################################
+# Look for the rest of Boost, which is an optional dependency of some tests.
+##############################################################################
+find_package(Boost 1.64)
+if (NOT Boost_FOUND)
+ message(WARNING "The rest of Boost was not found; some tests and examples will be disabled.")
+endif()
+
+
+##############################################################################
+# Setup custom functions to ease the creation of targets
+##############################################################################
+# boost_hana_target_name_for(<output variable> <source file> [ext])
+#
+# Return the target name associated to a source file. If the path of the
+# source file relative from the root of Hana is `path/to/source/file.ext`,
+# the target name associated to it will be `path.to.source.file`.
+#
+# The extension of the file should be specified as a last argument. If no
+# extension is specified, the `.cpp` extension is assumed.
+function(boost_hana_target_name_for out file)
+ if (NOT ARGV2)
+ set(_extension ".cpp")
+ else()
+ set(_extension "${ARGV2}")
+ endif()
+
+ file(RELATIVE_PATH _relative "${Boost.Hana_SOURCE_DIR}" "${file}")
+ string(REPLACE "${_extension}" "" _name "${_relative}")
+ string(REGEX REPLACE "/" "." _name "${_name}")
+ set(${out} "${_name}" PARENT_SCOPE)
+endfunction()
+
+
+##############################################################################
+# Setup the `check` target to build and then run all the tests and examples.
+##############################################################################
+add_custom_target(hana_check
+ COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ COMMENT "Build and then run all the tests and examples."
+ USES_TERMINAL)
+if (NOT TARGET check)
+ add_custom_target(check DEPENDS hana_check)
+else()
+ add_dependencies(check hana_check)
+endif()
+
+
+##############################################################################
+# Setup subdirectories and testing
+##############################################################################
+enable_testing()
+find_program(MEMORYCHECK_COMMAND valgrind)
+if (MEMORYCHECK_COMMAND)
+ message(STATUS "Found Valgrind: ${MEMORYCHECK_COMMAND}")
+ set(MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --error-exitcode=1")
+else()
+ message("Valgrind not found")
+endif()
+include(CTest)
+
+add_subdirectory(benchmark)
+add_subdirectory(doc)
+add_subdirectory(example)
+add_subdirectory(test)
diff --git a/src/boost/libs/hana/CONTRIBUTING.md b/src/boost/libs/hana/CONTRIBUTING.md
new file mode 100644
index 00000000..52d0858a
--- /dev/null
+++ b/src/boost/libs/hana/CONTRIBUTING.md
@@ -0,0 +1,63 @@
+# How to contribute
+
+Contributions are always very much appreciated. However, to make sure the
+process of accepting patches goes smoothly for everyone (especially for
+the maintainer), you should try to follow these few simple guidelines when
+you contribute:
+
+1. Fork the repository.
+2. Create a new branch based on the `develop` branch (`git checkout -b your_branch develop`).
+ If your contribution is a bug fix, you should name your branch `bugfix/xxx`;
+ for a feature, it should be `feature/xxx`. Otherwise, just use your good
+ judgment. Consistent naming of branches is appreciated since it makes the
+ output of `git branch` easier to understand with a single glance.
+3. Do your modifications on that branch. Except for special cases, your
+ contribution should include proper unit tests and documentation. Also,
+ please try to follow the style guide below.
+4. Make sure your modifications did not break anything by building and
+ running the tests:
+
+ ```shell
+ mkdir build
+ cd build
+ cmake ..
+ cmake --build . --target check
+ ```
+5. Commit your changes. Your commit message should start with a one line
+ short description of the modifications, with the details and explanations
+ of your modifications following in subsequent paragraphs or bullet points.
+ Please limit your lines to about 78 characters in commit messages, since
+ it makes the output easier to read in `git log`. Also, starting your commit
+ message with a tag describing the nature of the commit is nice, since it
+ makes the commit history easier to skim through. For commits that do not
+ change any functionality (e.g. refactoring or fixing typos), the `[NFC]`
+ tag (No Functionality Change) can be used. Here's an example of an
+ acceptable commit message:
+ ```
+ [Searchable] Refactor the interface
+
+ - Rename elem to contains
+ - Rename subset to is_subset, and make is_subset applicable in infix notation
+ - Add the at_key method
+ - operator[] is now bound to at_key instead of find
+ ```
+ When applicable, please squash adjacent _wip_ commits into a single
+ _logical_ commit. If your contribution has several logical commits,
+ it's fine.
+6. Push the changes to your fork (`git push origin your_branch`).
+7. Open a pull request against Hana's `develop` branch (not against `master`).
+ I will do my best to respond in a timely manner. I might discuss your patch
+ and suggest some modifications, or I might amend your patch myself and ask
+ you for feedback. You will always be given proper credit.
+
+
+## Style guide
+
+I'm not going to write an exhaustive style guide, but here are a couple of
+points you should watch out for:
+- Indent using 4 spaces.
+- Do not leave trailing white spaces at the end of lines, and no more than a
+ single newline at the end of a source file.
+- Hana's `#include`s go first, then a blank line and system headers.
+ `#include`s within each block should be sorted in alphabetical order.
+- Use your own judgment and stick to the style of the surrounding code.
diff --git a/src/boost/libs/hana/LICENSE.md b/src/boost/libs/hana/LICENSE.md
new file mode 100644
index 00000000..86391271
--- /dev/null
+++ b/src/boost/libs/hana/LICENSE.md
@@ -0,0 +1,25 @@
+Copyright Louis Dionne 2013-2017
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/src/boost/libs/hana/README.md b/src/boost/libs/hana/README.md
new file mode 100644
index 00000000..486295db
--- /dev/null
+++ b/src/boost/libs/hana/README.md
@@ -0,0 +1,203 @@
+# Boost.Hana <a target="_blank" href="http://semver.org">![Version][badge.version]</a> <a target="_blank" href="https://travis-ci.org/boostorg/hana">![Travis status][badge.Travis]</a> <a target="_blank" href="https://ci.appveyor.com/project/ldionne/hana">![Appveyor status][badge.Appveyor]</a> <a target="_blank" href="http://melpon.org/wandbox/permlink/g4ozIK33ITDtyGa3">![Try it online][badge.wandbox]</a> <a target="_blank" href="https://gitter.im/boostorg/hana">![Gitter Chat][badge.Gitter]</a>
+
+> Your standard library for metaprogramming
+
+## Overview
+<!-- Important: keep this in sync with example/overview.cpp -->
+```cpp
+#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), "");
+}
+```
+
+
+## Documentation
+You can browse the documentation online at http://boostorg.github.io/hana.
+The documentation covers everything you should need including installing the
+library, a tutorial explaining what Hana is and how to use it, and an extensive
+reference section with examples. The remainder of this README is mostly for
+people that wish to work on the library itself, not for its users.
+
+An offline copy of the documentation can be obtained by checking out the
+`gh-pages` branch. To avoid overwriting the current directory, you can clone
+the `gh-pages` branch into a subdirectory like `doc/html`:
+```shell
+git clone http://github.com/boostorg/hana --branch=gh-pages --depth=1 doc/html
+```
+
+After issuing this, `doc/html` will contain exactly the same static website
+that is [available online][Hana.docs]. Note that `doc/html` is automatically
+ignored by Git so updating the documentation won't pollute your index.
+
+
+## Hacking on Hana
+Setting yourself up to work on Hana is easy. First, you will need an
+installation of [CMake][]. Once this is done, you can `cd` to the root
+of the project and setup the build directory:
+```shell
+mkdir build
+cd build
+cmake ..
+```
+
+Usually, you'll want to specify a custom compiler because the system's
+compiler is too old:
+```shell
+cmake .. -DCMAKE_CXX_COMPILER=/path/to/compiler
+```
+
+Usually, this will work just fine. However, on some systems, the standard
+library and/or compiler provided by default does not support C++14. If
+this is your case, the [wiki][Hana.wiki] has more information about
+setting you up on different systems.
+
+Normally, Hana tries to find Boost headers if you have them on your system.
+It's also fine if you don't have them; a few tests requiring the Boost headers
+will be disabled in that case. However, if you'd like Hana to use a custom
+installation of Boost, you can specify the path to this custom installation:
+```shell
+cmake .. -DCMAKE_CXX_COMPILER=/path/to/compiler -DBOOST_ROOT=/path/to/boost
+```
+
+You can now build and run the unit tests and the examples:
+```shell
+cmake --build . --target check
+```
+
+You should be aware that compiling the unit tests is pretty time and RAM
+consuming, especially the tests for external adapters. This is due to the
+fact that Hana's unit tests are very thorough, and also that heterogeneous
+sequences in other libraries tend to have horrible compile-time performance.
+
+There are also optional targets which are enabled only when the required
+software is available on your computer. For example, generating the
+documentation requires [Doxygen][] to be installed. An informative message
+will be printed during the CMake generation step whenever an optional target
+is disabled. You can install any missing software and then re-run the CMake
+generation to update the list of available targets.
+
+> #### Tip
+> You can use the `help` target to get a list of all the available targets.
+
+If you want to add unit tests or examples, just add a source file in `test/`
+or `example/` and then re-run the CMake generation step so the new source
+file is known to the build system. Let's suppose the relative path from the
+root of the project to the new source file is `path/to/file.cpp`. When you
+re-run the CMake generation step, a new target named `path.to.file` will be
+created, and a test of the same name will also be created. Hence,
+```shell
+cd build # Go back to the build directory
+cmake --build . --target path.to.file # Builds the program associated to path/to/file.cpp
+ctest -R path.to.file # Runs the program as a test
+```
+
+> #### Tip for Sublime Text users
+> If you use the provided [hana.sublime-project](hana.sublime-project) file,
+> you can select the "[Hana] Build current file" build system. When viewing a
+> file to which a target is associated (like a test or an example), you can
+> then compile it by pressing ⌘B, or compile and then run it using ⇧⌘B.
+
+
+## Project organization
+The project is organized in a couple of subdirectories.
+- The [benchmark](benchmark) directory contains compile-time and runtime
+ benchmarks to make sure the library is as fast as advertised. The benchmark
+ code is written mostly in the form of [eRuby][] templates. The templates
+ are used to generate C++ files which are then compiled while gathering
+ compilation and execution statistics.
+- The [cmake](cmake) directory contains various CMake modules and other
+ scripts needed by the build system.
+- The [doc](doc) directory contains configuration files needed to generate
+ the documentation. The `doc/html` subdirectory is automatically ignored
+ by Git; you can conveniently store a local copy of the documentation by
+ cloning the `gh-pages` branch into that directory, as explained above.
+- The [example](example) directory contains the source code for all the
+ examples of both the tutorial and the reference documentation.
+- The [include](include) directory contains the library itself, which is
+ header only.
+- The [test](test) directory contains the source code for all the unit tests.
+
+
+## Contributing
+Please see [CONTRIBUTING.md](CONTRIBUTING.md).
+
+
+## License
+Please see [LICENSE.md](LICENSE.md).
+
+
+## Releasing
+This section acts as a reminder of the few simple steps required to release a
+new version of the library. This is only relevant to Hana's developers. To
+release a new version of the library, make sure the current version in
+`include/boost/hana/version.hpp` matches the release you're about to publish.
+Then, create an annotated tag with:
+```sh
+git tag -a --file=- v<version> <<EOM
+...your message here...
+EOM
+```
+
+Then, push the tag and create a new GitHub release pointing to that tag. Make
+sure to include the release notes in `RELEASE_NOTES.md` in that GitHub release.
+Once that is done, bump the version number in `include/boost/hana/version.hpp`
+so that it matches the next _planned_ release. Finally, do not forget to update
+the [Homebrew formula][] to point to the latest version.
+
+
+<!-- Links -->
+[badge.Appveyor]: https://ci.appveyor.com/api/projects/status/github/boostorg/hana?svg=true&branch=master
+[badge.Gitter]: https://img.shields.io/badge/gitter-join%20chat-blue.svg
+[badge.Travis]: https://travis-ci.org/boostorg/hana.svg?branch=master
+[badge.version]: https://badge.fury.io/gh/boostorg%2Fhana.svg
+[badge.Wandbox]: https://img.shields.io/badge/try%20it-online-blue.svg
+[CMake]: http://www.cmake.org
+[Doxygen]: http://www.doxygen.org
+[eRuby]: http://en.wikipedia.org/wiki/ERuby
+[Hana.docs]: http://boostorg.github.io/hana
+[Hana.wiki]: https://github.com/boostorg/hana/wiki
+[Homebrew formula]: https://github.com/Homebrew/homebrew-core/blob/master/Formula/hana.rb
diff --git a/src/boost/libs/hana/RELEASE_NOTES.md b/src/boost/libs/hana/RELEASE_NOTES.md
new file mode 100644
index 00000000..4163d5de
--- /dev/null
+++ b/src/boost/libs/hana/RELEASE_NOTES.md
@@ -0,0 +1,5 @@
+## These are the Release notes for the next release of Hana
+- Official support for Xcode 6, 7 and 8, and LLVM Clang 3.5, 3.6, 3.7, and 3.8
+ has has been dropped. The library should still work with these compilers,
+ however they are not being tested regularly anymore, so they are not
+ officially supported.
diff --git a/src/boost/libs/hana/benchmark/CMakeLists.txt b/src/boost/libs/hana/benchmark/CMakeLists.txt
new file mode 100644
index 00000000..21245456
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/CMakeLists.txt
@@ -0,0 +1,91 @@
+# Copyright Louis Dionne 2013-2017
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+##############################################################################
+# Required packages, gems and caveats
+##############################################################################
+find_package(Ruby 2.1)
+if(NOT ${RUBY_FOUND})
+ message(WARNING "Ruby >= 2.1 was not found; the benchmarks will be unavailable.")
+ return()
+endif()
+
+# Check for the 'ruby-progressbar' and 'tilt' gems
+execute_process(COMMAND ${RUBY_EXECUTABLE} -r ruby-progressbar -r tilt -e ""
+ RESULT_VARIABLE __BOOST_HANA_MISSING_GEMS
+ OUTPUT_QUIET ERROR_QUIET)
+if(${__BOOST_HANA_MISSING_GEMS})
+ message(WARNING
+ "The 'ruby-progressbar' and/or 'tilt' gems were not found; "
+ "the benchmarks will be unavailable."
+ "Use `gem install ruby-progressbar tilt` to install the missing gems.")
+ return()
+endif()
+
+# Some benchmarks depend on those libraries
+find_package(MPL11)
+find_package(Meta)
+
+include(CheckCXXCompilerFlag)
+check_cxx_compiler_flag(-ftemplate-depth=-1 BOOST_HANA_HAS_FTEMPLATE_DEPTH)
+
+##############################################################################
+# Configure the measure.rb script
+##############################################################################
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/measure.in.rb #input
+ ${CMAKE_CURRENT_BINARY_DIR}/measure.rb #output
+ @ONLY)
+
+##############################################################################
+# Add the benchmarks
+##############################################################################
+add_custom_target(benchmarks COMMENT "Generate all the benchmarks.")
+
+add_custom_target(travis_compiler_slug USES_TERMINAL
+ COMMAND ${CMAKE_COMMAND} -E echo "travis_compiler_slug: $<LOWER_CASE:${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}>")
+add_custom_target(travis_config_slug USES_TERMINAL
+ COMMAND ${CMAKE_COMMAND} -E echo "travis_config_slug: $<LOWER_CASE:$<CONFIG>>")
+
+file(GLOB_RECURSE BOOST_HANA_BENCHMARKS *.erb.json)
+foreach(benchmark IN LISTS BOOST_HANA_BENCHMARKS)
+ boost_hana_target_name_for(target ${benchmark} ".erb.json")
+ get_filename_component(directory "${benchmark}" DIRECTORY)
+ file(GLOB cpp_files "${directory}/*.erb.cpp")
+ configure_file("${benchmark}" "${CMAKE_CURRENT_BINARY_DIR}/${target}.erb.json" @ONLY)
+
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${target}.measure.cpp" "")
+ add_executable(${target}.measure EXCLUDE_FROM_ALL "${CMAKE_CURRENT_BINARY_DIR}/${target}.measure.cpp")
+ target_include_directories(${target}.measure PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
+ if (MPL11_FOUND)
+ target_include_directories(${target}.measure PRIVATE "${MPL11_INCLUDE_DIR}")
+ endif()
+ if (Meta_FOUND)
+ target_include_directories(${target}.measure PRIVATE "${Meta_INCLUDE_DIR}")
+ endif()
+ if (Boost_FOUND)
+ target_link_libraries(${target}.measure PRIVATE Boost::boost)
+ endif()
+ boost_hana_set_test_properties(${target}.measure)
+ if (BOOST_HANA_HAS_FTEMPLATE_DEPTH)
+ target_compile_options(${target}.measure PRIVATE -ftemplate-depth=-1)
+ endif()
+ set_target_properties(${target}.measure PROPERTIES RULE_LAUNCH_COMPILE "${CMAKE_CURRENT_BINARY_DIR}/measure.rb")
+ set_property(TARGET ${target}.measure APPEND PROPERTY INCLUDE_DIRECTORIES "${directory}")
+ add_custom_target(${target}.measure.run COMMAND ${target}.measure)
+
+ add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${target}.json"
+ COMMAND ${RUBY_EXECUTABLE} -r tilt -r "${CMAKE_CURRENT_BINARY_DIR}/measure.rb"
+ -e "MEASURE_FILE = '${CMAKE_CURRENT_BINARY_DIR}/${target}.measure.cpp'"
+ -e "MEASURE_TARGET = '${target}.measure'"
+ -e "json = Tilt::ERBTemplate.new('${CMAKE_CURRENT_BINARY_DIR}/${target}.erb.json').render"
+ -e "File.open('${CMAKE_CURRENT_BINARY_DIR}/${target}.json', 'w') { |f| f.write(json) } "
+ WORKING_DIRECTORY ${directory}
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${target}.erb.json" ${cpp_files}
+ VERBATIM USES_TERMINAL
+ COMMENT "Generating dataset for ${target}"
+ )
+
+ add_custom_target(${target} DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${target}.json")
+ add_dependencies(benchmarks ${target})
+endforeach()
diff --git a/src/boost/libs/hana/benchmark/chart.html b/src/boost/libs/hana/benchmark/chart.html
new file mode 100644
index 00000000..55718cef
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/chart.html
@@ -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)
+-->
+
+<!-- boost-no-inspect -->
+
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+
+ <script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
+ <script type="text/javascript" src="../doc/js/highcharts.js"></script>
+ <script type="text/javascript" src="../doc/js/highcharts-data.js"></script>
+ <script type="text/javascript" src="../doc/js/highcharts-exporting.js"></script>
+ <script type="text/javascript" src="../doc/js/chart.js"></script>
+
+ <script type="text/javascript">
+ var redrawChart = function(dataset) {
+ var path = "../build/benchmark/benchmark." + dataset + ".json";
+ $.getJSON(path, function(options) {
+ if ($("#container").highcharts())
+ $("#container").highcharts().destroy();
+
+ Hana.initChart($("#container"), options);
+ $('#container').highcharts().redraw();
+ });
+ };
+ </script>
+</head>
+
+<body>
+ <div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
+
+ <input type="text" size=100 id="dataset" class="enter" value="" onchange="redrawChart(this.value)"/>
+</body>
+
+</html>
diff --git a/src/boost/libs/hana/benchmark/find_if/compile.erb.json b/src/boost/libs/hana/benchmark/find_if/compile.erb.json
new file mode 100644
index 00000000..da6542b5
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/find_if/compile.erb.json
@@ -0,0 +1,53 @@
+<%
+ hana = (0...50).step(5).to_a + (50..200).step(25).to_a
+ fusion = (0...50).step(5).to_a
+ mpl = hana
+ meta = hana
+%>
+
+{
+ "title": {
+ "text": "Compile-time behavior of find_if"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= time_compilation('compile.hana.tuple.erb.cpp', hana) %>
+ }
+
+ <% if false %>
+ , {
+ "name": "hana::set",
+ "data": <%= time_compilation('compile.hana.set.erb.cpp', hana) %>
+ }, {
+ "name": "hana::map",
+ "data": <%= time_compilation('compile.hana.map.erb.cpp', hana) %>
+ }
+ <% end %>
+
+ , {
+ "name": "std::integer_sequence",
+ "data": <%= time_compilation('compile.std.integer_sequence.erb.cpp', hana) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "fusion::vector",
+ "data": <%= time_compilation('compile.fusion.vector.erb.cpp', fusion) %>
+ }, {
+ "name": "fusion::list",
+ "data": <%= time_compilation('compile.fusion.list.erb.cpp', fusion) %>
+ }, {
+ "name": "mpl::vector",
+ "data": <%= time_compilation('compile.mpl.vector.erb.cpp', mpl) %>
+ }
+ <% end %>
+
+ <% if cmake_bool("@Meta_FOUND@") %>
+ , {
+ "name": "meta::list",
+ "data": <%= time_compilation('compile.meta.list.erb.cpp', meta) %>
+ }
+ <% end %>
+ ]
+}
diff --git a/src/boost/libs/hana/benchmark/find_if/compile.fusion.list.erb.cpp b/src/boost/libs/hana/benchmark/find_if/compile.fusion.list.erb.cpp
new file mode 100644
index 00000000..a7c0ca90
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/find_if/compile.fusion.list.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_LIST_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/find_if.hpp>
+#include <boost/fusion/include/make_list.hpp>
+#include <boost/mpl/integral_c.hpp>
+namespace fusion = boost::fusion;
+namespace mpl = boost::mpl;
+
+
+struct is_last {
+ template <typename N>
+ struct apply
+ : mpl::integral_c<bool, N::type::value == <%= input_size %>>
+ { };
+};
+
+int main() {
+ auto ints = fusion::make_list(
+ <%= (1..input_size).map { |n| "mpl::integral_c<int, #{n}>{}" }.join(', ') %>
+ );
+
+ auto result = fusion::find_if<is_last>(ints);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/find_if/compile.fusion.vector.erb.cpp b/src/boost/libs/hana/benchmark/find_if/compile.fusion.vector.erb.cpp
new file mode 100644
index 00000000..067cbaae
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/find_if/compile.fusion.vector.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_VECTOR_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/find_if.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/mpl/integral_c.hpp>
+namespace fusion = boost::fusion;
+namespace mpl = boost::mpl;
+
+
+struct is_last {
+ template <typename N>
+ struct apply
+ : mpl::integral_c<bool, N::type::value == <%= input_size %>>
+ { };
+};
+
+int main() {
+ auto ints = fusion::make_vector(
+ <%= (1..input_size).map { |n| "mpl::integral_c<int, #{n}>{}" }.join(', ') %>
+ );
+
+ auto result = fusion::find_if<is_last>(ints);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/find_if/compile.hana.map.erb.cpp b/src/boost/libs/hana/benchmark/find_if/compile.hana.map.erb.cpp
new file mode 100644
index 00000000..8b600973
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/find_if/compile.hana.map.erb.cpp
@@ -0,0 +1,29 @@
+// Copyright Jason Rice 2015
+// Distributed under the 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/find_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+namespace hana = boost::hana;
+
+
+struct is_last {
+ template <typename N>
+ constexpr auto operator()(N) const {
+ return hana::bool_c<N::value == <%= input_size %>>;
+ }
+};
+
+struct undefined {};
+
+int main() {
+ constexpr auto map = hana::make_map(
+ <%= (1..input_size).map { |n|
+ "hana::make_pair(hana::int_c<#{n}>, undefined{})"
+ }.join(', ') %>
+ );
+ constexpr auto result = hana::find_if(map, is_last{});
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/find_if/compile.hana.set.erb.cpp b/src/boost/libs/hana/benchmark/find_if/compile.hana.set.erb.cpp
new file mode 100644
index 00000000..6ce31878
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/find_if/compile.hana.set.erb.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/bool.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+namespace hana = boost::hana;
+
+
+struct is_last {
+ template <typename N>
+ constexpr auto operator()(N) const {
+ return hana::bool_c<N::value == <%= input_size %>>;
+ }
+};
+
+int main() {
+ constexpr auto set = hana::make_set(
+ <%= (1..input_size).map { |n| "hana::int_c<#{n}>" }.join(', ') %>
+ );
+ constexpr auto result = hana::find_if(set, is_last{});
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/find_if/compile.hana.tuple.erb.cpp b/src/boost/libs/hana/benchmark/find_if/compile.hana.tuple.erb.cpp
new file mode 100644
index 00000000..7e4684b6
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/find_if/compile.hana.tuple.erb.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/find_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+
+struct is_last {
+ template <typename N>
+ constexpr auto operator()(N) const {
+ return boost::hana::bool_c<N::value == <%= input_size %>>;
+ }
+};
+
+int main() {
+ constexpr auto tuple = boost::hana::make_tuple(
+ <%= (1..input_size).map { |n| "boost::hana::int_c<#{n}>" }.join(', ') %>
+ );
+ constexpr auto result = boost::hana::find_if(tuple, is_last{});
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/find_if/compile.meta.list.erb.cpp b/src/boost/libs/hana/benchmark/find_if/compile.meta.list.erb.cpp
new file mode 100644
index 00000000..4c2e61aa
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/find_if/compile.meta.list.erb.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 <meta/meta.hpp>
+
+
+struct is_last {
+ template <typename N>
+ using apply = meta::bool_<N::value == <%= input_size %>>;
+};
+
+using list = meta::list<
+ <%= (1..input_size).map { |i| "meta::int_<#{i}>" }.join(', ') %>
+>;
+
+using result = meta::find_if<list, is_last>;
+
+int main() {
+
+}
diff --git a/src/boost/libs/hana/benchmark/find_if/compile.mpl.vector.erb.cpp b/src/boost/libs/hana/benchmark/find_if/compile.mpl.vector.erb.cpp
new file mode 100644
index 00000000..b6b42a70
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/find_if/compile.mpl.vector.erb.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/mpl/find_if.hpp>
+#include <boost/mpl/integral_c.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/quote.hpp>
+#include <boost/mpl/vector.hpp>
+namespace mpl = boost::mpl;
+
+
+struct is_last {
+ template <typename N>
+ struct apply
+ : mpl::integral_c<bool, N::type::value == <%= input_size %>>
+ { };
+};
+
+using vector = <%= mpl_vector((1..input_size).to_a.map { |n|
+ "mpl::integral_c<int, #{n}>"
+}) %>;
+
+using result = mpl::find_if<vector, is_last>::type;
+
+
+int main() { }
diff --git a/src/boost/libs/hana/benchmark/find_if/compile.std.integer_sequence.erb.cpp b/src/boost/libs/hana/benchmark/find_if/compile.std.integer_sequence.erb.cpp
new file mode 100644
index 00000000..1e519459
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/find_if/compile.std.integer_sequence.erb.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/bool.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct is_last {
+ template <typename N>
+ constexpr auto operator()(N) const {
+ return hana::bool_c<N::value == <%= input_size %>>;
+ }
+};
+
+int main() {
+ auto sequence = std::integer_sequence<
+ <%= (["int"] + (1..input_size).to_a).join(', ') %>
+ >{};
+ auto result = hana::find_if(sequence, is_last{});
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/bloat.erb.json b/src/boost/libs/hana/benchmark/fold_left/bloat.erb.json
new file mode 100644
index 00000000..b3bd9892
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/bloat.erb.json
@@ -0,0 +1,38 @@
+<%
+ exec = (0..100).step(10).to_a
+ fusion = (0..50).step(10).to_a
+%>
+
+{
+ "title": {
+ "text": "Executable size for fold_left"
+ },
+ "yAxis": {
+ "title": {
+ "text": "Executable size (kb)"
+ },
+ "floor": 0
+ },
+ "tooltip": {
+ "valueSuffix": "kb"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= measure(:bloat, 'execute.hana.tuple.erb.cpp', exec) %>
+ }, {
+ "name": "std::vector",
+ "data": <%= measure(:bloat, 'execute.std.vector.erb.cpp', exec) %>
+ }, {
+ "name": "std::array",
+ "data": <%= measure(:bloat, 'execute.std.array.erb.cpp', exec) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "fusion::vector",
+ "data": <%= measure(:bloat, 'execute.fusion.vector.erb.cpp', fusion) %>
+ }
+ <% end %>
+ ]
+} \ No newline at end of file
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.cexpr.recursive.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/compile.cexpr.recursive.erb.cpp
new file mode 100644
index 00000000..30beb169
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.cexpr.recursive.erb.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)
+
+template <typename ...xs>
+struct list { };
+
+template <typename T>
+struct basic_type { using type = T; };
+
+template <typename T>
+constexpr basic_type<T> type{};
+
+
+template <typename x, typename ...xs>
+constexpr auto head(list<x, xs...>)
+{ return type<x>; }
+
+template <typename x, typename ...xs>
+constexpr auto tail(list<x, xs...>)
+{ return list<xs...>{}; }
+
+template <typename F, typename State, typename X, typename ...Xs>
+constexpr auto foldl(F f, State s, list<X, Xs...> xs)
+{ return foldl(f, f(s, head(xs)), tail(xs)); }
+
+template <typename F, typename State>
+constexpr auto foldl(F, State s, list<>)
+{ return s; }
+
+//////////////////////////////////////////////////////////////////////////////
+
+
+struct f {
+ template <typename ...>
+ struct result { };
+
+ template <typename X, typename Y>
+ constexpr auto operator()(X, Y) const
+ { return result<X, Y>{}; }
+};
+
+template <int> struct x { };
+struct state { };
+
+int main() {
+ constexpr auto xs = list<
+ <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
+ >{};
+
+ constexpr auto result = foldl(f{}, state{}, xs);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.cexpr.unrolled.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/compile.cexpr.unrolled.erb.cpp
new file mode 100644
index 00000000..80fb46f0
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.cexpr.unrolled.erb.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/detail/variadic/foldl1.hpp>
+
+
+template <typename ...xs>
+struct list { };
+
+template <typename T>
+struct basic_type { using type = T; };
+
+template <typename T>
+constexpr basic_type<T> type{};
+
+
+template <typename F, typename State, typename ...Xs>
+constexpr auto foldl(F f, State s, list<Xs...> xs)
+{ return boost::hana::detail::variadic::foldl(f, s, type<Xs>...); }
+
+//////////////////////////////////////////////////////////////////////////////
+
+struct f {
+ template <typename ...>
+ struct result { };
+
+ template <typename X, typename Y>
+ constexpr auto operator()(X, Y) const
+ { return result<X, Y>{}; }
+};
+
+template <int> struct x { };
+struct state { };
+
+int main() {
+ constexpr auto xs = list<
+ <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
+ >{};
+
+ constexpr auto result = foldl(f{}, state{}, xs);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.erb.json b/src/boost/libs/hana/benchmark/fold_left/compile.erb.json
new file mode 100644
index 00000000..7240907a
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.erb.json
@@ -0,0 +1,61 @@
+<%
+ hana = (0...50).step(5).to_a + (50..400).step(25).to_a
+ fusion = (0..50).step(5)
+ mpl = hana
+ mpl11 = (0...50).step(5).to_a + (50..500).step(25).to_a
+ meta = (0...50).step(5).to_a + (50..200).step(25).to_a
+ cexpr = (0...50).step(5).to_a + (50..200).step(25).to_a
+%>
+
+
+{
+ "title": {
+ "text": "Compile-time behavior of fold_left"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= time_compilation('compile.hana.tuple.erb.cpp', hana) %>
+ }, {
+ "name": "hana::basic_tuple",
+ "data": <%= time_compilation('compile.hana.basic_tuple.erb.cpp', hana) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "fusion::vector",
+ "data": <%= time_compilation('compile.fusion.vector.erb.cpp', fusion) %>
+ },{
+ "name": "fusion::list",
+ "data": <%= time_compilation('compile.fusion.list.erb.cpp', fusion) %>
+ }, {
+ "name": "mpl::vector",
+ "data": <%= time_compilation('compile.mpl.vector.erb.cpp', mpl) %>
+ }
+ <% end %>
+
+ <% if cmake_bool("@MPL11_FOUND@") %>
+ , {
+ "name": "mpl11::list",
+ "data": <%= time_compilation('compile.mpl11.list.erb.cpp', mpl11) %>
+ }
+ <% end %>
+
+ <% if cmake_bool("@Meta_FOUND@") %>
+ , {
+ "name": "meta::list",
+ "data": <%= time_compilation('compile.meta.list.erb.cpp', meta) %>
+ }
+ <% end %>
+
+ <% if false %>
+ , {
+ "name": "cexpr::list (recursive)",
+ "data": <%= time_compilation('compile.cexpr.recursive.erb.cpp', cexpr) %>
+ }, {
+ "name": "cexpr::list (unrolled)",
+ "data": <%= time_compilation('compile.cexpr.unrolled.erb.cpp', cexpr) %>
+ }
+ <% end %>
+ ]
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.fusion.list.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/compile.fusion.list.erb.cpp
new file mode 100644
index 00000000..144744a2
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.fusion.list.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_LIST_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/fold.hpp>
+#include <boost/fusion/include/make_list.hpp>
+namespace fusion = boost::fusion;
+
+
+struct f {
+ template <typename State, typename X>
+ constexpr X operator()(State, X x) const { return x; }
+};
+
+struct state { };
+
+template <int i>
+struct x { };
+
+int main() {
+ auto xs = fusion::make_list(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+
+ auto result = fusion::fold(xs, state{}, f{});
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.fusion.vector.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/compile.fusion.vector.erb.cpp
new file mode 100644
index 00000000..3a319b35
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.fusion.vector.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_VECTOR_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/fold.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+namespace fusion = boost::fusion;
+
+
+struct f {
+ template <typename State, typename X>
+ constexpr X operator()(State, X x) const { return x; }
+};
+
+struct state { };
+
+template <int i>
+struct x { };
+
+int main() {
+ auto xs = fusion::make_vector(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+
+ auto result = fusion::fold(xs, state{}, f{});
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.hana.basic_tuple.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/compile.hana.basic_tuple.erb.cpp
new file mode 100644
index 00000000..c076f3fc
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.hana.basic_tuple.erb.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/fold_left.hpp>
+#include <boost/hana/basic_tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct f {
+ template <typename State, typename X>
+ constexpr X operator()(State, X x) const { return x; }
+};
+
+struct state { };
+
+template <int i>
+struct x { };
+
+int main() {
+ constexpr auto tuple = hana::make_basic_tuple(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+ constexpr auto result = hana::fold_left(tuple, state{}, f{});
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.hana.tuple.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/compile.hana.tuple.erb.cpp
new file mode 100644
index 00000000..a245e30c
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.hana.tuple.erb.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/fold_left.hpp>
+#include <boost/hana/tuple.hpp>
+
+
+struct f {
+ template <typename State, typename X>
+ constexpr X operator()(State, X x) const { return x; }
+};
+
+struct state { };
+
+template <int i>
+struct x { };
+
+int main() {
+ constexpr auto tuple = boost::hana::make_tuple(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+ constexpr auto result = boost::hana::fold_left(tuple, state{}, f{});
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.meta.list.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/compile.meta.list.erb.cpp
new file mode 100644
index 00000000..cd2ec0f8
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.meta.list.erb.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 <meta/meta.hpp>
+
+
+struct f {
+ template <typename, typename>
+ struct apply;
+};
+
+template <int> struct x;
+
+struct state;
+
+using list = meta::list<
+ <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
+>;
+
+using result = meta::fold<list, state, f>;
+
+int main() {
+
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.mpl.vector.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/compile.mpl.vector.erb.cpp
new file mode 100644
index 00000000..4d5b5b4b
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.mpl.vector.erb.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/mpl/fold.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/quote.hpp>
+#include <boost/mpl/vector.hpp>
+
+
+template <typename State, typename X>
+struct f { using type = X; };
+
+struct state { };
+
+template <int i>
+struct t { };
+
+using vector = <%= mpl_vector((1..input_size).to_a.map { |n| "t<#{n}>" }) %>;
+
+using result = boost::mpl::fold<vector, state, boost::mpl::quote2<f>>::type;
+
+
+int main() { }
diff --git a/src/boost/libs/hana/benchmark/fold_left/compile.mpl11.list.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/compile.mpl11.list.erb.cpp
new file mode 100644
index 00000000..cf383ef0
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/compile.mpl11.list.erb.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/mpl11/list.hpp>
+
+
+struct f {
+ using type = f;
+ template <typename, typename>
+ struct apply { struct type; };
+};
+
+template <int> struct x { struct type; };
+
+struct state { struct type; };
+
+using list = boost::mpl11::list<
+ <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
+>;
+
+using result = boost::mpl11::foldl<f, state, list>::type;
+
+int main() {
+
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/execute.erb.json b/src/boost/libs/hana/benchmark/fold_left/execute.erb.json
new file mode 100644
index 00000000..2f7d9455
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/execute.erb.json
@@ -0,0 +1,32 @@
+<%
+ exec = (0..100).step(10).to_a
+ fusion = (0..50).step(10).to_a
+%>
+
+{
+ "title": {
+ "text": "Runtime behavior of fold_left"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= time_execution('execute.hana.tuple.erb.cpp', exec) %>
+ }, {
+ "name": "std::vector",
+ "data": <%= time_execution('execute.std.vector.erb.cpp', exec) %>
+ }, {
+ "name": "std::array",
+ "data": <%= time_execution('execute.std.array.erb.cpp', exec) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "fusion::vector",
+ "data": <%= time_execution('execute.fusion.vector.erb.cpp', fusion) %>
+ }, {
+ "name": "fusion::list",
+ "data": <%= time_execution('execute.fusion.list.erb.cpp', fusion) %>
+ }
+ <% end %>
+ ]
+} \ No newline at end of file
diff --git a/src/boost/libs/hana/benchmark/fold_left/execute.fusion.list.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/execute.fusion.list.erb.cpp
new file mode 100644
index 00000000..b7193898
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/execute.fusion.list.erb.cpp
@@ -0,0 +1,32 @@
+// Copyright Louis Dionne 2013-2017
+// Copyright Zach Laine 2014
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_LIST_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/fold.hpp>
+#include <boost/fusion/include/make_list.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+int main () {
+ hana::benchmark::measure([] {
+ long double result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ auto values = fusion::make_list(
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ );
+
+ result += fusion::fold(values, 0, [](auto state, auto t) {
+ return state + t;
+ });
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/execute.fusion.vector.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/execute.fusion.vector.erb.cpp
new file mode 100644
index 00000000..c733a3be
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/execute.fusion.vector.erb.cpp
@@ -0,0 +1,32 @@
+// Copyright Louis Dionne 2013-2017
+// Copyright Zach Laine 2014
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_VECTOR_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/fold.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+int main () {
+ hana::benchmark::measure([] {
+ long double result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ auto values = fusion::make_vector(
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ );
+
+ result += fusion::fold(values, 0, [](auto state, auto t) {
+ return state + t;
+ });
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/execute.hana.tuple.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/execute.hana.tuple.erb.cpp
new file mode 100644
index 00000000..622d74f8
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/execute.hana.tuple.erb.cpp
@@ -0,0 +1,26 @@
+// Copyright Louis Dionne 2013-2017
+// Copyright Zach Laine 2014
+// Distributed under the 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/tuple.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+
+
+int main () {
+ boost::hana::benchmark::measure([] {
+ long double result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ auto values = boost::hana::make_tuple(
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ );
+
+ result += boost::hana::fold_left(values, 0, [](auto state, auto t) {
+ return state + t;
+ });
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/execute.std.array.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/execute.std.array.erb.cpp
new file mode 100644
index 00000000..3961151b
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/execute.std.array.erb.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 "measure.hpp"
+#include <array>
+#include <cstdlib>
+#include <numeric>
+
+
+int main () {
+ boost::hana::benchmark::measure([] {
+ long long result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ std::array<int, <%= input_size %>> values = {{
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ }};
+
+ result += std::accumulate(values.begin(), values.end(), 0);
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/fold_left/execute.std.vector.erb.cpp b/src/boost/libs/hana/benchmark/fold_left/execute.std.vector.erb.cpp
new file mode 100644
index 00000000..703b6fbc
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/fold_left/execute.std.vector.erb.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 "measure.hpp"
+#include <cstdlib>
+#include <numeric>
+#include <vector>
+
+
+int main () {
+ boost::hana::benchmark::measure([] {
+ long long result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ std::vector<int> values = {
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ };
+
+ result += std::accumulate(values.begin(), values.end(), 0);
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/including/baseline.erb.cpp b/src/boost/libs/hana/benchmark/including/baseline.erb.cpp
new file mode 100644
index 00000000..932facb4
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/including/baseline.erb.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+
+int main() { }
diff --git a/src/boost/libs/hana/benchmark/including/compile.erb.json b/src/boost/libs/hana/benchmark/including/compile.erb.json
new file mode 100644
index 00000000..2441a4ee
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/including/compile.erb.json
@@ -0,0 +1,73 @@
+<%
+ def self.avg(xs)
+ xs.inject(0, :+) / xs.length
+ end
+
+ def self.amortize(file)
+ # We remove the first one to mitigate cache effects
+ times = time_compilation(file, 6.times)
+ times.shift
+ avg(times.map { |_, t| t })
+ end
+%>
+
+{
+ "chart": {
+ "type": "column"
+ },
+ "legend": {
+ "enabled": false
+ },
+ "xAxis": {
+ "type": "category"
+ },
+ "title": {
+ "text": "Including various metaprogramming libraries"
+ },
+ "plotOptions": {
+ "series": {
+ "borderWidth": 0,
+ "dataLabels": {
+ "enabled": true,
+ "format": "{point.y:.5f}s"
+ }
+ }
+ },
+ "series": [{
+ "name": "Include time",
+ "colorByPoint": true,
+ "data": [
+ {
+ "name": "Baseline (no includes)",
+ "y": <%= amortize('baseline.erb.cpp') %>
+ }, {
+ "name": "Boost.Hana",
+ "y": <%= amortize('hana.erb.cpp') %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "Boost.MPL",
+ "y": <%= amortize('mpl.erb.cpp') %>
+ }, {
+ "name": "Boost.Fusion",
+ "y": <%= amortize('fusion.erb.cpp') %>
+ }
+ <% end %>
+
+ <% if cmake_bool("@MPL11_FOUND@") %>
+ , {
+ "name": "MPL11",
+ "y": <%= amortize('mpl11.erb.cpp') %>
+ }
+ <% end %>
+
+ <% if cmake_bool("@Meta_FOUND@") %>
+ , {
+ "name": "Meta",
+ "y": <%= amortize('meta.erb.cpp') %>
+ }
+ <% end %>
+ ]
+ }]
+}
diff --git a/src/boost/libs/hana/benchmark/including/fusion.erb.cpp b/src/boost/libs/hana/benchmark/including/fusion.erb.cpp
new file mode 100644
index 00000000..bae08353
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/including/fusion.erb.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/fusion/adapted.hpp>
+#include <boost/fusion/algorithm.hpp>
+#include <boost/fusion/container.hpp>
+#include <boost/fusion/functional.hpp>
+#include <boost/fusion/iterator.hpp>
+#include <boost/fusion/sequence.hpp>
+#include <boost/fusion/support.hpp>
+#include <boost/fusion/tuple.hpp>
+#include <boost/fusion/view.hpp>
+
+
+int main() { }
diff --git a/src/boost/libs/hana/benchmark/including/hana.erb.cpp b/src/boost/libs/hana/benchmark/including/hana.erb.cpp
new file mode 100644
index 00000000..e35e8135
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/including/hana.erb.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/benchmark/including/meta.erb.cpp b/src/boost/libs/hana/benchmark/including/meta.erb.cpp
new file mode 100644
index 00000000..492d2f9e
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/including/meta.erb.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 <meta/meta.hpp>
+
+
+int main() { }
diff --git a/src/boost/libs/hana/benchmark/including/mpl.erb.cpp b/src/boost/libs/hana/benchmark/including/mpl.erb.cpp
new file mode 100644
index 00000000..167eb376
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/including/mpl.erb.cpp
@@ -0,0 +1,155 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under 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/accumulate.hpp>
+#include <boost/mpl/advance.hpp>
+#include <boost/mpl/alias.hpp>
+#include <boost/mpl/always.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/apply_wrap.hpp>
+#include <boost/mpl/arg.hpp>
+#include <boost/mpl/arithmetic.hpp>
+#include <boost/mpl/as_sequence.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/back.hpp>
+#include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/base.hpp>
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/bind.hpp>
+#include <boost/mpl/bitand.hpp>
+#include <boost/mpl/bitor.hpp>
+#include <boost/mpl/bitwise.hpp>
+#include <boost/mpl/bitxor.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/char.hpp>
+#include <boost/mpl/clear.hpp>
+#include <boost/mpl/comparison.hpp>
+#include <boost/mpl/contains.hpp>
+#include <boost/mpl/copy.hpp>
+#include <boost/mpl/copy_if.hpp>
+#include <boost/mpl/count.hpp>
+#include <boost/mpl/count_if.hpp>
+#include <boost/mpl/deque.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/distance.hpp>
+#include <boost/mpl/divides.hpp>
+#include <boost/mpl/empty.hpp>
+#include <boost/mpl/empty_base.hpp>
+#include <boost/mpl/empty_sequence.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/mpl/equal.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/erase.hpp>
+#include <boost/mpl/erase_key.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/filter_view.hpp>
+#include <boost/mpl/find.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/for_each.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/front_inserter.hpp>
+#include <boost/mpl/greater.hpp>
+#include <boost/mpl/greater_equal.hpp>
+#include <boost/mpl/has_key.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/index_if.hpp>
+#include <boost/mpl/index_of.hpp>
+#include <boost/mpl/inherit.hpp>
+#include <boost/mpl/inherit_linearly.hpp>
+#include <boost/mpl/insert.hpp>
+#include <boost/mpl/insert_range.hpp>
+#include <boost/mpl/inserter.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+#include <boost/mpl/integral_c_tag.hpp>
+#include <boost/mpl/is_placeholder.hpp>
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/iter_fold.hpp>
+#include <boost/mpl/iter_fold_if.hpp>
+#include <boost/mpl/iterator_category.hpp>
+#include <boost/mpl/iterator_range.hpp>
+#include <boost/mpl/iterator_tags.hpp>
+#include <boost/mpl/joint_view.hpp>
+#include <boost/mpl/key_type.hpp>
+#include <boost/mpl/lambda.hpp>
+#include <boost/mpl/less.hpp>
+#include <boost/mpl/less_equal.hpp>
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/list_c.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/mpl/long.hpp>
+#include <boost/mpl/lower_bound.hpp>
+#include <boost/mpl/map.hpp>
+#include <boost/mpl/max.hpp>
+#include <boost/mpl/max_element.hpp>
+#include <boost/mpl/min.hpp>
+#include <boost/mpl/min_element.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/mpl/minus.hpp>
+#include <boost/mpl/modulus.hpp>
+#include <boost/mpl/multiplies.hpp>
+#include <boost/mpl/negate.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/next_prior.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/not_equal_to.hpp>
+#include <boost/mpl/numeric_cast.hpp>
+#include <boost/mpl/O1_size.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/order.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/pair_view.hpp>
+#include <boost/mpl/partition.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/plus.hpp>
+#include <boost/mpl/pop_back.hpp>
+#include <boost/mpl/pop_front.hpp>
+#include <boost/mpl/print.hpp>
+#include <boost/mpl/prior.hpp>
+#include <boost/mpl/protect.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/push_front.hpp>
+#include <boost/mpl/quote.hpp>
+#include <boost/mpl/range_c.hpp>
+#include <boost/mpl/remove.hpp>
+#include <boost/mpl/remove_if.hpp>
+#include <boost/mpl/replace.hpp>
+#include <boost/mpl/replace_if.hpp>
+#include <boost/mpl/reverse.hpp>
+#include <boost/mpl/reverse_fold.hpp>
+#include <boost/mpl/reverse_iter_fold.hpp>
+#include <boost/mpl/same_as.hpp>
+#include <boost/mpl/sequence_tag.hpp>
+#include <boost/mpl/set.hpp>
+#include <boost/mpl/set_c.hpp>
+#include <boost/mpl/shift_left.hpp>
+#include <boost/mpl/shift_right.hpp>
+#include <boost/mpl/single_view.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/size_t.hpp>
+#include <boost/mpl/sizeof.hpp>
+#include <boost/mpl/sort.hpp>
+#include <boost/mpl/stable_partition.hpp>
+#include <boost/mpl/string.hpp>
+#include <boost/mpl/switch.hpp>
+#include <boost/mpl/tag.hpp>
+#include <boost/mpl/times.hpp>
+#include <boost/mpl/transform.hpp>
+#include <boost/mpl/transform_view.hpp>
+#include <boost/mpl/unique.hpp>
+#include <boost/mpl/unpack_args.hpp>
+#include <boost/mpl/upper_bound.hpp>
+#include <boost/mpl/value_type.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/vector_c.hpp>
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/zip_view.hpp>
+
+
+int main() { }
diff --git a/src/boost/libs/hana/benchmark/including/mpl11.erb.cpp b/src/boost/libs/hana/benchmark/including/mpl11.erb.cpp
new file mode 100644
index 00000000..e5b9fd51
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/including/mpl11.erb.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/mpl11.hpp>
+
+
+int main() { }
diff --git a/src/boost/libs/hana/benchmark/make/compile.erb.json b/src/boost/libs/hana/benchmark/make/compile.erb.json
new file mode 100644
index 00000000..24166876
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.erb.json
@@ -0,0 +1,58 @@
+<%
+ hana = (0...50).step(5).to_a + (50..400).step(25).to_a
+ fusion = (0...50).step(5).to_a + [50, 75, 100]
+ mpl = hana
+ meta = (0...50).step(5).to_a + (50..200).step(25).to_a
+ mpl11 = hana
+ std = (0...50).step(5).to_a + (50..100).step(25).to_a
+%>
+
+{
+ "title": {
+ "text": "Compile-time behavior of creating a sequence"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= time_compilation('compile.hana.tuple.erb.cpp', hana) %>
+ }, {
+ "name": "hana::basic_tuple",
+ "data": <%= time_compilation('compile.hana.basic_tuple.erb.cpp', hana) %>
+ }, {
+ "name": "std::array",
+ "data": <%= time_compilation('compile.std.array.erb.cpp', hana) %>
+ }
+
+ , {
+ "name": "std::tuple",
+ "data": <%= time_compilation('compile.std.tuple.erb.cpp', std) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "fusion::vector",
+ "data": <%= time_compilation('compile.fusion.vector.erb.cpp', fusion) %>
+ }, {
+ "name": "fusion::list",
+ "data": <%= time_compilation('compile.fusion.list.erb.cpp', fusion) %>
+ }, {
+ "name": "mpl::vector",
+ "data": <%= time_compilation('compile.mpl.vector.erb.cpp', mpl) %>
+ }
+ <% end %>
+
+ <% if cmake_bool("@Meta_FOUND@") %>
+ , {
+ "name": "meta::list",
+ "data": <%= time_compilation('compile.meta.list.erb.cpp', meta) %>
+ }
+ <% end %>
+
+ <% if cmake_bool("@MPL11_FOUND@") %>
+ , {
+ "name": "mpl11::list",
+ "data": <%= time_compilation('compile.mpl11.list.erb.cpp', mpl11) %>
+ }
+ <% end %>
+ ]
+}
diff --git a/src/boost/libs/hana/benchmark/make/compile.fusion.list.erb.cpp b/src/boost/libs/hana/benchmark/make/compile.fusion.list.erb.cpp
new file mode 100644
index 00000000..7274375a
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.fusion.list.erb.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/fusion/include/make_list.hpp>
+#include <boost/fusion/include/push_back.hpp>
+
+
+template <int i>
+struct x { };
+
+int main() {
+ auto xs = <%= fusion_list((1..input_size).map { |n| "x<#{n}>{}" }) %>;
+ (void)xs;
+}
diff --git a/src/boost/libs/hana/benchmark/make/compile.fusion.vector.erb.cpp b/src/boost/libs/hana/benchmark/make/compile.fusion.vector.erb.cpp
new file mode 100644
index 00000000..fd3794b3
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.fusion.vector.erb.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/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/push_back.hpp>
+
+
+template <int i>
+struct x { };
+
+int main() {
+ auto vector = <%= fusion_vector((1..input_size).map { |n| "x<#{n}>{}" }) %>;
+ (void)vector;
+}
diff --git a/src/boost/libs/hana/benchmark/make/compile.hana.basic_tuple.erb.cpp b/src/boost/libs/hana/benchmark/make/compile.hana.basic_tuple.erb.cpp
new file mode 100644
index 00000000..a04016a4
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.hana.basic_tuple.erb.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/basic_tuple.hpp>
+
+
+template <int i>
+struct x { };
+
+int main() {
+ constexpr auto tuple = boost::hana::make_basic_tuple(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+ (void)tuple;
+}
diff --git a/src/boost/libs/hana/benchmark/make/compile.hana.tuple.erb.cpp b/src/boost/libs/hana/benchmark/make/compile.hana.tuple.erb.cpp
new file mode 100644
index 00000000..34ce368e
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.hana.tuple.erb.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/tuple.hpp>
+
+
+template <int i>
+struct x { };
+
+int main() {
+ constexpr auto tuple = boost::hana::make_tuple(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+ (void)tuple;
+}
diff --git a/src/boost/libs/hana/benchmark/make/compile.meta.list.erb.cpp b/src/boost/libs/hana/benchmark/make/compile.meta.list.erb.cpp
new file mode 100644
index 00000000..f90fef99
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.meta.list.erb.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 <meta/meta.hpp>
+
+
+template <int>
+struct x;
+
+using list = meta::list<
+ <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
+>;
+
+int main() {
+
+}
diff --git a/src/boost/libs/hana/benchmark/make/compile.mpl.vector.erb.cpp b/src/boost/libs/hana/benchmark/make/compile.mpl.vector.erb.cpp
new file mode 100644
index 00000000..4b7d94c5
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.mpl.vector.erb.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/mpl/push_back.hpp>
+#include <boost/mpl/vector.hpp>
+
+
+template <int i>
+struct t { };
+
+using vector = <%= mpl_vector((1..input_size).to_a.map { |n| "t<#{n}>" }) %>;
+
+int main() { }
diff --git a/src/boost/libs/hana/benchmark/make/compile.mpl11.list.erb.cpp b/src/boost/libs/hana/benchmark/make/compile.mpl11.list.erb.cpp
new file mode 100644
index 00000000..79d0c697
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.mpl11.list.erb.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/mpl11/list.hpp>
+
+
+template <int>
+struct x;
+
+using list = boost::mpl11::list<
+ <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
+>;
+
+int main() {
+
+}
diff --git a/src/boost/libs/hana/benchmark/make/compile.std.array.erb.cpp b/src/boost/libs/hana/benchmark/make/compile.std.array.erb.cpp
new file mode 100644
index 00000000..792ec484
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.std.array.erb.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 <array>
+
+
+template <int i>
+struct x { };
+
+int main() {
+ constexpr std::array<int, <%= input_size %>> array = {{
+ <%= (1..input_size).to_a.join(', ') %>
+ }};
+ (void)array;
+}
diff --git a/src/boost/libs/hana/benchmark/make/compile.std.tuple.erb.cpp b/src/boost/libs/hana/benchmark/make/compile.std.tuple.erb.cpp
new file mode 100644
index 00000000..11fc7cd8
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/make/compile.std.tuple.erb.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 <tuple>
+
+
+template <int i>
+struct x { };
+
+int main() {
+ constexpr auto tuple = std::make_tuple(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+ (void)tuple;
+}
diff --git a/src/boost/libs/hana/benchmark/measure.hpp b/src/boost/libs/hana/benchmark/measure.hpp
new file mode 100644
index 00000000..a477fefc
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/measure.hpp
@@ -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)
+
+#ifndef BOOST_HANA_BENCHMARK_MEASURE_HPP
+#define BOOST_HANA_BENCHMARK_MEASURE_HPP
+
+#include <chrono>
+#include <iostream>
+
+
+namespace boost { namespace hana { namespace benchmark {
+ auto measure = [](auto f) {
+ constexpr auto repetitions = 500ull;
+ auto start = std::chrono::steady_clock::now();
+ for (auto i = repetitions; i > 0; --i) {
+ f();
+ }
+ auto stop = std::chrono::steady_clock::now();
+
+ auto time = std::chrono::duration_cast<std::chrono::duration<float>>(
+ (stop - start) / repetitions
+ );
+ std::cout << std::fixed;
+ std::cout << "[execution time: " << time.count() << "]" << std::endl;
+ };
+}}}
+
+#endif
diff --git a/src/boost/libs/hana/benchmark/measure.in.rb b/src/boost/libs/hana/benchmark/measure.in.rb
new file mode 100755
index 00000000..65e2a98b
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/measure.in.rb
@@ -0,0 +1,161 @@
+#!/usr/bin/env ruby
+#
+# Copyright Louis Dionne 2013-2017
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+#
+#
+# When called as a program, this script runs the command line given in
+# arguments and returns the total time. This is similar to the `time`
+# command from Bash.
+#
+# This file can also be required as a Ruby module to gain access to the
+# methods defined below.
+#
+# NOTE:
+# This file must not be used as-is. It must be processed by CMake first.
+
+require 'benchmark'
+require 'open3'
+require 'pathname'
+require 'ruby-progressbar'
+require 'tilt'
+
+
+def split_at(n, list)
+ before = list[0...n] || []
+ after = list[n..-1] || []
+ return [before, after]
+end
+
+# types : A sequence of strings to put in the mpl::vector.
+# Using this method requires including
+# - <boost/mpl/vector.hpp>
+# - <boost/mpl/push_back.hpp>
+def mpl_vector(types)
+ fast, rest = split_at(20, types)
+ rest.inject("boost::mpl::vector#{fast.length}<#{fast.join(', ')}>") { |v, t|
+ "boost::mpl::push_back<#{v}, #{t}>::type"
+ }
+end
+
+# types : A sequence of strings to put in the mpl::list.
+# Using this method requires including
+# - <boost/mpl/list.hpp>
+# - <boost/mpl/push_front.hpp>
+def mpl_list(types)
+ prefix, fast = split_at([types.length - 20, 0].max, types)
+ prefix.reverse.inject("boost::mpl::list#{fast.length}<#{fast.join(', ')}>") { |l, t|
+ "boost::mpl::push_front<#{l}, #{t}>::type"
+ }
+end
+
+# values : A sequence of strings representing values to put in the fusion::vector.
+# Using this method requires including
+# - <boost/fusion/include/make_vector.hpp>
+# - <boost/fusion/include/push_back.hpp>
+def fusion_vector(values)
+ fast, rest = split_at(10, values)
+ rest.inject("boost::fusion::make_vector(#{fast.join(', ')})") { |xs, v|
+ "boost::fusion::push_back(#{xs}, #{v})"
+ }
+end
+
+# values : A sequence of strings representing values to put in the fusion::list.
+# Using this method requires including
+# - <boost/fusion/include/make_list.hpp>
+# - <boost/fusion/include/push_back.hpp>
+def fusion_list(values)
+ fast, rest = split_at(10, values)
+ rest.inject("boost::fusion::make_list(#{fast.join(', ')})") { |xs, v|
+ "boost::fusion::push_back(#{xs}, #{v})"
+ }
+end
+
+# Turns a CMake-style boolean into a Ruby boolean.
+def cmake_bool(b)
+ return true if b.is_a? String and ["true", "yes", "1"].include?(b.downcase)
+ return true if b.is_a? Integer and b > 0
+ return false # otherwise
+end
+
+# aspect must be one of :compilation_time, :bloat, :execution_time
+def measure(aspect, template_relative, range, env = {})
+ measure_file = Pathname.new("#{MEASURE_FILE}")
+ template = Pathname.new(template_relative).expand_path
+ range = range.to_a
+
+ if ENV["BOOST_HANA_JUST_CHECK_BENCHMARKS"] && range.length >= 2
+ range = [range[0], range[-1]]
+ end
+
+ make = -> (target) {
+ command = "@CMAKE_COMMAND@ --build @CMAKE_BINARY_DIR@ --target #{target}"
+ stdout, stderr, status = Open3.capture3(command)
+ }
+
+ progress = ProgressBar.create(format: '%p%% %t | %B |',
+ title: template_relative,
+ total: range.size,
+ output: STDERR)
+ range.map do |n|
+ # Evaluate the ERB template with the given environment, and save
+ # the result in the `measure.cpp` file.
+ code = Tilt::ERBTemplate.new(template).render(nil, input_size: n, env: env)
+ measure_file.write(code)
+
+ # Compile the file and get timing statistics. The timing statistics
+ # are output to stdout when we compile the file because of the way
+ # the `compile.benchmark.measure` CMake target is setup.
+ stdout, stderr, status = make["#{MEASURE_TARGET}"]
+ raise "compilation error: #{stdout}\n\n#{stderr}\n\n#{code}" if not status.success?
+ ctime = stdout.match(/\[compilation time: (.+)\]/i)
+ # Size of the generated executable in KB
+ size = File.size("@CMAKE_CURRENT_BINARY_DIR@/#{MEASURE_TARGET}").to_f / 1000
+
+ # If we didn't match anything, that's because we went too fast, CMake
+ # did not have the time to see the changes to the measure file and
+ # the target was not rebuilt. So we sleep for a bit and then retry
+ # this iteration.
+ (sleep 0.2; redo) if ctime.nil?
+ stat = ctime.captures[0].to_f if aspect == :compilation_time
+ stat = size if aspect == :bloat
+
+ # Run the resulting program and get timing statistics. The statistics
+ # should be written to stdout by the `measure` function of the
+ # `measure.hpp` header.
+ if aspect == :execution_time
+ stdout, stderr, status = make["#{MEASURE_TARGET}.run"]
+ raise "runtime error: #{stderr}\n\n#{code}" if not status.success?
+ match = stdout.match(/\[execution time: (.+)\]/i)
+ if match.nil?
+ raise ("Could not find [execution time: ...] bit in the output. " +
+ "Did you use the `measure` function in the `measure.hpp` header? " +
+ "stdout follows:\n#{stdout}")
+ end
+ stat = match.captures[0].to_f
+ end
+
+ progress.increment
+ [n, stat]
+ end
+ensure
+ measure_file.write("")
+ progress.finish if progress
+end
+
+def time_execution(erb_file, range, env = {})
+ measure(:execution_time, erb_file, range, env)
+end
+
+def time_compilation(erb_file, range, env = {})
+ measure(:compilation_time, erb_file, range, env)
+end
+
+if __FILE__ == $0
+ command = ARGV.join(' ')
+ time = Benchmark.realtime { `#{command}` }
+
+ puts "[command line: #{command}]"
+ puts "[compilation time: #{time}]"
+end
diff --git a/src/boost/libs/hana/benchmark/reverse/move.erb.json b/src/boost/libs/hana/benchmark/reverse/move.erb.json
new file mode 100644
index 00000000..81ab5b7f
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/reverse/move.erb.json
@@ -0,0 +1,23 @@
+<%
+ exec = (0..100).step(10).to_a
+ fusion = (0..50).step(10).to_a
+%>
+
+{
+ "title": {
+ "text": "Runtime performance of reverse on a moved-from container"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= time_execution('move.hana.tuple.erb.cpp', exec) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "fusion::vector",
+ "data": <%= time_execution('move.fusion.vector.erb.cpp', fusion) %>
+ }
+ <% end %>
+ ]
+}
diff --git a/src/boost/libs/hana/benchmark/reverse/move.fusion.vector.erb.cpp b/src/boost/libs/hana/benchmark/reverse/move.fusion.vector.erb.cpp
new file mode 100644
index 00000000..83c29371
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/reverse/move.fusion.vector.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_VECTOR_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/reverse.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+#include <string>
+#include <utility>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+int main () {
+ std::string s(1000, 'x');
+ hana::benchmark::measure([&] {
+ for (int iteration = 0; iteration < 1 << 5; ++iteration) {
+ auto values = fusion::make_vector(
+ <%= input_size.times.map { 's' }.join(', ') %>
+ );
+
+ auto result = fusion::as_vector(fusion::reverse(std::move(values)));
+ (void)result;
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/reverse/move.hana.tuple.erb.cpp b/src/boost/libs/hana/benchmark/reverse/move.hana.tuple.erb.cpp
new file mode 100644
index 00000000..bf27357d
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/reverse/move.hana.tuple.erb.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/reverse.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+#include <string>
+#include <utility>
+namespace hana = boost::hana;
+
+
+int main () {
+ std::string s(1000, 'x');
+ hana::benchmark::measure([&] {
+ for (int iteration = 0; iteration < 1 << 5; ++iteration) {
+ auto values = hana::make_tuple(
+ <%= input_size.times.map { 's' }.join(', ') %>
+ );
+
+ auto result = hana::reverse(std::move(values));
+ (void)result;
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/reverse/nomove.erb.json b/src/boost/libs/hana/benchmark/reverse/nomove.erb.json
new file mode 100644
index 00000000..b9d39bd8
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/reverse/nomove.erb.json
@@ -0,0 +1,23 @@
+<%
+ exec = (0..100).step(10).to_a
+ fusion = (0..50).step(10).to_a
+%>
+
+{
+ "title": {
+ "text": "Runtime performance of reverse on a normal container"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= time_execution('nomove.hana.tuple.erb.cpp', exec) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "fusion::vector",
+ "data": <%= time_execution('nomove.fusion.vector.erb.cpp', fusion) %>
+ }
+ <% end %>
+ ]
+}
diff --git a/src/boost/libs/hana/benchmark/reverse/nomove.fusion.vector.erb.cpp b/src/boost/libs/hana/benchmark/reverse/nomove.fusion.vector.erb.cpp
new file mode 100644
index 00000000..cbb4b07d
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/reverse/nomove.fusion.vector.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_VECTOR_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/reverse.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+#include <string>
+#include <utility>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+int main () {
+ std::string s(1000, 'x');
+ hana::benchmark::measure([&] {
+ for (int iteration = 0; iteration < 1 << 5; ++iteration) {
+ auto values = fusion::make_vector(
+ <%= input_size.times.map { 's' }.join(', ') %>
+ );
+
+ auto result = fusion::as_vector(fusion::reverse(values));
+ (void)result;
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/reverse/nomove.hana.tuple.erb.cpp b/src/boost/libs/hana/benchmark/reverse/nomove.hana.tuple.erb.cpp
new file mode 100644
index 00000000..913061e3
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/reverse/nomove.hana.tuple.erb.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/reverse.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+#include <string>
+#include <utility>
+namespace hana = boost::hana;
+
+
+int main () {
+ std::string s(1000, 'x');
+ hana::benchmark::measure([&] {
+ for (int iteration = 0; iteration < 1 << 5; ++iteration) {
+ auto values = hana::make_tuple(
+ <%= input_size.times.map { 's' }.join(', ') %>
+ );
+
+ auto result = hana::reverse(values);
+ (void)result;
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/sort/compile.erb.json b/src/boost/libs/hana/benchmark/sort/compile.erb.json
new file mode 100644
index 00000000..1a13543b
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/sort/compile.erb.json
@@ -0,0 +1,31 @@
+<%
+ hana = [0, 1, 2, 5, 10, 20, 50, 100]
+%>
+
+{
+ "title": {
+ "text": "Compile-time behavior of sort"
+ },
+ "series": [
+ {
+ "name": "hana::tuple::sorted",
+ "data": <%= time_compilation('compile.hana.tuple.sorted.erb.cpp', hana) %>
+ },
+ {
+ "name": "hana::tuple::reversed",
+ "data": <%= time_compilation('compile.hana.tuple.reversed.erb.cpp', hana) %>
+ },
+ {
+ "name": "hana::tuple::rand",
+ "data": <%= time_compilation('compile.hana.tuple.rand.erb.cpp', hana) %>
+ },
+ {
+ "name": "hana::tuple::sorted_but_first",
+ "data": <%= time_compilation('compile.hana.tuple.sorted_but_first.erb.cpp', hana) %>
+ },
+ {
+ "name": "hana::tuple::sorted_but_last",
+ "data": <%= time_compilation('compile.hana.tuple.sorted_but_last.erb.cpp', hana) %>
+ }
+ ]
+}
diff --git a/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.rand.erb.cpp b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.rand.erb.cpp
new file mode 100644
index 00000000..771a1ffa
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.rand.erb.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/tuple.hpp>
+#include <boost/hana/sort.hpp>
+
+int main() {
+ constexpr auto tuple = boost::hana::make_tuple(
+ <%= (1..input_size).to_a.shuffle.map { |n| "boost::hana::int_c<#{n}>" }.join(', ') %>
+ );
+ constexpr auto result = boost::hana::sort(tuple);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.reversed.erb.cpp b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.reversed.erb.cpp
new file mode 100644
index 00000000..6fc85758
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.reversed.erb.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/tuple.hpp>
+#include <boost/hana/sort.hpp>
+
+int main() {
+ constexpr auto tuple = boost::hana::make_tuple(
+ <%= (1..input_size).to_a.reverse.map { |n| "boost::hana::int_c<#{n}>" }.join(', ') %>
+ );
+ constexpr auto result = boost::hana::sort(tuple);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted.erb.cpp b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted.erb.cpp
new file mode 100644
index 00000000..c48becf0
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted.erb.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/tuple.hpp>
+#include <boost/hana/sort.hpp>
+
+int main() {
+ constexpr auto tuple = boost::hana::make_tuple(
+ <%= (1..input_size).map { |n| "boost::hana::int_c<#{n}>" }.join(', ') %>
+ );
+ constexpr auto result = boost::hana::sort(tuple);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted_but_first.erb.cpp b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted_but_first.erb.cpp
new file mode 100644
index 00000000..14795621
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted_but_first.erb.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/tuple.hpp>
+#include <boost/hana/sort.hpp>
+
+int main() {
+ constexpr auto tuple = boost::hana::make_tuple(
+ <%= ([input_size+1] + (1..input_size).to_a).map { |n| "boost::hana::int_c<#{n}>" }.join(', ') %>
+ );
+ constexpr auto result = boost::hana::sort(tuple);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted_but_last.erb.cpp b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted_but_last.erb.cpp
new file mode 100644
index 00000000..5ed14ab7
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/sort/compile.hana.tuple.sorted_but_last.erb.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/tuple.hpp>
+#include <boost/hana/sort.hpp>
+
+int main() {
+ constexpr auto tuple = boost::hana::make_tuple(
+ <%= ((1..input_size).to_a + [0]).map { |n| "boost::hana::int_c<#{n}>" }.join(', ') %>
+ );
+ constexpr auto result = boost::hana::sort(tuple);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/transform/bloat.erb.json b/src/boost/libs/hana/benchmark/transform/bloat.erb.json
new file mode 100644
index 00000000..62cbdd7a
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/bloat.erb.json
@@ -0,0 +1,42 @@
+<%
+ exec = (0..100).step(10).to_a
+ fusion = (0..50).step(10).to_a
+%>
+
+{
+ "title": {
+ "text": "Executable size for transform"
+ },
+ "yAxis": {
+ "title": {
+ "text": "Executable size (kb)"
+ },
+ "floor": 0
+ },
+ "tooltip": {
+ "valueSuffix": "kb"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= measure(:bloat, 'execute.hana.tuple.erb.cpp', exec) %>
+ }
+
+ , {
+ "name": "std::array",
+ "data": <%= measure(:bloat, 'execute.std.array.erb.cpp', exec) %>
+ }
+
+ , {
+ "name": "std::vector",
+ "data": <%= measure(:bloat, 'execute.std.vector.erb.cpp', exec) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "fusion::vector",
+ "data": <%= measure(:bloat, 'execute.fusion.vector.erb.cpp', fusion) %>
+ }
+ <% end %>
+ ]
+} \ No newline at end of file
diff --git a/src/boost/libs/hana/benchmark/transform/compile.erb.json b/src/boost/libs/hana/benchmark/transform/compile.erb.json
new file mode 100644
index 00000000..9036ab49
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/compile.erb.json
@@ -0,0 +1,49 @@
+<%
+ hana = (0...50).step(5).to_a + (50..400).step(25).to_a
+ fusion = (0..50).step(5)
+ mpl = hana
+ meta = hana
+ mpl11 = hana
+%>
+
+{
+ "title": {
+ "text": "Compile-time behavior of transform"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= time_compilation('compile.hana.tuple.erb.cpp', hana) %>
+ }, {
+ "name": "hana::types",
+ "data": <%= time_compilation('compile.hana.types.erb.cpp', hana) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "mpl::vector",
+ "data": <%= time_compilation('compile.mpl.vector.erb.cpp', mpl) %>
+ }, {
+ "name": "fusion::vector",
+ "data": <%= time_compilation('compile.fusion.vector.erb.cpp', fusion) %>
+ }, {
+ "name": "fusion::list",
+ "data": <%= time_compilation('compile.fusion.list.erb.cpp', fusion) %>
+ }
+ <% end %>
+
+ <% if cmake_bool("@Meta_FOUND@") %>
+ , {
+ "name": "meta::list",
+ "data": <%= time_compilation('compile.meta.list.erb.cpp', meta) %>
+ }
+ <% end %>
+
+ <% if cmake_bool("@MPL11_FOUND@") %>
+ , {
+ "name": "mpl11::list",
+ "data": <%= time_compilation('compile.mpl11.list.erb.cpp', mpl11) %>
+ }
+ <% end %>
+ ]
+}
diff --git a/src/boost/libs/hana/benchmark/transform/compile.fusion.list.erb.cpp b/src/boost/libs/hana/benchmark/transform/compile.fusion.list.erb.cpp
new file mode 100644
index 00000000..4ced955d
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/compile.fusion.list.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_LIST_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/as_list.hpp>
+#include <boost/fusion/include/make_list.hpp>
+#include <boost/fusion/include/transform.hpp>
+namespace fusion = boost::fusion;
+
+
+struct f {
+ template <typename X>
+ constexpr X operator()(X x) const { return x; }
+};
+
+template <int i>
+struct x { };
+
+int main() {
+ auto xs = fusion::make_list(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+
+ auto result = fusion::as_list(fusion::transform(xs, f{}));
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/transform/compile.fusion.vector.erb.cpp b/src/boost/libs/hana/benchmark/transform/compile.fusion.vector.erb.cpp
new file mode 100644
index 00000000..687e7b51
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/compile.fusion.vector.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_VECTOR_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/transform.hpp>
+namespace fusion = boost::fusion;
+
+
+struct f {
+ template <typename X>
+ constexpr X operator()(X x) const { return x; }
+};
+
+template <int i>
+struct x { };
+
+int main() {
+ auto xs = fusion::make_vector(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+
+ auto result = fusion::as_vector(fusion::transform(xs, f{}));
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/transform/compile.hana.tuple.erb.cpp b/src/boost/libs/hana/benchmark/transform/compile.hana.tuple.erb.cpp
new file mode 100644
index 00000000..0d3c8951
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/compile.hana.tuple.erb.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/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+
+struct f {
+ template <typename X>
+ constexpr X operator()(X x) const { return x; }
+};
+
+template <int i>
+struct x { };
+
+int main() {
+ constexpr auto tuple = boost::hana::make_tuple(
+ <%= (1..input_size).map { |n| "x<#{n}>{}" }.join(', ') %>
+ );
+ constexpr auto result = boost::hana::transform(tuple, f{});
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/transform/compile.hana.types.erb.cpp b/src/boost/libs/hana/benchmark/transform/compile.hana.types.erb.cpp
new file mode 100644
index 00000000..0ad75569
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/compile.hana.types.erb.cpp
@@ -0,0 +1,26 @@
+/*
+@copyright Louis Dionne 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+
+#include <boost/hana/experimental/types.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <typename>
+struct f { struct type; };
+
+template <int> struct x;
+
+
+int main() {
+ constexpr auto types = hana::experimental::types<
+ <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
+ >{};
+
+ constexpr auto result = hana::transform(types, hana::metafunction<f>);
+ (void)result;
+}
diff --git a/src/boost/libs/hana/benchmark/transform/compile.meta.list.erb.cpp b/src/boost/libs/hana/benchmark/transform/compile.meta.list.erb.cpp
new file mode 100644
index 00000000..1341cccb
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/compile.meta.list.erb.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 <meta/meta.hpp>
+
+
+struct f {
+ template <typename>
+ struct apply;
+};
+
+template <int> struct x;
+
+using list = meta::list<
+ <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
+>;
+
+using result = meta::transform<list, f>;
+
+int main() {
+
+}
diff --git a/src/boost/libs/hana/benchmark/transform/compile.mpl.vector.erb.cpp b/src/boost/libs/hana/benchmark/transform/compile.mpl.vector.erb.cpp
new file mode 100644
index 00000000..a7bdc72d
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/compile.mpl.vector.erb.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/mpl/push_back.hpp>
+#include <boost/mpl/quote.hpp>
+#include <boost/mpl/transform.hpp>
+#include <boost/mpl/vector.hpp>
+
+
+template <typename X>
+struct f { using type = X; };
+
+template <int i>
+struct t { };
+
+using vector = <%= mpl_vector((1..input_size).to_a.map { |n| "t<#{n}>" }) %>;
+
+using result = boost::mpl::transform<vector, boost::mpl::quote1<f>>::type;
+
+
+int main() { }
diff --git a/src/boost/libs/hana/benchmark/transform/compile.mpl11.list.erb.cpp b/src/boost/libs/hana/benchmark/transform/compile.mpl11.list.erb.cpp
new file mode 100644
index 00000000..262e48bc
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/compile.mpl11.list.erb.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/mpl11/list.hpp>
+
+
+struct f {
+ using type = f;
+ template <typename>
+ struct apply { struct type; };
+};
+
+template <int> struct x { struct type; };
+
+using list = boost::mpl11::list<
+ <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
+>;
+
+using result = boost::mpl11::fmap<f, list>::type;
+
+int main() {
+
+}
diff --git a/src/boost/libs/hana/benchmark/transform/execute.erb.json b/src/boost/libs/hana/benchmark/transform/execute.erb.json
new file mode 100644
index 00000000..98738317
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/execute.erb.json
@@ -0,0 +1,36 @@
+<%
+ exec = (0..100).step(10).to_a
+ fusion = (0..50).step(10).to_a
+%>
+
+{
+ "title": {
+ "text": "Runtime behavior of transform"
+ },
+ "series": [
+ {
+ "name": "hana::tuple",
+ "data": <%= time_execution('execute.hana.tuple.erb.cpp', exec) %>
+ }
+
+ , {
+ "name": "std::array",
+ "data": <%= time_execution('execute.std.array.erb.cpp', exec) %>
+ }
+
+ , {
+ "name": "std::vector",
+ "data": <%= time_execution('execute.std.vector.erb.cpp', exec) %>
+ }
+
+ <% if cmake_bool("@Boost_FOUND@") %>
+ , {
+ "name": "fusion::vector",
+ "data": <%= time_execution('execute.fusion.vector.erb.cpp', fusion) %>
+ }, {
+ "name": "fusion::list",
+ "data": <%= time_execution('execute.fusion.list.erb.cpp', fusion) %>
+ }
+ <% end %>
+ ]
+}
diff --git a/src/boost/libs/hana/benchmark/transform/execute.fusion.list.erb.cpp b/src/boost/libs/hana/benchmark/transform/execute.fusion.list.erb.cpp
new file mode 100644
index 00000000..5855a61d
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/execute.fusion.list.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_LIST_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/as_list.hpp>
+#include <boost/fusion/include/make_list.hpp>
+#include <boost/fusion/include/transform.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+int main () {
+ hana::benchmark::measure([] {
+ long long result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ auto values = fusion::make_list(
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ );
+
+ auto transformed = fusion::as_list(fusion::transform(values, [&](auto t) {
+ return result += t;
+ }));
+ (void)transformed;
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/transform/execute.fusion.vector.erb.cpp b/src/boost/libs/hana/benchmark/transform/execute.fusion.vector.erb.cpp
new file mode 100644
index 00000000..721a35f2
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/execute.fusion.vector.erb.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)
+
+<% if input_size > 10 %>
+ #define FUSION_MAX_VECTOR_SIZE <%= ((input_size + 9) / 10) * 10 %>
+<% end %>
+
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/transform.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+namespace fusion = boost::fusion;
+namespace hana = boost::hana;
+
+
+int main () {
+ hana::benchmark::measure([] {
+ long long result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ auto values = fusion::make_vector(
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ );
+
+ auto transformed = fusion::as_vector(fusion::transform(values, [&](auto t) {
+ return result += t;
+ }));
+ (void)transformed;
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/transform/execute.hana.tuple.erb.cpp b/src/boost/libs/hana/benchmark/transform/execute.hana.tuple.erb.cpp
new file mode 100644
index 00000000..8d58e193
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/execute.hana.tuple.erb.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/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include "measure.hpp"
+#include <cstdlib>
+
+
+int main () {
+ boost::hana::benchmark::measure([] {
+ long long result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ auto values = boost::hana::make_tuple(
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ );
+
+ auto transformed = boost::hana::transform(values, [&](auto t) {
+ return result += t;
+ });
+ (void)transformed;
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/transform/execute.std.array.erb.cpp b/src/boost/libs/hana/benchmark/transform/execute.std.array.erb.cpp
new file mode 100644
index 00000000..f5537be4
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/execute.std.array.erb.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 "measure.hpp"
+#include <algorithm>
+#include <array>
+#include <cstdlib>
+
+
+int main () {
+ boost::hana::benchmark::measure([] {
+ long long result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ std::array<int, <%= input_size %>> values = {{
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ }};
+
+ std::array<long long, <%= input_size %>> results{};
+
+ std::transform(values.begin(), values.end(), results.begin(), [&](auto t) {
+ return result += t;
+ });
+ }
+ });
+}
diff --git a/src/boost/libs/hana/benchmark/transform/execute.std.vector.erb.cpp b/src/boost/libs/hana/benchmark/transform/execute.std.vector.erb.cpp
new file mode 100644
index 00000000..5b6b11d7
--- /dev/null
+++ b/src/boost/libs/hana/benchmark/transform/execute.std.vector.erb.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 "measure.hpp"
+#include <algorithm>
+#include <cstdlib>
+#include <vector>
+
+
+int main () {
+ boost::hana::benchmark::measure([] {
+ long long result = 0;
+ for (int iteration = 0; iteration < 1 << 10; ++iteration) {
+ std::vector<int> values = {
+ <%= input_size.times.map { 'std::rand()' }.join(', ') %>
+ };
+
+ std::vector<long long> results;
+ results.reserve(<%= input_size %>);
+
+ std::transform(values.begin(), values.end(), results.begin(), [&](auto t) {
+ return result += t;
+ });
+ }
+ });
+}
diff --git a/src/boost/libs/hana/cmake/CheckCxxCompilerSupport.cmake b/src/boost/libs/hana/cmake/CheckCxxCompilerSupport.cmake
new file mode 100644
index 00000000..0b5d72a6
--- /dev/null
+++ b/src/boost/libs/hana/cmake/CheckCxxCompilerSupport.cmake
@@ -0,0 +1,85 @@
+# Copyright Louis Dionne 2013-2017
+# Copyright Markus J. Weber 2015
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+#
+#
+# This CMake module checks whether the current compiler is supported, and
+# provides friendly hints to the user.
+
+if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
+ if (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS "3.9.1")
+ message(WARNING "
+ ### You appear to be using Clang ${CMAKE_CXX_COMPILER_VERSION}, which is known
+ ### to be unable to compile Hana. Consider switching to
+ ### Clang >= 3.9.1. If it is already installed on your
+ ### system, you can tell CMake about it with
+ ###
+ ### cmake .. -DCMAKE_CXX_COMPILER=/path/to/clang
+ ")
+ endif()
+
+ if (MSVC)
+ if(${MSVC_VERSION} LESS 1900)
+ message(WARNING "
+ ###
+ ### We detected that you were using Clang for Windows with a
+ ### -fms-compatibility-version parameter lower than 19. Only
+ ### -fms-compatibility-version=19 and above are supported by
+ ### Hana for lack of proper C++14 support prior for versions
+ ### below that.
+ ###
+ ### If this diagnostic is wrong and you are not using
+ ### -fms-compatibility-version, please file an issue at
+ ### https://github.com/boostorg/hana/issues.
+ ###
+ ")
+ endif()
+ endif()
+elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "AppleClang")
+ if (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS "6.1.0")
+ message(WARNING "
+ ### You appear to be using Apple's Clang ${CMAKE_CXX_COMPILER_VERSION}, which is
+ ### shipped with Xcode < 6.3. Unfortunately, only Apple's Clang
+ ### >= 6.1.0 (shipped with Xcode >= 6.3) can compile Hana.
+ ### You should consider updating to Xcode >= 6.3 (requires Yosemite)
+ ### or using a non-Apple Clang >= 3.9.1, which can be installed via
+ ### Homebrew with
+ ###
+ ### brew install llvm --with-clang
+ ###
+ ### You can then tell CMake to use that non-system Clang with
+ ###
+ ### cmake .. -DCMAKE_CXX_COMPILER=/path/to/clang
+ ")
+ endif()
+elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
+ if (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS "6.0.0")
+ message(WARNING "
+ ### You appear to be using GCC ${CMAKE_CXX_COMPILER_VERSION}, which is known to be
+ ### unable to compile Hana. Only GCC >= 6.0.0 is supported.
+ ### Consider using a more recent GCC or switching to Clang.
+ ### If a more recent compiler is already installed on your
+ ### system, you can tell CMake to use it with
+ ###
+ ### cmake .. -DCMAKE_CXX_COMPILER=/path/to/compiler
+ ")
+ endif()
+elseif (MSVC)
+ message(WARNING "
+ ### Using the native Microsoft compiler (MSVC) is not supported for lack
+ ### of proper C++14 support. However, you can install pre-built Clang for
+ ### Windows binaries (with Visual Studio integration if desired) at
+ ### http://llvm.org/releases/download.html.
+ ###
+ ### More information about how to set up Hana with Clang for Windows is
+ ### available on Hana's wiki at http://git.io/vBYIp.
+ ")
+else()
+ message(WARNING "
+ ### You appear to be using a compiler that is not yet tested with Hana.
+ ### Please tell us whether it successfully compiles or if and how it
+ ### fails by opening an issue at https://github.com/boostorg/hana/issues.
+ ### Thanks!
+ ")
+endif()
diff --git a/src/boost/libs/hana/cmake/FindMPL11.cmake b/src/boost/libs/hana/cmake/FindMPL11.cmake
new file mode 100644
index 00000000..5b8b3c4e
--- /dev/null
+++ b/src/boost/libs/hana/cmake/FindMPL11.cmake
@@ -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)
+#
+#
+# This CMake module finds the MPL11 include directory. This module sets the
+# following CMake variables:
+#
+# MPL11_FOUND
+# Set to 1 when the MPL11 include directory is found, 0 otherwise.
+#
+# MPL11_INCLUDE_DIR
+# If the MPL11 include directory is found, this is set to the path of that
+# directory. Otherwise, this is not set.
+#
+#
+# The following variables can be used to customize the behavior of the module:
+#
+# MPL11_INCLUDE_DIR
+# The path to the MPL11 include directory. When set, this will be used as-is.
+#
+# MPL11_CLONE_IF_MISSING
+# If the MPL11 include directory can't be found and this is set to true,
+# the MPL11 project will be cloned locally.
+
+if (NOT EXISTS "${MPL11_INCLUDE_DIR}")
+ find_path(MPL11_INCLUDE_DIR NAMES boost/mpl11/mpl11.hpp
+ DOC "MPL11 library header files")
+endif()
+
+if (NOT EXISTS "${MPL11_INCLUDE_DIR}" AND MPL11_CLONE_IF_MISSING)
+ include(ExternalProject)
+ ExternalProject_Add(MPL11 EXCLUDE_FROM_ALL 1
+ GIT_REPOSITORY https://github.com/ldionne/mpl11
+ TIMEOUT 5
+ CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
+ PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
+ BUILD_COMMAND "" # Disable build step
+ INSTALL_COMMAND "" # Disable install step
+ TEST_COMMAND "" # Disable test step
+ )
+
+ ExternalProject_Get_Property(MPL11 SOURCE_DIR)
+ set(MPL11_INCLUDE_DIR "${SOURCE_DIR}/include")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MPL11 DEFAULT_MSG MPL11_INCLUDE_DIR)
diff --git a/src/boost/libs/hana/cmake/FindMeta.cmake b/src/boost/libs/hana/cmake/FindMeta.cmake
new file mode 100644
index 00000000..0a532062
--- /dev/null
+++ b/src/boost/libs/hana/cmake/FindMeta.cmake
@@ -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)
+#
+# This file was adapted from FindMeta.cmake at https://github.com/ericniebler/meta.
+#
+#
+# This CMake module finds the Meta include directory. This module sets the
+# following CMake variables:
+#
+# Meta_FOUND
+# Set to 1 when the Meta include directory is found, 0 otherwise.
+#
+# Meta_INCLUDE_DIR
+# If the Meta include directory is found, this is set to the path of that
+# directory. Otherwise, this is not set.
+#
+#
+# The following variables can be used to customize the behavior of the module:
+#
+# Meta_INCLUDE_DIR
+# The path to the Meta include directory. When set, this will be used as-is.
+#
+# Meta_CLONE_IF_MISSING
+# If the Meta include directory can't be found and this is set to true,
+# the Meta project will be cloned locally.
+
+if (NOT EXISTS "${Meta_INCLUDE_DIR}")
+ find_path(Meta_INCLUDE_DIR NAMES meta/meta.hpp
+ DOC "Meta library header files")
+endif()
+
+if (NOT EXISTS "${Meta_INCLUDE_DIR}" AND Meta_CLONE_IF_MISSING)
+ include(ExternalProject)
+ ExternalProject_Add(meta EXCLUDE_FROM_ALL 1
+ GIT_REPOSITORY https://github.com/ericniebler/meta
+ TIMEOUT 5
+ CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
+ PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
+ BUILD_COMMAND "" # Disable build step
+ INSTALL_COMMAND "" # Disable install step
+ TEST_COMMAND "" # Disable test step
+ )
+
+ ExternalProject_Get_Property(meta SOURCE_DIR)
+ set(Meta_INCLUDE_DIR "${SOURCE_DIR}/include")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Meta
+ FOUND_VAR Meta_FOUND
+ REQUIRED_VARS Meta_INCLUDE_DIR)
diff --git a/src/boost/libs/hana/cmake/TestHeaders.cmake b/src/boost/libs/hana/cmake/TestHeaders.cmake
new file mode 100644
index 00000000..663c9f4e
--- /dev/null
+++ b/src/boost/libs/hana/cmake/TestHeaders.cmake
@@ -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)
+#
+#
+# This CMake module provides a function generating a unit test to make sure
+# that every public header can be included on its own.
+#
+# When a C++ library or application has many header files, it can happen that
+# a header does not include all the other headers it depends on. When this is
+# the case, it can happen that including that header file on its own will
+# break the compilation. This CMake module generates a dummy executable
+# comprised of many .cpp files, each of which includes a header file that
+# is part of the public API. In other words, the executable is comprised
+# of .cpp files of the form:
+#
+# #include <the/public/header.hpp>
+#
+# and then exactly one `main` function. If this succeeds to compile, it means
+# that the header can be included on its own, which is what clients expect.
+# Otherwise, you have a problem. Since writing these dumb unit tests by hand
+# is tedious and repetitive, you can use this CMake module to automate this
+# task.
+
+# add_header_test(<target> [EXCLUDE_FROM_ALL] [EXCLUDE excludes...] HEADERS headers...)
+#
+# Generates header-inclusion unit tests for all the specified headers.
+#
+# This function creates a target which builds a dummy executable including
+# each specified header file individually. If this target builds successfully,
+# it means that all the specified header files can be included individually.
+#
+# Parameters
+# ----------
+# <target>:
+# The name of the target to generate.
+#
+# HEADERS headers:
+# A list of header files to generate the inclusion tests for. All headers
+# in this list must be represented as relative paths from the root of the
+# include directory added to the compiler's header search path. In other
+# words, it should be possible to include all headers in this list as
+#
+# #include <${header}>
+#
+# For example, for a library with the following structure:
+#
+# project/
+# doc/
+# test/
+# ...
+# include/
+# boost/
+# hana.hpp
+# hana/
+# transform.hpp
+# tuple.hpp
+# pair.hpp
+# ...
+#
+# When building the unit tests for that library, we'll add `-I project/include'
+# to the compiler's arguments. The list of public headers should therefore contain
+#
+# boost/hana.hpp
+# boost/hana/transform.hpp
+# boost/hana/tuple.hpp
+# boost/hana/pair.hpp
+# ...
+#
+# Usually, all the 'public' header files of a library should be tested for
+# standalone inclusion. A header is considered 'public' if a client should
+# be able to include that header on its own.
+#
+# [EXCLUDE excludes]:
+# An optional list of headers or regexes for which no unit test should be
+# generated. Basically, any header in the list specified by the `HEADERS`
+# argument that matches anything in `EXCLUDE` will be skipped.
+#
+# [EXCLUDE_FROM_ALL]:
+# If provided, the generated target is excluded from the 'all' target.
+#
+function(add_header_test target)
+ cmake_parse_arguments(ARGS "EXCLUDE_FROM_ALL" # options
+ "" # 1 value args
+ "HEADERS;EXCLUDE" # multivalued args
+ ${ARGN})
+ if (NOT ARGS_HEADERS)
+ message(FATAL_ERROR "The `HEADERS` argument must be provided.")
+ endif()
+
+ if (ARGS_EXCLUDE_FROM_ALL)
+ set(ARGS_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL")
+ else()
+ set(ARGS_EXCLUDE_FROM_ALL "")
+ endif()
+
+ foreach(header ${ARGS_HEADERS})
+ set(skip FALSE)
+ foreach(exclude ${ARGS_EXCLUDE})
+ if (${header} MATCHES ${exclude})
+ set(skip TRUE)
+ break()
+ endif()
+ endforeach()
+ if (skip)
+ continue()
+ endif()
+
+ get_filename_component(filename "${header}" NAME_WE)
+ get_filename_component(directory "${header}" DIRECTORY)
+
+ set(source "${CMAKE_CURRENT_BINARY_DIR}/headers/${directory}/${filename}.cpp")
+ if (NOT EXISTS "${source}")
+ file(WRITE "${source}" "#include <${header}>")
+ endif()
+ list(APPEND sources "${source}")
+ endforeach()
+
+ set(standalone_main "${CMAKE_CURRENT_BINARY_DIR}/headers/_standalone_main.cpp")
+ if (NOT EXISTS "${standalone_main}")
+ file(WRITE "${standalone_main}" "int main() { }")
+ endif()
+ add_executable(${target}
+ ${ARGS_EXCLUDE_FROM_ALL}
+ ${sources}
+ "${CMAKE_CURRENT_BINARY_DIR}/headers/_standalone_main.cpp"
+ )
+endfunction()
diff --git a/src/boost/libs/hana/cmake/hana.pc.in b/src/boost/libs/hana/cmake/hana.pc.in
new file mode 100644
index 00000000..316d379a
--- /dev/null
+++ b/src/boost/libs/hana/cmake/hana.pc.in
@@ -0,0 +1,5 @@
+Name: Boost.Hana
+Description: A modern C++ metaprogramming library
+URL: https://github.com/boostorg/hana
+Version: @Boost.Hana_VERSION_STRING@
+Cflags: -I@CMAKE_INSTALL_PREFIX@/include
diff --git a/src/boost/libs/hana/example/CMakeLists.txt b/src/boost/libs/hana/example/CMakeLists.txt
new file mode 100644
index 00000000..0f59c512
--- /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 00000000..cbc48901
--- /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 00000000..54e591dc
--- /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 00000000..9170e2ce
--- /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 00000000..74ad1836
--- /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 00000000..399f9e60
--- /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 00000000..b34e31eb
--- /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 00000000..6a7dee95
--- /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 00000000..f33a32d7
--- /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 00000000..14e0861f
--- /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 00000000..330c1063
--- /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 00000000..51000d91
--- /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 00000000..8731cb73
--- /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 00000000..802a4f7d
--- /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 00000000..df4e257f
--- /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 00000000..41f29b57
--- /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 00000000..4ca689c1
--- /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 00000000..b037dd04
--- /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 00000000..22aab507
--- /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 00000000..0e7850b7
--- /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 00000000..000d03dd
--- /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 00000000..e35e8135
--- /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 00000000..8c653881
--- /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 00000000..d344a58d
--- /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 00000000..ce7bc5d1
--- /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 00000000..30883b27
--- /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 00000000..25df42df
--- /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 00000000..2dcd40f2
--- /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 00000000..618637a2
--- /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 00000000..e076924d
--- /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 00000000..2f0906d4
--- /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 00000000..07244ea2
--- /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 00000000..73ff31b5
--- /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 00000000..a534ea12
--- /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 00000000..59185c0e
--- /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 00000000..2c9ddf7b
--- /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 00000000..6689ef96
--- /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 00000000..2c5e34d2
--- /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 00000000..2ed680fa
--- /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 00000000..8e26b2da
--- /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 00000000..da7a42eb
--- /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 00000000..f9315146
--- /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 00000000..8597e70f
--- /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 00000000..b616a524
--- /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 00000000..0d5d020f
--- /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 00000000..d84b0dac
--- /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 00000000..f499fda7
--- /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 00000000..5bb3cd85
--- /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 00000000..87c90b7a
--- /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 00000000..d7e14246
--- /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 00000000..87d62817
--- /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 00000000..748f4f8a
--- /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 00000000..9d06400d
--- /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 00000000..e86eba49
--- /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 00000000..578e9b15
--- /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 00000000..2b603c62
--- /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 00000000..5c909e1d
--- /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 00000000..8083c2ee
--- /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 00000000..c4838837
--- /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 00000000..e7e6923c
--- /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 00000000..0e3cf7e7
--- /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 00000000..44737cb7
--- /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 00000000..71900cac
--- /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 00000000..a917ebad
--- /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 00000000..f17bd11c
--- /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 00000000..60aeef42
--- /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 00000000..965e7847
--- /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 00000000..dbd2cfc7
--- /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 00000000..2c4743b0
--- /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 00000000..fd2f115b
--- /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 00000000..e4b78135
--- /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 00000000..7f281648
--- /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 00000000..2bed0559
--- /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 00000000..6f21fdc8
--- /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 00000000..87a803c2
--- /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 00000000..4ce0fd77
--- /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 00000000..c5e936f5
--- /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 00000000..7319f200
--- /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 00000000..eb9411a6
--- /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 00000000..c6751a3b
--- /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 00000000..47694992
--- /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 00000000..319e8083
--- /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 00000000..c1c81487
--- /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 00000000..cff38e1c
--- /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 00000000..d14dbd91
--- /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 00000000..7f4c9f2b
--- /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 00000000..10b62752
--- /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 00000000..4d7c3253
--- /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 00000000..ef421ec3
--- /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 00000000..c0a159bc
--- /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 00000000..04e234f1
--- /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 00000000..d118b18f
--- /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 00000000..7bcdbbd3
--- /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 00000000..05d64de3
--- /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 00000000..7764bb12
--- /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 00000000..d545d6fb
--- /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 00000000..9d5351b1
--- /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 00000000..1334a831
--- /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 00000000..d18a8214
--- /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 00000000..af7fbba3
--- /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 00000000..cd75bc97
--- /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 00000000..73264683
--- /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 00000000..c48a9b65
--- /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 00000000..61c3d272
--- /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 00000000..a351be58
--- /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 00000000..4480c3f6
--- /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 00000000..5a9e675d
--- /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 00000000..ec6a24a5
--- /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 00000000..e58ad920
--- /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 00000000..74278545
--- /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 00000000..5c459442
--- /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 00000000..a5686a9c
--- /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 00000000..53030a66
--- /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 00000000..588c9b3f
--- /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 00000000..a1e026df
--- /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 00000000..6e24b039
--- /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 00000000..8dfd69eb
--- /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 00000000..62ad0374
--- /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 00000000..9afb2bca
--- /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 00000000..16a39c1e
--- /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 00000000..3b74044d
--- /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 00000000..40aa7c93
--- /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 00000000..cbb8266c
--- /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 00000000..bc5e5662
--- /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 00000000..2a78f7b5
--- /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 00000000..632234f5
--- /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 00000000..ac40f12a
--- /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 00000000..31cbc4a5
--- /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 00000000..45ba8f18
--- /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 00000000..52f422db
--- /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 00000000..be5b56c7
--- /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 00000000..5b9021c4
--- /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 00000000..9025cb0a
--- /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 00000000..dcbdd7af
--- /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 00000000..9d580a07
--- /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 00000000..ae8f227c
--- /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 00000000..098b2b8c
--- /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 00000000..d2e210a6
--- /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 00000000..1d78c57a
--- /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 00000000..aaad126d
--- /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 00000000..3e956699
--- /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 00000000..71cde04e
--- /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 00000000..d9893511
--- /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 00000000..064942b5
--- /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 00000000..a685361c
--- /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 00000000..39bbbea6
--- /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 00000000..5fa20ab3
--- /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 00000000..d602c96d
--- /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 00000000..f425e281
--- /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 00000000..26246dac
--- /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 00000000..1762aede
--- /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 00000000..368c2e89
--- /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 00000000..5c70f59e
--- /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 00000000..c8f777cb
--- /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 00000000..4c3d348b
--- /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 00000000..6b94b0a2
--- /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 00000000..2ba40714
--- /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 00000000..1884220a
--- /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 00000000..80aff7d5
--- /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 00000000..1be8bf0b
--- /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 00000000..073d6dec
--- /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 00000000..a9660e1c
--- /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 00000000..a04ecfd7
--- /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 00000000..4f51e704
--- /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 00000000..0f978475
--- /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 00000000..550c7665
--- /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 00000000..d214b34d
--- /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 00000000..4bbfb92f
--- /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 00000000..15b1031b
--- /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 00000000..b6d377d5
--- /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 00000000..5ee979c2
--- /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 00000000..0353f3af
--- /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 00000000..0449bae4
--- /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 00000000..4349f290
--- /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 00000000..2595744e
--- /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 00000000..de1aa967
--- /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 00000000..40872df9
--- /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 00000000..a28cac1e
--- /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 00000000..de8308e4
--- /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 00000000..b5eecaf1
--- /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 00000000..6bccfd53
--- /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 00000000..d3bcbd19
--- /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 00000000..ffbdf1eb
--- /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 00000000..a41174a2
--- /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 00000000..01f5a9ab
--- /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 00000000..48892580
--- /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 00000000..6a290489
--- /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 00000000..c74a3e2c
--- /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 00000000..cc078519
--- /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 00000000..9c95ee7f
--- /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 00000000..734c055e
--- /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 00000000..25596240
--- /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 00000000..22522df1
--- /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 00000000..1a52322b
--- /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 00000000..38aa012f
--- /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 00000000..17d24a5b
--- /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 00000000..119372c6
--- /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 00000000..5750bf84
--- /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 00000000..536300a3
--- /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 00000000..f8eb84a7
--- /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 00000000..3c67c30e
--- /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 00000000..ba192b85
--- /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 00000000..21fc920c
--- /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 00000000..6faf54a0
--- /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 00000000..7c7216ac
--- /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 00000000..ffde02df
--- /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 00000000..bf7d3204
--- /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 00000000..fd0034a7
--- /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 00000000..5e90cb65
--- /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 00000000..2be7821a
--- /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 00000000..d3268152
--- /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 00000000..81f109e9
--- /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 00000000..b8cb7e11
--- /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 00000000..e95d451a
--- /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 00000000..1fe9adf0
--- /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 00000000..392154b3
--- /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 00000000..adbb7aac
--- /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 00000000..1d0b2296
--- /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 00000000..567aebcf
--- /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 00000000..9f8c18ed
--- /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 00000000..37b802f3
--- /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 00000000..63610e2f
--- /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 00000000..e9e92c74
--- /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 00000000..f13e3de9
--- /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 00000000..14c87e5b
--- /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 00000000..c48db2ce
--- /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 00000000..708c4eaa
--- /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 00000000..413c24c6
--- /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 00000000..7de42fbd
--- /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 00000000..d869977f
--- /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 00000000..0db9eb5d
--- /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 00000000..3ca19eb7
--- /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 00000000..52cb4bc1
--- /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 00000000..d9b3a43f
--- /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 00000000..5c85f839
--- /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 00000000..a27014cc
--- /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 00000000..e294b543
--- /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 00000000..f696ebc6
--- /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 00000000..0c151054
--- /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 00000000..9b7da7ae
--- /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 00000000..4ffb5205
--- /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 00000000..80f96f78
--- /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 00000000..b0dc9555
--- /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 00000000..e6211796
--- /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 00000000..83295bb3
--- /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 00000000..dc813f0f
--- /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 00000000..742eb9ac
--- /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 00000000..444ac1c8
--- /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 00000000..9d450a2a
--- /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 00000000..6f10c473
--- /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 00000000..df9880b6
--- /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 00000000..91d3db53
--- /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 00000000..96fd7793
--- /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 00000000..0e176ac1
--- /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 00000000..42e04d39
--- /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 00000000..310c886a
--- /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 00000000..c46ffcea
--- /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 00000000..5888a653
--- /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 00000000..cdef35f1
--- /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 00000000..0b26e647
--- /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 00000000..5a9a8794
--- /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 00000000..658e4a19
--- /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 00000000..3dccdb8a
--- /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 00000000..27ea46da
--- /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 00000000..ba2f89a3
--- /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 00000000..00003587
--- /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 00000000..568592bf
--- /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 00000000..4bc2ecad
--- /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 00000000..e91a9222
--- /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 00000000..d3bc3cd5
--- /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 00000000..0f17415e
--- /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 00000000..47fffc76
--- /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 00000000..1d080432
--- /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 00000000..08f84834
--- /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 00000000..81fa2693
--- /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 00000000..0e66e73e
--- /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 00000000..59f0cb91
--- /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 00000000..b52d1d4a
--- /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 00000000..f3f44e01
--- /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 00000000..95407931
--- /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 00000000..8e1e990a
--- /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 00000000..59161a98
--- /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 00000000..c3109563
--- /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 00000000..e86d4bb0
--- /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 00000000..d1d4661e
--- /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 00000000..3441473e
--- /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 00000000..a781fdef
--- /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 00000000..af7a2f38
--- /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 00000000..feab6f69
--- /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 00000000..3c2d2ea7
--- /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 00000000..c7bac05d
--- /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 00000000..305e6351
--- /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 00000000..21faeaa2
--- /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 00000000..b7e2175a
--- /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 00000000..32723407
--- /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 00000000..16109a23
--- /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 00000000..1328d01c
--- /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 00000000..3ba10a37
--- /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 00000000..9788e830
--- /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 00000000..238f4dc5
--- /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 00000000..7f52e920
--- /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 00000000..37e97040
--- /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 00000000..aae5dbfa
--- /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 00000000..501f7260
--- /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 00000000..8d2f5192
--- /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 00000000..3fded1a4
--- /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 00000000..e4a988b0
--- /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 00000000..c4d035df
--- /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 00000000..347619a7
--- /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 00000000..554bb485
--- /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 00000000..79f6b21e
--- /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 00000000..6c93eeb5
--- /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 00000000..40c192c1
--- /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 00000000..0bdf4cb0
--- /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 00000000..8a5354e3
--- /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 00000000..cc274aee
--- /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 00000000..e88fe38a
--- /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 00000000..e16ff8d0
--- /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 00000000..01222174
--- /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 00000000..7da9107e
--- /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 00000000..9afe86b1
--- /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 00000000..3174af2c
--- /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 00000000..751b4730
--- /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 00000000..ea81ec08
--- /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 00000000..fe924270
--- /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 00000000..8b6a334d
--- /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 00000000..2802bafe
--- /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 00000000..e3c15546
--- /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 00000000..d753d624
--- /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 00000000..7e93f940
--- /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 00000000..be285c56
--- /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 00000000..1cafff04
--- /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 00000000..bfdf4453
--- /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 00000000..3b72db44
--- /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 00000000..d81dd001
--- /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 00000000..9b987ff9
--- /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 00000000..d9e87345
--- /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 00000000..6358e503
--- /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 00000000..4456aef3
--- /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 00000000..9d419af1
--- /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 00000000..19ca9d15
--- /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 00000000..92010d49
--- /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 00000000..b4fb9452
--- /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 00000000..e3104d65
--- /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 00000000..19eb282b
--- /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 00000000..45110f1a
--- /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 00000000..eaecfff1
--- /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 00000000..612665de
--- /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 00000000..a683e78f
--- /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 00000000..97bb4a11
--- /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 00000000..a60d6077
--- /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 00000000..f01e2671
--- /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 00000000..300015dd
--- /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 00000000..3840cc7c
--- /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 00000000..31064bc7
--- /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 00000000..f219aec3
--- /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 00000000..4d77d01c
--- /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 00000000..f4599ddc
--- /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 00000000..4f3b67c6
--- /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 00000000..f2ceb5da
--- /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 00000000..d78f2878
--- /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 00000000..413cf6d0
--- /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 00000000..9d18fa9e
--- /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 00000000..b56465d6
--- /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 00000000..73dc27f9
--- /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 00000000..d6f92383
--- /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 00000000..4c03c49a
--- /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 00000000..860a27e1
--- /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 00000000..ea5a40fa
--- /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 00000000..55ae0102
--- /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() { }
diff --git a/src/boost/libs/hana/hana.sublime-project b/src/boost/libs/hana/hana.sublime-project
new file mode 100644
index 00000000..5fcd4b1c
--- /dev/null
+++ b/src/boost/libs/hana/hana.sublime-project
@@ -0,0 +1,38 @@
+{
+ "folders":
+ [
+ {
+ "follow_symlinks": true,
+ "path": "."
+ }
+ ],
+
+ "build_systems":
+ [
+ {
+ "name": "[Hana] Build current file",
+ "selector": "source.c++",
+ "working_dir": "$project_path/build",
+ "cmd": ["ruby"
+ , "-r", "pathname"
+ , "-e", "project = Pathname.new('${project_path}')"
+ , "-e", "file = Pathname.new('${file}').relative_path_from(project)"
+ , "-e", "target = file.sub_ext('').to_s.gsub('/', '.')"
+ , "-e", "system('/usr/local/bin/cmake', '--build', '$project_path/build', '--target', target)"
+ ],
+ "variants": [
+ {
+ "name": "Primary Quick Build",
+ "cmd": ["ruby"
+ , "-r", "pathname"
+ , "-e", "project = Pathname.new('${project_path}')"
+ , "-e", "file = Pathname.new('${file}').relative_path_from(project)"
+ , "-e", "target = file.sub_ext('').to_s.gsub('/', '.')"
+ , "-e", "system('/usr/local/bin/cmake', '--build', '$project_path/build', '--target', target)"
+ , "-e", "system('/usr/local/bin/ctest', '-V', '--output-on-failure', '-R', target)"
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/boost/libs/hana/index.html b/src/boost/libs/hana/index.html
new file mode 100644
index 00000000..f7fb3b83
--- /dev/null
+++ b/src/boost/libs/hana/index.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+ </head>
+
+ <body>
+ Automatic redirection failed, click this <a href="doc/html/index.html">link</a>
+ <hr>
+ <p>Copyright Louis Dionne 2013-2017</p>
+ <p>
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file <a href="LICENSE.md">LICENSE.md</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)
+ </p>
+ </body>
+</html>
diff --git a/src/boost/libs/hana/meta/libraries.json b/src/boost/libs/hana/meta/libraries.json
new file mode 100644
index 00000000..dc33cf9d
--- /dev/null
+++ b/src/boost/libs/hana/meta/libraries.json
@@ -0,0 +1,10 @@
+{
+ "key": "hana",
+ "name": "Hana",
+ "authors": [ "Louis Dionne" ],
+ "maintainers": [ "Louis Dionne <ldionne.2 -at- gmail.com>" ],
+ "description": "A modern C++ metaprogramming library. It provides high level algorithms to manipulate heterogeneous sequences, allows writing type-level computations with a natural syntax, provides tools to introspect user-defined types and much more.",
+ "category": [
+ "Metaprogramming"
+ ]
+} \ No newline at end of file
diff --git a/src/boost/libs/hana/test/CMakeLists.txt b/src/boost/libs/hana/test/CMakeLists.txt
new file mode 100644
index 00000000..c51d577f
--- /dev/null
+++ b/src/boost/libs/hana/test/CMakeLists.txt
@@ -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)
+
+add_custom_target(tests COMMENT "Build all the unit tests.")
+add_dependencies(hana_check tests)
+
+
+##############################################################################
+# Take note of files that depend on Boost
+##############################################################################
+file(GLOB_RECURSE TESTS_REQUIRING_BOOST "ext/boost/*.cpp"
+ "experimental/printable/*.cpp")
+
+file(GLOB_RECURSE PUBLIC_HEADERS_REQUIRING_BOOST
+ RELATIVE "${Boost.Hana_SOURCE_DIR}/include"
+ "${Boost.Hana_SOURCE_DIR}/include/boost/hana/ext/boost/*.hpp"
+ "${Boost.Hana_SOURCE_DIR}/include/boost/hana/ext/boost.hpp"
+ "${Boost.Hana_SOURCE_DIR}/include/boost/hana/experimental/printable.hpp"
+)
+
+
+##############################################################################
+# Caveats: Take note of public headers and tests that are not supported.
+##############################################################################
+if (NOT Boost_FOUND)
+ list(APPEND EXCLUDED_UNIT_TESTS ${TESTS_REQUIRING_BOOST})
+ list(APPEND EXCLUDED_PUBLIC_HEADERS ${PUBLIC_HEADERS_REQUIRING_BOOST})
+endif()
+
+# The experimental::type_name test is only supported on Clang and AppleClang >= 7.0
+if (NOT (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"
+ OR (${CMAKE_CXX_COMPILER_ID} STREQUAL "AppleClang" AND
+ NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 7)))
+ list(APPEND EXCLUDED_PUBLIC_HEADERS
+ "boost/hana/experimental/type_name.hpp")
+ list(APPEND EXCLUDED_UNIT_TESTS "experimental/type_name.cpp")
+endif()
+
+# On Windows, Clang-cl emulates a MSVC bug that causes EBO not to be applied
+# properly. We disable the tests that check for EBO.
+if (MSVC AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
+ list(APPEND EXCLUDED_UNIT_TESTS
+ "detail/ebo.cpp"
+ "issues/github_202.cpp"
+ "pair/empty_storage.cpp"
+ "tuple/empty_member.cpp"
+ )
+endif()
+
+
+##############################################################################
+# Generate tests that include each public header.
+# The headers that were excluded above due to caveats are ignored here.
+##############################################################################
+add_custom_target(test.headers COMMENT "Build all the header-inclusion unit tests.")
+add_dependencies(tests test.headers)
+
+file(GLOB_RECURSE PUBLIC_HEADERS
+ RELATIVE "${Boost.Hana_SOURCE_DIR}/include"
+ "${Boost.Hana_SOURCE_DIR}/include/*.hpp"
+)
+list(REMOVE_ITEM PUBLIC_HEADERS ${PUBLIC_HEADERS_REQUIRING_BOOST})
+
+include(TestHeaders)
+add_header_test(test.headers.standalone EXCLUDE_FROM_ALL
+ HEADERS ${PUBLIC_HEADERS}
+ EXCLUDE ${EXCLUDED_PUBLIC_HEADERS})
+target_link_libraries(test.headers.standalone PRIVATE hana)
+add_dependencies(test.headers test.headers.standalone)
+
+if (Boost_FOUND)
+ add_header_test(test.headers.boost EXCLUDE_FROM_ALL
+ HEADERS ${PUBLIC_HEADERS_REQUIRING_BOOST}
+ EXCLUDE ${EXCLUDED_PUBLIC_HEADERS})
+ target_link_libraries(test.headers.boost PRIVATE hana Boost::boost)
+ add_dependencies(test.headers test.headers.boost)
+endif()
+
+
+##############################################################################
+# Check for ODR violations when linking several translation units
+# (GitHub issue 75)
+##############################################################################
+list(APPEND EXCLUDED_UNIT_TESTS "issues/github_75/*.cpp")
+boost_hana_target_name_for(github_75 "${CMAKE_CURRENT_LIST_DIR}/issues/github_75")
+add_executable(${github_75} EXCLUDE_FROM_ALL "issues/github_75/tu1.cpp" "issues/github_75/tu2.cpp")
+boost_hana_set_test_properties(${github_75})
+add_test(${github_75} "${CMAKE_CURRENT_BINARY_DIR}/${github_75}")
+add_dependencies(tests ${github_75})
+
+
+##############################################################################
+# Add all the remaining unit tests
+##############################################################################
+file(GLOB_RECURSE UNIT_TESTS "*.cpp")
+file(GLOB_RECURSE EXCLUDED_UNIT_TESTS ${EXCLUDED_UNIT_TESTS})
+list(REMOVE_ITEM UNIT_TESTS ${EXCLUDED_UNIT_TESTS})
+
+foreach(_file IN LISTS UNIT_TESTS)
+ boost_hana_target_name_for(_target "${_file}")
+ add_executable(${_target} EXCLUDE_FROM_ALL "${_file}")
+ boost_hana_set_test_properties(${_target})
+ if (_file IN_LIST TESTS_REQUIRING_BOOST)
+ target_link_libraries(${_target} PRIVATE Boost::boost)
+ endif()
+ target_include_directories(${_target} PRIVATE _include)
+ add_test(${_target} "${CMAKE_CURRENT_BINARY_DIR}/${_target}")
+ add_dependencies(tests ${_target})
+endforeach()
+
+
+##############################################################################
+# Add the deployment test, which checks that we can indeed install `hana` and
+# then use the provided `HanaConfig.cmake` config file to use `hana` from an
+# external project.
+##############################################################################
+include(ExternalProject)
+set(HANA_FAKE_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/deploy/fakeroot")
+ExternalProject_Add(test.deploy.fakeroot
+ SOURCE_DIR "${PROJECT_SOURCE_DIR}"
+ EXCLUDE_FROM_ALL TRUE
+ BUILD_ALWAYS TRUE
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${HANA_FAKE_INSTALL_DIR}
+ -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
+ -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+ TEST_COMMAND "" # Disable test step
+ UPDATE_COMMAND "" # Disable source work-tree update
+)
+
+add_custom_target(test.deploy
+ DEPENDS test.deploy.fakeroot
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/deploy/build"
+ COMMAND ${CMAKE_COMMAND} -E chdir "${CMAKE_CURRENT_BINARY_DIR}/deploy/build"
+ ${CMAKE_COMMAND} "${CMAKE_CURRENT_SOURCE_DIR}/deploy"
+ -DCMAKE_CXX_COMPILER="${CMAKE_CXX_COMPILER}"
+ -DCMAKE_PREFIX_PATH="${HANA_FAKE_INSTALL_DIR}"
+ -DCMAKE_GENERATOR=${CMAKE_GENERATOR}
+ -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}"
+ COMMAND ${CMAKE_COMMAND} --build "${CMAKE_CURRENT_BINARY_DIR}/deploy/build"
+ USES_TERMINAL
+)
+add_dependencies(hana_check test.deploy)
diff --git a/src/boost/libs/hana/test/Jamfile.v2 b/src/boost/libs/hana/test/Jamfile.v2
new file mode 100644
index 00000000..cc66d79b
--- /dev/null
+++ b/src/boost/libs/hana/test/Jamfile.v2
@@ -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)
+
+import config : requires ;
+import testing ;
+import regex ;
+
+project boost/hana :
+ requirements
+ <include>./_include
+ <include>../include
+;
+
+rule hana-all-tests {
+ local toolset =
+ <toolset>clang:<cxxflags>"-std=c++1y -pedantic -Wall -Wextra"
+ <toolset>darwin:<cxxflags>"-std=c++1y -pedantic -Wall -Wextra"
+ [ requires
+ cxx14_constexpr
+ cxx14_decltype_auto
+ cxx14_generic_lambdas
+ cxx14_return_type_deduction
+ ]
+ ;
+
+ local result ;
+
+ result += [ run issues/github_75/tu1.cpp issues/github_75/tu2.cpp : : : $(toolset) : test.issues.github_75 ] ;
+
+ local sources = [ glob-tree *.cpp : *github_75* ] ;
+ for local source in $(sources)
+ {
+ local target = [ regex.replace $(source) "\.cpp" "" ] ;
+ target = [ regex.replace $(target) "/" "." ] ;
+ result += [ run $(source) : : : $(toolset) : test.$(target) ] ;
+ }
+
+ return $(result) ;
+}
+
+test-suite hana : [ hana-all-tests ] ;
+
+# Satisfy the Boost library requirements
+test-suite minimal : hana ;
+test-suite full : hana ;
+test-suite extra : hana ;
+
+explicit hana ;
+explicit minimal ;
+explicit extra ;
diff --git a/src/boost/libs/hana/test/_include/auto/README.md b/src/boost/libs/hana/test/_include/auto/README.md
new file mode 100644
index 00000000..082906c2
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/README.md
@@ -0,0 +1,44 @@
+The headers in this directory provide facilities for automatic unit testing.
+Basically, each header defines unit tests for an algorithm or a set of related
+algorithms. To get the tests for these algorithms, simply include the header
+at global scope. However, before including the header, you must define the
+following macros:
+
+ `MAKE_TUPLE(...)`
+ Must expand to a sequence holding `__VA_ARGS__`. A valid definition
+ would be `hana::make_tuple(__VA_ARGS__)`.
+
+ `TUPLE_TYPE(...)`
+ Must expand to the type of a sequence holding objects of type `__VA_ARGS__`.
+ A valid definition would be `hana::tuple<__VA_ARGS__>`.
+
+ `TUPLE_TAG`
+ Must expand to the tag of the sequence. A valid definition would
+ be `hana::tuple_tag`.
+
+
+The following macros may or may not be defined:
+
+ `MAKE_TUPLE_NO_CONSTEXPR`
+ Must be defined if the `MAKE_TUPLE` macro can't be used inside a
+ constant expression. Otherwise, `MAKE_TUPLE` is assumed to be able
+ to construct a `constexpr` container.
+
+The following directories contain automatic unit tests, and the following is
+sufficient when adding a new automatic unit test (in a file `${FILE}`):
+
+```sh
+DIRECTORIES=$(find test -type d -name auto | grep -v test/_include/auto)
+for d in ${DIRECTORIES}; do
+ cat > ${d}/${FILE}.cpp <<EOF
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include "_specs.hpp"
+#include <auto/${FILE}.hpp>
+
+int main() { }
+EOF
+done
+```
diff --git a/src/boost/libs/hana/test/_include/auto/all_of.hpp b/src/boost/libs/hana/test/_include/auto/all_of.hpp
new file mode 100644
index 00000000..b1bdc112
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/all_of.hpp
@@ -0,0 +1,120 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_ALL_OF_HPP
+#define BOOST_HANA_TEST_AUTO_ALL_OF_HPP
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_all_of{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(
+ MAKE_TUPLE(),
+ [](auto) { return hana::false_c; }
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ [](auto) { return hana::true_c; }
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ [](auto) { return hana::false_c; }
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ hana::equal.to(ct_eq<999>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ [](auto) { return hana::true_c; }
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ [](auto) { return hana::false_c; }
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ hana::equal.to(ct_eq<0>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ [](auto) { return hana::true_c; }
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ [](auto) { return hana::false_c; }
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<999>{}, ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<999>{}, ct_eq<0>{}, ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<999>{}, ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}, ct_eq<999>{}),
+ hana::equal.to(ct_eq<0>{})
+ )));
+
+ // Make sure `all_of` short-circuits with runtime predicates
+ // See http://stackoverflow.com/q/42012512/627587
+ {
+ {
+ int counter = 0;
+ auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{});
+ hana::all_of(tuple, [&](auto) { ++counter; return false; });
+ BOOST_HANA_RUNTIME_CHECK(counter == 1);
+ }
+ {
+ int counter = 0;
+ auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<999>{}, ct_eq<0>{});
+ hana::all_of(tuple, [&](auto x) -> bool {
+ ++counter;
+ return hana::equal(x, ct_eq<0>{});
+ });
+ BOOST_HANA_RUNTIME_CHECK(counter == 2);
+ }
+ }
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_ALL_OF_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/any_of.hpp b/src/boost/libs/hana/test/_include/auto/any_of.hpp
new file mode 100644
index 00000000..400b5a3b
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/any_of.hpp
@@ -0,0 +1,173 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_ANY_OF_HPP
+#define BOOST_HANA_TEST_AUTO_ANY_OF_HPP
+
+#include <boost/hana/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_any_of{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(),
+ [](auto) { return hana::true_c; }
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ [](auto) { return hana::true_c; }
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ [](auto) { return hana::false_c; }
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ hana::equal.to(ct_eq<999>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ [](auto) { return hana::false_c; }
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ [](auto) { return hana::true_c; }
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ hana::equal.to(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ hana::equal.to(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ hana::equal.to(ct_eq<999>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ [](auto) { return hana::false_c; }
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ [](auto) { return hana::true_c; }
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::equal.to(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::equal.to(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::equal.to(ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::equal.to(ct_eq<999>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ [](auto) { return hana::false_c; }
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ [](auto) { return hana::true_c; }
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::equal.to(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::equal.to(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::equal.to(ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::equal.to(ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::equal.to(ct_eq<999>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ [](auto) { return hana::false_c; }
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ [](auto) { return hana::true_c; }
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<4>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<999>{})
+ )));
+
+ // Make sure `any_of` short-circuits with runtime predicates
+ // See http://stackoverflow.com/q/42012512/627587
+ {
+ {
+ int counter = 0;
+ auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{});
+ hana::any_of(tuple, [&](auto) { ++counter; return true; });
+ BOOST_HANA_RUNTIME_CHECK(counter == 1);
+ }
+ {
+ int counter = 0;
+ auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ hana::any_of(tuple, [&](auto x) -> bool {
+ ++counter;
+ return hana::equal(x, ct_eq<1>{});
+ });
+ BOOST_HANA_RUNTIME_CHECK(counter == 2);
+ }
+ }
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_ANY_OF_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/ap.hpp b/src/boost/libs/hana/test/_include/auto/ap.hpp
new file mode 100644
index 00000000..7fe0fc5b
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/ap.hpp
@@ -0,0 +1,76 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_AP_HPP
+#define BOOST_HANA_TEST_AUTO_AP_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/ap.hpp>
+#include <boost/hana/equal.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_ap{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ hana::test::_injection<0> f{};
+ hana::test::_injection<1> g{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(f), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(f), MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(f), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(f), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(f, g), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(f, g), MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}), g(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(f, g), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), g(ct_eq<0>{}), g(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(MAKE_TUPLE(f, g), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}),
+ g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}))
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_AP_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/at.hpp b/src/boost/libs/hana/test/_include/auto/at.hpp
new file mode 100644
index 00000000..66574a36
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/at.hpp
@@ -0,0 +1,91 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_AT_HPP
+#define BOOST_HANA_TEST_AUTO_AT_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+#include <support/tracked.hpp>
+
+
+namespace _test_at_detail { template <int> struct invalid { }; }
+
+
+TestCase test_at{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+ using _test_at_detail::invalid;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(MAKE_TUPLE(ct_eq<0>{}, invalid<1>{}), hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(MAKE_TUPLE(invalid<0>{}, ct_eq<1>{}), hana::size_c<1>),
+ ct_eq<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(MAKE_TUPLE(invalid<0>{}, ct_eq<1>{}, invalid<2>{}), hana::size_c<1>),
+ ct_eq<1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(MAKE_TUPLE(invalid<0>{}, invalid<1>{}, ct_eq<2>{}), hana::size_c<2>),
+ ct_eq<2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(MAKE_TUPLE(invalid<0>{}, invalid<1>{}, ct_eq<2>{}, invalid<3>{}), hana::size_c<2>),
+ ct_eq<2>{}
+ ));
+
+#ifndef MAKE_TUPLE_NO_CONSTEXPR
+ static_assert(hana::equal(
+ hana::at(MAKE_TUPLE(1), hana::size_c<0>),
+ 1
+ ), "");
+ static_assert(hana::equal(
+ hana::at(MAKE_TUPLE(1, '2'), hana::size_c<0>),
+ 1
+ ), "");
+ static_assert(hana::equal(
+ hana::at(MAKE_TUPLE(1, '2', 3.3), hana::size_c<0>),
+ 1
+ ), "");
+
+ static_assert(hana::equal(
+ hana::at(MAKE_TUPLE(1, '2'), hana::size_c<1>),
+ '2'
+ ), "");
+ static_assert(hana::equal(
+ hana::at(MAKE_TUPLE(1, '2', 3.3), hana::size_c<1>),
+ '2'
+ ), "");
+
+ static_assert(hana::equal(
+ hana::at(MAKE_TUPLE(1, '2', 3.3), hana::size_c<2>),
+ 3.3
+ ), "");
+#endif
+
+ // make sure we can use non-pods on both sides
+ {
+ // store the result to make sure `at` is executed.
+ auto result = hana::at(MAKE_TUPLE(Tracked{0}, ct_eq<1>{}, Tracked{1}), hana::size_c<1>);;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(result, ct_eq<1>{}));
+ }
+
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_AT_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/cartesian_product.hpp b/src/boost/libs/hana/test/_include/auto/cartesian_product.hpp
new file mode 100644
index 00000000..8aecf364
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/cartesian_product.hpp
@@ -0,0 +1,234 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_CARTESIAN_PRODUCT_HPP
+#define BOOST_HANA_TEST_AUTO_CARTESIAN_PRODUCT_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/cartesian_product.hpp>
+#include <boost/hana/equal.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_cartesian_product{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ // 0 lists
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+
+ // 1 list
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE()
+ )),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{})
+ )
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{})
+ )
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<2>{})
+ )
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<3>{})
+ )
+ ));
+
+ // 2 lists
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(),
+ MAKE_TUPLE()
+ )),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}),
+ MAKE_TUPLE()
+ )),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}),
+ MAKE_TUPLE(ct_eq<10>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{})
+ )
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<01>{}),
+ MAKE_TUPLE(ct_eq<10>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}),
+ MAKE_TUPLE(ct_eq<01>{}, ct_eq<10>{})
+ )
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}),
+ MAKE_TUPLE(ct_eq<10>{}, ct_eq<11>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}),
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<11>{})
+ )
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<01>{}),
+ MAKE_TUPLE(ct_eq<10>{}, ct_eq<11>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}),
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<11>{}),
+ MAKE_TUPLE(ct_eq<01>{}, ct_eq<10>{}),
+ MAKE_TUPLE(ct_eq<01>{}, ct_eq<11>{})
+ )
+ ));
+
+ // misc
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}),
+ MAKE_TUPLE(ct_eq<10>{}),
+ MAKE_TUPLE(ct_eq<20>{}),
+ MAKE_TUPLE(ct_eq<30>{}, ct_eq<31>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<20>{}, ct_eq<30>{}),
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<20>{}, ct_eq<31>{})
+ )
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}),
+ MAKE_TUPLE(ct_eq<10>{}),
+ MAKE_TUPLE(ct_eq<20>{}, ct_eq<21>{}),
+ MAKE_TUPLE(ct_eq<30>{}, ct_eq<31>{})
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<20>{}, ct_eq<30>{}),
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<20>{}, ct_eq<31>{}),
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<21>{}, ct_eq<30>{}),
+ MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<21>{}, ct_eq<31>{})
+ )
+ ));
+
+
+ // cartesian_product in a constexpr context
+#ifndef MAKE_TUPLE_NO_CONSTEXPR
+ static_assert(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(1),
+ MAKE_TUPLE('a', 'b')
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(1, 'a'),
+ MAKE_TUPLE(1, 'b')
+ )
+ ), "");
+
+ static_assert(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(1, 2),
+ MAKE_TUPLE('a')
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(1, 'a'),
+ MAKE_TUPLE(2, 'a')
+ )
+ ), "");
+
+ static_assert(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(1, 2),
+ MAKE_TUPLE('a', 'b')
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(1, 'a'),
+ MAKE_TUPLE(1, 'b'),
+ MAKE_TUPLE(2, 'a'),
+ MAKE_TUPLE(2, 'b')
+ )
+ ), "");
+
+ static_assert(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(1),
+ MAKE_TUPLE('a'),
+ MAKE_TUPLE(1.f),
+ MAKE_TUPLE(1l, 2l)
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(1, 'a', 1.f, 1l),
+ MAKE_TUPLE(1, 'a', 1.f, 2l)
+ )
+ ), "");
+
+ static_assert(hana::equal(
+ hana::cartesian_product(MAKE_TUPLE(
+ MAKE_TUPLE(1),
+ MAKE_TUPLE('a'),
+ MAKE_TUPLE(1.f),
+ MAKE_TUPLE(1l, 2l),
+ MAKE_TUPLE(nullptr)
+ )),
+ MAKE_TUPLE(
+ MAKE_TUPLE(1, 'a', 1.f, 1l, nullptr),
+ MAKE_TUPLE(1, 'a', 1.f, 2l, nullptr)
+ )
+ ), "");
+#endif
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_CARTESIAN_PRODUCT_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/drop_back.hpp b/src/boost/libs/hana/test/_include/auto/drop_back.hpp
new file mode 100644
index 00000000..e3ea42e0
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/drop_back.hpp
@@ -0,0 +1,99 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_DROP_BACK_HPP
+#define BOOST_HANA_TEST_AUTO_DROP_BACK_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_back.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_drop_back{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(), hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(), hana::size_c<1>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(), hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<3>),
+ MAKE_TUPLE()
+ ));
+
+ // make sure hana::drop_back(xs) == hana::drop_back(xs, hana::size_c<1>)
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE()),
+ hana::drop_back(MAKE_TUPLE(), hana::size_c<1>)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{})),
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{})),
+ hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}), hana::size_c<1>)
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_DROP_BACK_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/drop_front.hpp b/src/boost/libs/hana/test/_include/auto/drop_front.hpp
new file mode 100644
index 00000000..05988ace
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/drop_front.hpp
@@ -0,0 +1,160 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_DROP_FRONT_HPP
+#define BOOST_HANA_TEST_AUTO_DROP_FRONT_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_drop_front{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(), hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(), hana::size_c<1>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(), hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<3>),
+ MAKE_TUPLE()
+ ));
+
+ // make sure hana::drop_front(xs) == hana::drop_front(xs, size_c<1>)
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE()),
+ hana::drop_front(MAKE_TUPLE(), hana::size_c<1>)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{})),
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{})),
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}), hana::size_c<1>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+}};
+
+TestCase test_drop_front_exactly{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(MAKE_TUPLE(), hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{},
+ ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}), hana::size_c<4>),
+ MAKE_TUPLE(ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{})
+ ));
+
+ // make sure drop_front_exactly(xs) == drop_front_exactly(xs, size_c<1>)
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{})),
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{})),
+ hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}), hana::size_c<1>)
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_DROP_FRONT_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/drop_while.hpp b/src/boost/libs/hana/test/_include/auto/drop_while.hpp
new file mode 100644
index 00000000..054d79be
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/drop_while.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_DROP_WHILE_HPP
+#define BOOST_HANA_TEST_AUTO_DROP_WHILE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/drop_while.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_drop_while{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(), hana::id),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(hana::true_c), hana::id),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(hana::false_c), hana::id),
+ MAKE_TUPLE(hana::false_c)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(hana::true_c, hana::true_c), hana::id),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(hana::true_c, hana::false_c), hana::id),
+ MAKE_TUPLE(hana::false_c)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(hana::false_c, hana::true_c), hana::id),
+ MAKE_TUPLE(hana::false_c, hana::true_c)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(hana::false_c, hana::false_c), hana::id),
+ MAKE_TUPLE(hana::false_c, hana::false_c)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::not_equal.to(ct_eq<99>{})),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::not_equal.to(ct_eq<1>{})),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::not_equal.to(ct_eq<3>{})),
+ MAKE_TUPLE(ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_while(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::not_equal.to(ct_eq<0>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_DROP_WHILE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/for_each.hpp b/src/boost/libs/hana/test/_include/auto/for_each.hpp
new file mode 100644
index 00000000..4e36e985
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/for_each.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_FOR_EACH_HPP
+#define BOOST_HANA_TEST_AUTO_FOR_EACH_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/for_each.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+#include <vector>
+
+
+TestCase test_for_each{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ // Make sure the function is applied in left-to-right order.
+ {
+ auto check = [](auto ...xs) {
+ std::vector<int> seen{};
+ hana::for_each(MAKE_TUPLE(xs...), [&](int x) {
+ seen.push_back(x);
+ });
+ BOOST_HANA_RUNTIME_CHECK(seen == std::vector<int>{xs...});
+ };
+
+ check();
+ check(0);
+ check(0, 1);
+ check(0, 1, 2);
+ check(0, 1, 2, 3);
+ check(0, 1, 2, 3, 4);
+ }
+
+ // Make sure the function is never called when the sequence is empty.
+ {
+ struct undefined { };
+ hana::for_each(MAKE_TUPLE(), undefined{});
+ }
+
+ // Make sure it works with heterogeneous sequences.
+ {
+ hana::for_each(MAKE_TUPLE(ct_eq<0>{}), [](auto) { });
+ hana::for_each(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), [](auto) { });
+ hana::for_each(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), [](auto) { });
+ hana::for_each(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), [](auto) { });
+ }
+
+ // Make sure for_each is constexpr when used with a constexpr function
+ // and constexpr arguments. This used not to be the case.
+#ifndef MAKE_TUPLE_NO_CONSTEXPR
+ {
+ struct f { constexpr void operator()(int) const { } };
+ constexpr int i = (hana::for_each(MAKE_TUPLE(1, 2, 3), f{}), 0);
+ (void)i;
+ }
+#endif
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_FOR_EACH_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/group.hpp b/src/boost/libs/hana/test/_include/auto/group.hpp
new file mode 100644
index 00000000..1802ebd3
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/group.hpp
@@ -0,0 +1,150 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_GROUP_HPP
+#define BOOST_HANA_TEST_AUTO_GROUP_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/group.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+#include <support/equivalence_class.hpp>
+
+
+TestCase test_group{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ struct undefined { };
+
+ // Test without a custom predicate
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<0>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}, ct_eq<0>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<1>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<2>{}, ct_eq<2>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<2>{}, ct_eq<2>{}))
+ ));
+ }
+
+ // Test with a custom predicate
+ {
+ auto a = [](auto z) { return ::equivalence_class(ct_eq<999>{}, z); };
+ auto b = [](auto z) { return ::equivalence_class(ct_eq<888>{}, z); };
+
+ auto pred = [](auto x, auto y) {
+ return hana::equal(x.unwrap, y.unwrap);
+ };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(), undefined{}),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(a(ct_eq<0>{})), pred),
+ MAKE_TUPLE(
+ MAKE_TUPLE(a(ct_eq<0>{})))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})), pred),
+ MAKE_TUPLE(
+ MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{})), pred),
+ MAKE_TUPLE(
+ MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})),
+ MAKE_TUPLE(a(ct_eq<1>{})))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{}), b(ct_eq<1>{})), pred),
+ MAKE_TUPLE(
+ MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})),
+ MAKE_TUPLE(a(ct_eq<1>{}), b(ct_eq<1>{})))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{}), b(ct_eq<1>{}), b(ct_eq<0>{})), pred),
+ MAKE_TUPLE(
+ MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})),
+ MAKE_TUPLE(a(ct_eq<1>{}), b(ct_eq<1>{})),
+ MAKE_TUPLE(b(ct_eq<0>{})))
+ ));
+
+ // Test group.by syntactic sugar
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group.by(pred, MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{}), b(ct_eq<1>{}), b(ct_eq<0>{}))),
+ MAKE_TUPLE(
+ MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})),
+ MAKE_TUPLE(a(ct_eq<1>{}), b(ct_eq<1>{})),
+ MAKE_TUPLE(b(ct_eq<0>{})))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::group.by(pred)(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{}), b(ct_eq<1>{}), b(ct_eq<0>{}))),
+ MAKE_TUPLE(
+ MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})),
+ MAKE_TUPLE(a(ct_eq<1>{}), b(ct_eq<1>{})),
+ MAKE_TUPLE(b(ct_eq<0>{})))
+ ));
+ }
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_GROUP_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/index_if.hpp b/src/boost/libs/hana/test/_include/auto/index_if.hpp
new file mode 100644
index 00000000..af7c86bb
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/index_if.hpp
@@ -0,0 +1,81 @@
+// 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)
+
+#ifndef BOOST_HANA_TEST_AUTO_INDEX_IF_HPP
+#define BOOST_HANA_TEST_AUTO_INDEX_IF_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/index_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+#include <support/tracked.hpp>
+
+
+namespace _test_index_if_detail { template <int> struct invalid { }; }
+
+
+TestCase test_index_if{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+ using _test_index_if_detail::invalid;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::index_if(MAKE_TUPLE(), hana::equal.to(ct_eq<0>{})),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::index_if(MAKE_TUPLE(ct_eq<0>{}), hana::equal.to(ct_eq<0>{})),
+ hana::just(hana::size_c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::index_if(MAKE_TUPLE(ct_eq<0>{}), hana::equal.to(ct_eq<42>{})),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::index_if(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<0>{})),
+ hana::just(hana::size_c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::index_if(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<1>{})),
+ hana::just(hana::size_c<1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::index_if(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<2>{})),
+ hana::just(hana::size_c<2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::index_if(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<42>{})),
+ hana::nothing
+ ));
+
+#ifndef MAKE_TUPLE_NO_CONSTEXPR
+ auto type_equal = [](auto type) { return [=](auto&& value) {
+ return hana::equal(hana::typeid_(value), type);
+ };};
+
+ static_assert(decltype(hana::equal(
+ hana::index_if(MAKE_TUPLE(1, '2', 3.3), type_equal(hana::type_c<int>)),
+ hana::just(hana::size_c<0>)
+ )){}, "");
+ static_assert(decltype(hana::equal(
+ hana::index_if(MAKE_TUPLE(1, '2', 3.3), type_equal(hana::type_c<char>)),
+ hana::just(hana::size_c<1>)
+ )){}, "");
+ static_assert(decltype(hana::equal(
+ hana::index_if(MAKE_TUPLE(1, '2', 3.3), type_equal(hana::type_c<double>)),
+ hana::just(hana::size_c<2>)
+ )){}, "");
+ static_assert(decltype(hana::equal(
+ hana::index_if(MAKE_TUPLE(1, '2', 3.3), type_equal(hana::type_c<invalid<42>>)),
+ hana::nothing
+ )){}, "");
+#endif
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_INDEX_IF_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/insert.hpp b/src/boost/libs/hana/test/_include/auto/insert.hpp
new file mode 100644
index 00000000..c9715452
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/insert.hpp
@@ -0,0 +1,84 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_INSERT_HPP
+#define BOOST_HANA_TEST_AUTO_INSERT_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/insert.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_insert{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ auto z = ct_eq<999>{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>, z),
+ MAKE_TUPLE(z, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>, z),
+ MAKE_TUPLE(ct_eq<0>{}, z)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>, z),
+ MAKE_TUPLE(z, ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>, z),
+ MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>, z),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, z)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<0>, z),
+ MAKE_TUPLE(z, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<1>, z),
+ MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<2>, z),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, z, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<3>, z),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, z)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<0>, z),
+ MAKE_TUPLE(z, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<1>, z),
+ MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<2>, z),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, z, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<3>, z),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, z, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<4>, z),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, z)
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_INSERT_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/insert_range.hpp b/src/boost/libs/hana/test/_include/auto/insert_range.hpp
new file mode 100644
index 00000000..ac929d7e
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/insert_range.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_INSERT_RANGE_HPP
+#define BOOST_HANA_TEST_AUTO_INSERT_RANGE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/insert_range.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+
+
+TestCase test_insert_range{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ auto foldable = ::seq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}),
+ hana::size_c<0>,
+ foldable()),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}),
+ hana::size_c<0>,
+ foldable(ct_eq<-1>{})),
+ MAKE_TUPLE(ct_eq<-1>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}),
+ hana::size_c<0>,
+ foldable(ct_eq<-1>{}, ct_eq<-2>{})),
+ MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}),
+ hana::size_c<0>,
+ foldable(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{})),
+ MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<0>,
+ foldable()),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<0>,
+ foldable(ct_eq<-1>{})),
+ MAKE_TUPLE(ct_eq<-1>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<0>,
+ foldable(ct_eq<-1>{}, ct_eq<-2>{})),
+ MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<1>,
+ foldable()),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<1>,
+ foldable(ct_eq<-1>{})),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<-1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<1>,
+ foldable(ct_eq<-1>{}, ct_eq<-2>{})),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert_range(
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::size_c<2>,
+ foldable(ct_eq<-1>{}, ct_eq<-2>{})),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<3>{}, ct_eq<4>{})
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_INSERT_RANGE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/intersperse.hpp b/src/boost/libs/hana/test/_include/auto/intersperse.hpp
new file mode 100644
index 00000000..83e7e814
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/intersperse.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_INTERSPERSE_HPP
+#define BOOST_HANA_TEST_AUTO_INTERSPERSE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/intersperse.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_intersperse{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ struct undefined { };
+
+ auto z = ct_eq<999>{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersperse(MAKE_TUPLE(), undefined{}),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersperse(MAKE_TUPLE(ct_eq<0>{}), undefined{}),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), z),
+ MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), z),
+ MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, z, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), z),
+ MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, z, ct_eq<2>{}, z, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), z),
+ MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, z, ct_eq<2>{}, z, ct_eq<3>{}, z, ct_eq<4>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}), z),
+ MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, z, ct_eq<2>{}, z, ct_eq<3>{}, z, ct_eq<4>{}, z, ct_eq<5>{})
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_INTERSPERSE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/is_empty.hpp b/src/boost/libs/hana/test/_include/auto/is_empty.hpp
new file mode 100644
index 00000000..99ae879d
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/is_empty.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_IS_EMPTY_HPP
+#define BOOST_HANA_TEST_AUTO_IS_EMPTY_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+
+#include "test_case.hpp"
+
+
+namespace _test_is_empty_detail { template <int i> struct undefined { }; }
+
+TestCase test_is_empty{[]{
+ namespace hana = boost::hana;
+ using _test_is_empty_detail::undefined;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ MAKE_TUPLE(undefined<0>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ MAKE_TUPLE(undefined<0>{}, undefined<1>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ MAKE_TUPLE(undefined<0>{}, undefined<1>{}, undefined<2>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ MAKE_TUPLE(undefined<0>{}, undefined<1>{}, undefined<2>{}, undefined<3>{})
+ )));
+
+ // Check with a runtime value
+ {
+ int i = 3; // <- runtime value
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(MAKE_TUPLE(i))));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(MAKE_TUPLE(i, i))));
+ }
+
+#ifndef MAKE_TUPLE_NO_CONSTEXPR
+ static_assert(hana::is_empty(MAKE_TUPLE()), "");
+ static_assert(hana::not_(hana::is_empty(MAKE_TUPLE(undefined<0>{}))), "");
+ static_assert(hana::not_(hana::is_empty(MAKE_TUPLE(undefined<0>{}, undefined<1>{}))), "");
+#endif
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_IS_EMPTY_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/length.hpp b/src/boost/libs/hana/test/_include/auto/length.hpp
new file mode 100644
index 00000000..25f75dc4
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/length.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_LENGTH_HPP
+#define BOOST_HANA_TEST_AUTO_LENGTH_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+
+#include "test_case.hpp"
+
+
+namespace _test_length_detail { template <int> struct undefined { }; }
+
+TestCase test_length{[]{
+ namespace hana = boost::hana;
+ using _test_length_detail::undefined;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(MAKE_TUPLE()),
+ hana::size_c<0>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(MAKE_TUPLE(undefined<1>{})),
+ hana::size_c<1>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(MAKE_TUPLE(undefined<1>{}, undefined<2>{})),
+ hana::size_c<2>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(MAKE_TUPLE(undefined<1>{}, undefined<2>{}, undefined<3>{})),
+ hana::size_c<3>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(MAKE_TUPLE(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, undefined<5>{}, undefined<6>{})),
+ hana::size_c<6>
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_LENGTH_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/lexicographical_compare.hpp b/src/boost/libs/hana/test/_include/auto/lexicographical_compare.hpp
new file mode 100644
index 00000000..83870d56
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/lexicographical_compare.hpp
@@ -0,0 +1,109 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_LEXICOGRAPHICAL_COMPARE_HPP
+#define BOOST_HANA_TEST_AUTO_LEXICOGRAPHICAL_COMPARE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/lexicographical_compare.hpp>
+#include <boost/hana/not.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_lexicographical_compare{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_ord;
+
+ struct undefined { };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(),
+ MAKE_TUPLE()
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare(
+ MAKE_TUPLE(),
+ MAKE_TUPLE(undefined{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(undefined{}),
+ MAKE_TUPLE()
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}),
+ MAKE_TUPLE(ct_ord<0>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}),
+ MAKE_TUPLE(ct_ord<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<1>{}),
+ MAKE_TUPLE(ct_ord<0>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, undefined{}),
+ MAKE_TUPLE(ct_ord<0>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}),
+ MAKE_TUPLE(ct_ord<0>{}, undefined{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<0>{}),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<0>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{}),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<3>{}, undefined{}),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{}),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<3>{}, undefined{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{}),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare(
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<3>{}),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{})
+ )));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_LEXICOGRAPHICAL_COMPARE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/make.hpp b/src/boost/libs/hana/test/_include/auto/make.hpp
new file mode 100644
index 00000000..83536edf
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/make.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_MAKE_HPP
+#define BOOST_HANA_TEST_AUTO_MAKE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/equal.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_make{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ MAKE_TUPLE(),
+ hana::make<TUPLE_TAG>()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ MAKE_TUPLE(ct_eq<0>{}),
+ hana::make<TUPLE_TAG>(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make<TUPLE_TAG>(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make<TUPLE_TAG>(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_MAKE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/none_of.hpp b/src/boost/libs/hana/test/_include/auto/none_of.hpp
new file mode 100644
index 00000000..7e1dff2d
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/none_of.hpp
@@ -0,0 +1,90 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_NONE_OF_HPP
+#define BOOST_HANA_TEST_AUTO_NONE_OF_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/none_of.hpp>
+#include <boost/hana/not.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_none_of{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::none_of(
+ MAKE_TUPLE(),
+ [](auto) { return hana::false_c; }
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ [](auto) { return hana::true_c; }
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ [](auto) { return hana::false_c; }
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ hana::equal.to(ct_eq<0>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}),
+ hana::equal.to(ct_eq<999>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<0>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<1>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<2>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<3>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<4>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::none_of(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::equal.to(ct_eq<999>{})
+ ));
+
+ // Make sure `none_of` short-circuits with runtime predicates
+ // See http://stackoverflow.com/q/42012512/627587
+ {
+ {
+ int counter = 0;
+ auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{});
+ hana::none_of(tuple, [&](auto) { ++counter; return true; });
+ BOOST_HANA_RUNTIME_CHECK(counter == 1);
+ }
+ {
+ int counter = 0;
+ auto tuple = MAKE_TUPLE(ct_eq<999>{}, ct_eq<0>{}, ct_eq<999>{});
+ hana::none_of(tuple, [&](auto x) -> bool {
+ ++counter;
+ return hana::equal(x, ct_eq<0>{});
+ });
+ BOOST_HANA_RUNTIME_CHECK(counter == 2);
+ }
+ }
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_NONE_OF_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/partition.hpp b/src/boost/libs/hana/test/_include/auto/partition.hpp
new file mode 100644
index 00000000..d1fa7212
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/partition.hpp
@@ -0,0 +1,74 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_PARTITION_HPP
+#define BOOST_HANA_TEST_AUTO_PARTITION_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/partition.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+
+
+TestCase test_partition{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ struct undefined { };
+
+ auto pair = ::minimal_product;
+ auto pred = hana::in ^ MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{}, ct_eq<-4>{}, ct_eq<-5>{});
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partition(MAKE_TUPLE(), undefined{}),
+ pair(MAKE_TUPLE(), MAKE_TUPLE())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partition(MAKE_TUPLE(ct_eq<0>{}), pred),
+ pair(MAKE_TUPLE(),
+ MAKE_TUPLE(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partition(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), pred),
+ pair(MAKE_TUPLE(),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partition(MAKE_TUPLE(ct_eq<-1>{}), pred),
+ pair(MAKE_TUPLE(ct_eq<-1>{}),
+ MAKE_TUPLE())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partition(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{}), pred),
+ pair(MAKE_TUPLE(ct_eq<-1>{}),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partition(MAKE_TUPLE(ct_eq<0>{}, ct_eq<-3>{}, ct_eq<2>{}, ct_eq<-5>{}, ct_eq<6>{}), pred),
+ pair(MAKE_TUPLE(ct_eq<-3>{}, ct_eq<-5>{}),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<6>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partition(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<2>{}, ct_eq<-3>{}, ct_eq<0>{}, ct_eq<-3>{}, ct_eq<4>{}), pred),
+ pair(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-3>{}, ct_eq<-3>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<0>{}, ct_eq<4>{}))
+ ));
+
+ // partition.by
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partition.by(pred, MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{})),
+ hana::partition(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{}), pred)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partition.by(pred)(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{})),
+ hana::partition(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{}), pred)
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_PARTITION_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/permutations.hpp b/src/boost/libs/hana/test/_include/auto/permutations.hpp
new file mode 100644
index 00000000..d854103a
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/permutations.hpp
@@ -0,0 +1,87 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_PERMUTATIONS_HPP
+#define BOOST_HANA_TEST_AUTO_PERMUTATIONS_HPP
+
+#include <boost/hana/and.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/is_subset.hpp>
+#include <boost/hana/permutations.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_permutations{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ auto is_permutation = [](auto xs, auto ys) {
+ return hana::and_(hana::is_subset(xs, ys), hana::is_subset(ys, xs));
+ };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::permutations(MAKE_TUPLE()),
+ MAKE_TUPLE(MAKE_TUPLE())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::permutations(MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(is_permutation(
+ hana::permutations(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{})
+ )
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(is_permutation(
+ hana::permutations(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<0>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ )
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(is_permutation(
+ hana::permutations(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})),
+ MAKE_TUPLE(
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<3>{}, ct_eq<1>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}, ct_eq<3>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<0>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<3>{}, ct_eq<0>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<0>{}, ct_eq<3>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<3>{}, ct_eq<0>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<3>{}, ct_eq<1>{}, ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<3>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<3>{}, ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<3>{}, ct_eq<1>{}, ct_eq<0>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<3>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<3>{}, ct_eq<2>{}, ct_eq<0>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ )
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_PERMUTATIONS_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/remove_at.hpp b/src/boost/libs/hana/test/_include/auto/remove_at.hpp
new file mode 100644
index 00000000..296b989e
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/remove_at.hpp
@@ -0,0 +1,130 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_REMOVE_AT_HPP
+#define BOOST_HANA_TEST_AUTO_REMOVE_AT_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/remove_at.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_remove_at{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}),
+ hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::size_c<3>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<4>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::size_c<3>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<4>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::size_c<4>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+ // remove_at_c
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at_c<0>(MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at_c<0>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at_c<1>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at_c<0>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at_c<1>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_at_c<2>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_REMOVE_AT_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/remove_range.hpp b/src/boost/libs/hana/test/_include/auto/remove_range.hpp
new file mode 100644
index 00000000..51bbf913
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/remove_range.hpp
@@ -0,0 +1,114 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_REMOVE_RANGE_HPP
+#define BOOST_HANA_TEST_AUTO_REMOVE_RANGE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/remove_range.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_remove_range{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(), hana::size_c<0>, hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(), hana::size_c<1>, hana::size_c<1>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(), hana::size_c<2>, hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>, hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>, hana::size_c<1>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>, hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>, hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>, hana::size_c<0>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>, hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>, hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>, hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>, hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ hana::size_c<9999>, hana::size_c<9999>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<0>, hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::size_c<1>, hana::size_c<3>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::size_c<0>, hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::size_c<2>, hana::size_c<3>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{},
+ ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}),
+ hana::size_c<4>, hana::size_c<7>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{})
+ ));
+
+ // remove_range_c
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::remove_range_c<4, 7>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{},
+ ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{})
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_REMOVE_RANGE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/reverse.hpp b/src/boost/libs/hana/test/_include/auto/reverse.hpp
new file mode 100644
index 00000000..c0c2000c
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/reverse.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_REVERSE_HPP
+#define BOOST_HANA_TEST_AUTO_REVERSE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/reverse.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_reverse{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+ using hana::test::cx_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::reverse(MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::reverse(MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::reverse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::reverse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+
+
+#ifndef MAKE_TUPLE_NO_CONSTEXPR
+ static_assert(hana::equal(
+ hana::reverse(MAKE_TUPLE(cx_eq<1>{})),
+ MAKE_TUPLE(cx_eq<1>{})
+ ), "");
+ static_assert(hana::equal(
+ hana::reverse(MAKE_TUPLE(cx_eq<1>{}, cx_eq<2>{})),
+ MAKE_TUPLE(cx_eq<2>{}, cx_eq<1>{})
+ ), "");
+ static_assert(hana::equal(
+ hana::reverse(MAKE_TUPLE(cx_eq<1>{}, cx_eq<2>{}, cx_eq<3>{})),
+ MAKE_TUPLE(cx_eq<3>{}, cx_eq<2>{}, cx_eq<1>{})
+ ), "");
+#endif
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_REVERSE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/scans.hpp b/src/boost/libs/hana/test/_include/auto/scans.hpp
new file mode 100644
index 00000000..5c5c0dd6
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/scans.hpp
@@ -0,0 +1,216 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_SCANS_HPP
+#define BOOST_HANA_TEST_AUTO_SCANS_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/scan_left.hpp>
+#include <boost/hana/scan_right.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_scan_left{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ struct undefined { };
+ hana::test::_injection<0> f{};
+
+ // Without initial state
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(), undefined{}),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}), undefined{}),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), f),
+ MAKE_TUPLE(ct_eq<0>{}, f(ct_eq<0>{}, ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), f),
+ MAKE_TUPLE(
+ ct_eq<0>{},
+ f(ct_eq<0>{}, ct_eq<1>{}),
+ f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{})
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), f),
+ MAKE_TUPLE(
+ ct_eq<0>{},
+ f(ct_eq<0>{}, ct_eq<1>{}),
+ f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}),
+ f(f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{})
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), f),
+ MAKE_TUPLE(
+ ct_eq<0>{},
+ f(ct_eq<0>{}, ct_eq<1>{}),
+ f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}),
+ f(f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}),
+ f(f(f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}), ct_eq<4>{})
+ )
+ ));
+
+ // With initial state
+ auto s = ct_eq<999>{};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(), s, undefined{}),
+ MAKE_TUPLE(s)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}), s, f),
+ MAKE_TUPLE(s, f(s, ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), s, f),
+ MAKE_TUPLE(s, f(s, ct_eq<0>{}), f(f(s, ct_eq<0>{}), ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), s, f),
+ MAKE_TUPLE(
+ s,
+ f(s, ct_eq<0>{}),
+ f(f(s, ct_eq<0>{}), ct_eq<1>{}),
+ f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{})
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), s, f),
+ MAKE_TUPLE(
+ s,
+ f(s, ct_eq<0>{}),
+ f(f(s, ct_eq<0>{}), ct_eq<1>{}),
+ f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}),
+ f(f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{})
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), s, f),
+ MAKE_TUPLE(
+ s,
+ f(s, ct_eq<0>{}),
+ f(f(s, ct_eq<0>{}), ct_eq<1>{}),
+ f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}),
+ f(f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}),
+ f(f(f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}), ct_eq<4>{})
+ )
+ ));
+}};
+
+
+TestCase test_scan_right{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ struct undefined { };
+ hana::test::_injection<0> f{};
+
+ // Without initial state
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(), undefined{}),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}), undefined{}),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), f),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, ct_eq<1>{}),
+ ct_eq<1>{}
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), f),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, f(ct_eq<1>{}, ct_eq<2>{})),
+ f(ct_eq<1>{}, ct_eq<2>{}),
+ ct_eq<2>{}
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), f),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, ct_eq<3>{}))),
+ f(ct_eq<1>{}, f(ct_eq<2>{}, ct_eq<3>{})),
+ f(ct_eq<2>{}, ct_eq<3>{}),
+ ct_eq<3>{}
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), f),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, ct_eq<4>{})))),
+ f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, ct_eq<4>{}))),
+ f(ct_eq<2>{}, f(ct_eq<3>{}, ct_eq<4>{})),
+ f(ct_eq<3>{}, ct_eq<4>{}),
+ ct_eq<4>{}
+ )
+ ));
+
+ // With initial state
+ auto s = ct_eq<999>{};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(), s, undefined{}),
+ MAKE_TUPLE(s)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}), s, f),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, s),
+ s
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), s, f),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, f(ct_eq<1>{}, s)),
+ f(ct_eq<1>{}, s),
+ s
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), s, f),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, s))),
+ f(ct_eq<1>{}, f(ct_eq<2>{}, s)),
+ f(ct_eq<2>{}, s),
+ s
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), s, f),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, s)))),
+ f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, s))),
+ f(ct_eq<2>{}, f(ct_eq<3>{}, s)),
+ f(ct_eq<3>{}, s),
+ s
+ )
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), s, f),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, f(ct_eq<4>{}, s))))),
+ f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, f(ct_eq<4>{}, s)))),
+ f(ct_eq<2>{}, f(ct_eq<3>{}, f(ct_eq<4>{}, s))),
+ f(ct_eq<3>{}, f(ct_eq<4>{}, s)),
+ f(ct_eq<4>{}, s),
+ s
+ )
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_SCANS_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/sequence.hpp b/src/boost/libs/hana/test/_include/auto/sequence.hpp
new file mode 100644
index 00000000..280b7355
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/sequence.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_SEQUENCE_HPP
+#define BOOST_HANA_TEST_AUTO_SEQUENCE_HPP
+
+#include <boost/hana/concept/sequence.hpp>
+
+
+static_assert(boost::hana::Sequence<TUPLE_TAG>::value, "");
+
+#endif // !BOOST_HANA_TEST_AUTO_SEQUENCE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/slice.hpp b/src/boost/libs/hana/test/_include/auto/slice.hpp
new file mode 100644
index 00000000..3beb2ef0
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/slice.hpp
@@ -0,0 +1,182 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_SLICE_HPP
+#define BOOST_HANA_TEST_AUTO_SLICE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/slice.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+
+#include <cstddef>
+
+
+TestCase test_slice{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+ constexpr auto foldable = ::seq;
+
+ struct undefined { };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Test with arbitrary indices
+ //////////////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(),
+ foldable()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(undefined{}),
+ foldable()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(undefined{}, undefined{}),
+ foldable()),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}),
+ foldable(hana::size_c<0>)),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, undefined{}),
+ foldable(hana::size_c<0>)),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}),
+ foldable(hana::size_c<1>)),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ foldable(hana::size_c<0>, hana::size_c<1>)),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ foldable(hana::size_c<1>, hana::size_c<0>)),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ foldable(hana::size_c<0>, hana::size_c<0>)),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ foldable(hana::size_c<1>, hana::size_c<1>)),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ foldable(hana::size_c<0>, hana::size_c<1>, hana::size_c<2>)),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ foldable(hana::size_c<0>, hana::size_c<2>, hana::size_c<1>)),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ foldable(hana::size_c<0>, hana::size_c<2>, hana::size_c<1>, hana::size_c<0>)),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ foldable(hana::size_c<0>, hana::size_c<2>, hana::size_c<1>, hana::size_c<0>, hana::size_c<1>)),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ // Try with a tuple_c
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::tuple_c<unsigned, 1, 3, 2>),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<3>{}, ct_eq<2>{})
+ ));
+
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Test with a `range` (check the optimization for contiguous indices)
+ //////////////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(),
+ hana::range_c<std::size_t, 0, 0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(undefined{}),
+ hana::range_c<std::size_t, 0, 0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(undefined{}, undefined{}),
+ hana::range_c<std::size_t, 0, 0>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}),
+ hana::range_c<std::size_t, 0, 1>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, undefined{}),
+ hana::range_c<std::size_t, 0, 1>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}),
+ hana::range_c<std::size_t, 1, 2>),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}, undefined{}),
+ hana::range_c<std::size_t, 1, 2>),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ hana::range_c<std::size_t, 0, 2>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, undefined{}),
+ hana::range_c<std::size_t, 0, 2>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::range_c<std::size_t, 1, 3>),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}, ct_eq<2>{}, undefined{}),
+ hana::range_c<std::size_t, 1, 3>),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_SLICE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/sort.hpp b/src/boost/libs/hana/test/_include/auto/sort.hpp
new file mode 100644
index 00000000..398584fe
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/sort.hpp
@@ -0,0 +1,111 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_SORT_HPP
+#define BOOST_HANA_TEST_AUTO_SORT_HPP
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/sort.hpp>
+#include <boost/hana/transform.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+#include <support/equivalence_class.hpp>
+
+
+TestCase test_sort{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+ using hana::test::ct_ord;
+
+ // Test without a custom predicate
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(ct_ord<0>{})),
+ MAKE_TUPLE(ct_ord<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{})),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(ct_ord<1>{}, ct_ord<0>{})),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(ct_ord<1>{}, ct_ord<0>{}, ct_ord<4>{}, ct_ord<2>{})),
+ MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, ct_ord<4>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(ct_ord<1>{}, ct_ord<0>{}, ct_ord<-4>{}, ct_ord<2>{})),
+ MAKE_TUPLE(ct_ord<-4>{}, ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{})
+ ));
+ }
+
+ // Test with a custom predicate
+ {
+ auto pred = [](auto x, auto y) {
+ return hana::less(x.unwrap, y.unwrap);
+ };
+ auto a = [](auto z) { return ::equivalence_class(ct_eq<999>{}, z); };
+ auto b = [](auto z) { return ::equivalence_class(ct_eq<888>{}, z); };
+
+ auto check = [=](auto ...sorted) {
+ auto perms = hana::transform(
+ hana::permutations(MAKE_TUPLE(a(sorted)...)),
+ hana::sort.by(pred)
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(perms, [=](auto xs) {
+ return hana::equal(xs, MAKE_TUPLE(a(sorted)...));
+ }));
+ };
+
+ check();
+ check(ct_ord<1>{});
+ check(ct_ord<1>{}, ct_ord<2>{});
+ check(ct_ord<1>{}, ct_ord<2>{}, ct_ord<3>{});
+
+ // check stability
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{})), pred),
+ MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{})), pred),
+ MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{})), pred),
+ MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(a(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<1>{}), b(ct_ord<2>{})), pred),
+ MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{})), pred),
+ MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(a(ct_ord<2>{}), b(ct_ord<1>{}), b(ct_ord<2>{}), a(ct_ord<1>{})), pred),
+ MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sort(MAKE_TUPLE(a(ct_ord<1>{}), a(ct_ord<3>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<3>{})), pred),
+ MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), a(ct_ord<3>{}), b(ct_ord<3>{}))
+ ));
+ }
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_SORT_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/span.hpp b/src/boost/libs/hana/test/_include/auto/span.hpp
new file mode 100644
index 00000000..1a15d408
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/span.hpp
@@ -0,0 +1,84 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_SPAN_HPP
+#define BOOST_HANA_TEST_AUTO_SPAN_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/span.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+
+
+TestCase test_span{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ auto z = ct_eq<999>{};
+ auto pair = ::minimal_product;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(), hana::equal.to(z)),
+ pair(MAKE_TUPLE(), MAKE_TUPLE())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(ct_eq<0>{}), hana::equal.to(z)),
+ pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(z), hana::equal.to(z)),
+ pair(MAKE_TUPLE(z), MAKE_TUPLE())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(ct_eq<0>{}, z), hana::equal.to(z)),
+ pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, z))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(z, ct_eq<0>{}), hana::equal.to(z)),
+ pair(MAKE_TUPLE(z), MAKE_TUPLE(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::equal.to(z)),
+ pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(z)),
+ pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(z, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(z)),
+ pair(MAKE_TUPLE(z), MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<2>{}), hana::equal.to(z)),
+ pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(z, z, ct_eq<2>{}), hana::equal.to(z)),
+ pair(MAKE_TUPLE(z, z), MAKE_TUPLE(ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span(MAKE_TUPLE(z, z, z), hana::equal.to(z)),
+ pair(MAKE_TUPLE(z, z, z), MAKE_TUPLE())
+ ));
+
+ // span.by
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span.by(hana::equal.to(z), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ hana::span(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(z))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::span.by(hana::equal.to(z))(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ hana::span(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(z))
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_SPAN_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/take_back.hpp b/src/boost/libs/hana/test/_include/auto/take_back.hpp
new file mode 100644
index 00000000..11a795e0
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/take_back.hpp
@@ -0,0 +1,82 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_TAKE_BACK_HPP
+#define BOOST_HANA_TEST_AUTO_TAKE_BACK_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/take_back.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_take_back{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(), hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(), hana::size_c<1>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(), hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<3>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<3>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<3>),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_back(MAKE_TUPLE(
+ ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{},
+ ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}),
+ hana::size_c<5>),
+ MAKE_TUPLE(ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{})
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_TAKE_BACK_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/take_front.hpp b/src/boost/libs/hana/test/_include/auto/take_front.hpp
new file mode 100644
index 00000000..5e9b6733
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/take_front.hpp
@@ -0,0 +1,77 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_TAKE_FRONT_HPP
+#define BOOST_HANA_TEST_AUTO_TAKE_FRONT_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/take_front.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_take{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(), hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(), hana::size_c<1>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(), hana::size_c<2>),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<3>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<3>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_front(MAKE_TUPLE(
+ ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{},
+ ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}, ct_eq<10>{}, ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}),
+ hana::size_c<10>),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{},
+ ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{})
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_TAKE_FRONT_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/take_while.hpp b/src/boost/libs/hana/test/_include/auto/take_while.hpp
new file mode 100644
index 00000000..72d0b8b1
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/take_while.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_TAKE_WHILE_HPP
+#define BOOST_HANA_TEST_AUTO_TAKE_WHILE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/take_while.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_take_while{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ auto z = ct_eq<999>{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(), hana::not_equal.to(z)),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(ct_eq<1>{}), hana::not_equal.to(z)),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(z), hana::not_equal.to(z)),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), hana::not_equal.to(z)),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(ct_eq<1>{}, z), hana::not_equal.to(z)),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(z, ct_eq<2>{}), hana::not_equal.to(z)),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::not_equal.to(z)),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, z), hana::not_equal.to(z)),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(ct_eq<1>{}, z, ct_eq<3>{}), hana::not_equal.to(z)),
+ MAKE_TUPLE(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::take_while(MAKE_TUPLE(z, ct_eq<2>{}, ct_eq<3>{}), hana::not_equal.to(z)),
+ MAKE_TUPLE()
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_TAKE_WHILE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/test_case.hpp b/src/boost/libs/hana/test/_include/auto/test_case.hpp
new file mode 100644
index 00000000..03de19ac
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/test_case.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_TEST_CASE_HPP
+#define BOOST_HANA_TEST_AUTO_TEST_CASE_HPP
+
+struct TestCase {
+ template <typename F>
+ explicit TestCase(F const& f) { f(); }
+};
+
+#endif // !BOOST_HANA_TEST_AUTO_TEST_CASE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/transform.hpp b/src/boost/libs/hana/test/_include/auto/transform.hpp
new file mode 100644
index 00000000..478d725a
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/transform.hpp
@@ -0,0 +1,74 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_TRANSFORM_HPP
+#define BOOST_HANA_TEST_AUTO_TRANSFORM_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/transform.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+
+
+TestCase test_transform{[] {
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+ struct undefined { };
+ constexpr hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(MAKE_TUPLE(), undefined{}),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(MAKE_TUPLE(ct_eq<1>{}), f),
+ MAKE_TUPLE(f(ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), f),
+ MAKE_TUPLE(f(ct_eq<1>{}), f(ct_eq<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), f),
+ MAKE_TUPLE(f(ct_eq<1>{}), f(ct_eq<2>{}), f(ct_eq<3>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), f),
+ MAKE_TUPLE(f(ct_eq<1>{}), f(ct_eq<2>{}), f(ct_eq<3>{}), f(ct_eq<4>{}))
+ ));
+
+#ifndef MAKE_TUPLE_NO_CONSTEXPR
+ struct incr {
+ constexpr int operator()(int i) const { return i + 1; }
+ };
+
+ static_assert(hana::equal(
+ hana::transform(MAKE_TUPLE(1), incr{}),
+ MAKE_TUPLE(2)
+ ), "");
+
+ static_assert(hana::equal(
+ hana::transform(MAKE_TUPLE(1, 2), incr{}),
+ MAKE_TUPLE(2, 3)
+ ), "");
+
+ static_assert(hana::equal(
+ hana::transform(MAKE_TUPLE(1, 2, 3), incr{}),
+ MAKE_TUPLE(2, 3, 4)
+ ), "");
+
+ static_assert(hana::equal(
+ hana::transform(MAKE_TUPLE(1, 2, 3, 4), incr{}),
+ MAKE_TUPLE(2, 3, 4, 5)
+ ), "");
+#endif
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_TRANSFORM_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/unfolds.hpp b/src/boost/libs/hana/test/_include/auto/unfolds.hpp
new file mode 100644
index 00000000..afa01d3f
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/unfolds.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_UNFOLDS_HPP
+#define BOOST_HANA_TEST_AUTO_UNFOLDS_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/unfold_left.hpp>
+#include <boost/hana/unfold_right.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_unfold_left{[]{
+ namespace hana = boost::hana;
+
+ hana::test::_injection<0> f{};
+ auto stop_at = [=](auto stop) {
+ return [=](auto x) {
+ return hana::if_(hana::equal(stop, x),
+ hana::nothing,
+ hana::just(::minimal_product(x + hana::int_c<1>, f(x)))
+ );
+ };
+ };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<0>)),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<1>)),
+ MAKE_TUPLE(f(hana::int_c<0>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<2>)),
+ MAKE_TUPLE(f(hana::int_c<1>), f(hana::int_c<0>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<3>)),
+ MAKE_TUPLE(f(hana::int_c<2>), f(hana::int_c<1>), f(hana::int_c<0>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<4>)),
+ MAKE_TUPLE(f(hana::int_c<3>), f(hana::int_c<2>), f(hana::int_c<1>), f(hana::int_c<0>))
+ ));
+}};
+
+
+TestCase test_unfold_right{[]{
+ namespace hana = boost::hana;
+
+ hana::test::_injection<0> f{};
+ auto stop_at = [=](auto stop) {
+ return [=](auto x) {
+ return hana::if_(hana::equal(stop, x),
+ hana::nothing,
+ hana::just(::minimal_product(f(x), x + hana::int_c<1>))
+ );
+ };
+ };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<0>)),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<1>)),
+ MAKE_TUPLE(f(hana::int_c<0>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<2>)),
+ MAKE_TUPLE(f(hana::int_c<0>), f(hana::int_c<1>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<3>)),
+ MAKE_TUPLE(f(hana::int_c<0>), f(hana::int_c<1>), f(hana::int_c<2>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<4>)),
+ MAKE_TUPLE(f(hana::int_c<0>), f(hana::int_c<1>), f(hana::int_c<2>), f(hana::int_c<3>))
+ ));
+}};
+
+// Make sure unfolds can be reversed under certain conditions.
+TestCase test_unfold_undo{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ auto z = ct_eq<999>{};
+ auto f = ::minimal_product;
+ auto g = [=](auto k) {
+ return hana::if_(hana::equal(k, z),
+ hana::nothing,
+ hana::just(k)
+ );
+ };
+
+ // Make sure the special conditions are met
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ g(z),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ g(f(ct_eq<0>{}, z)),
+ hana::just(::minimal_product(ct_eq<0>{}, z))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ g(f(z, ct_eq<0>{})),
+ hana::just(::minimal_product(z, ct_eq<0>{}))
+ ));
+
+ // Make sure the reversing works
+ {
+ auto xs = MAKE_TUPLE();
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g),
+ xs
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g),
+ xs
+ ));
+ }
+ {
+ auto xs = MAKE_TUPLE(ct_eq<0>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g),
+ xs
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g),
+ xs
+ ));
+ }
+ {
+ auto xs = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g),
+ xs
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g),
+ xs
+ ));
+ }
+ {
+ auto xs = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g),
+ xs
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g),
+ xs
+ ));
+ }
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_UNFOLDS_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/unique.hpp b/src/boost/libs/hana/test/_include/auto/unique.hpp
new file mode 100644
index 00000000..8ef7076f
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/unique.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_AUTO_UNIQUE_HPP
+#define BOOST_HANA_TEST_AUTO_UNIQUE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/unique.hpp>
+
+#include "test_case.hpp"
+#include <laws/base.hpp>
+#include <support/equivalence_class.hpp>
+
+
+TestCase test_unique{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{})),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{})),
+ MAKE_TUPLE(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<0>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<1>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(
+ ct_eq<0>{}, ct_eq<0>{},
+ ct_eq<1>{},
+ ct_eq<2>{}, ct_eq<2>{}, ct_eq<2>{},
+ ct_eq<3>{}, ct_eq<3>{}, ct_eq<3>{},
+ ct_eq<0>{})),
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<0>{})
+ ));
+}};
+
+TestCase test_unique_by{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ struct undefined { };
+
+ auto a = [](auto z) { return ::equivalence_class(ct_eq<999>{}, z); };
+ auto b = [](auto z) { return ::equivalence_class(ct_eq<888>{}, z); };
+ auto c = [](auto z) { return ::equivalence_class(ct_eq<777>{}, z); };
+
+ auto pred = [](auto x, auto y) {
+ return hana::equal(x.unwrap, y.unwrap);
+ };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(), undefined{}),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(a(ct_eq<0>{})), pred),
+ MAKE_TUPLE(a(ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})), pred),
+ MAKE_TUPLE(a(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{})), pred),
+ MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), c(ct_eq<0>{})), pred),
+ MAKE_TUPLE(a(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), c(ct_eq<1>{})), pred),
+ MAKE_TUPLE(a(ct_eq<0>{}), c(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<0>{})), pred),
+ MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<1>{}), b(ct_eq<1>{})), pred),
+ MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{})), pred),
+ MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique(MAKE_TUPLE(
+ a(ct_eq<0>{}), b(ct_eq<0>{}),
+ a(ct_eq<1>{}),
+ a(ct_eq<2>{}), b(ct_eq<2>{}), c(ct_eq<2>{}),
+ a(ct_eq<3>{}), b(ct_eq<3>{}), c(ct_eq<3>{}),
+ a(ct_eq<0>{})), pred),
+ MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{}), a(ct_eq<3>{}), a(ct_eq<0>{}))
+ ));
+
+ // unique.by
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique.by(pred, MAKE_TUPLE(
+ a(ct_eq<0>{}), b(ct_eq<0>{}),
+ a(ct_eq<1>{}),
+ a(ct_eq<2>{}), b(ct_eq<2>{}), c(ct_eq<2>{}),
+ a(ct_eq<3>{}), b(ct_eq<3>{}), c(ct_eq<3>{}),
+ a(ct_eq<0>{}))),
+ MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{}), a(ct_eq<3>{}), a(ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unique.by(pred)(MAKE_TUPLE(
+ a(ct_eq<0>{}), b(ct_eq<0>{}),
+ a(ct_eq<1>{}),
+ a(ct_eq<2>{}), b(ct_eq<2>{}), c(ct_eq<2>{}),
+ a(ct_eq<3>{}), b(ct_eq<3>{}), c(ct_eq<3>{}),
+ a(ct_eq<0>{}))),
+ MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{}), a(ct_eq<3>{}), a(ct_eq<0>{}))
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_UNIQUE_HPP
diff --git a/src/boost/libs/hana/test/_include/auto/zips.hpp b/src/boost/libs/hana/test/_include/auto/zips.hpp
new file mode 100644
index 00000000..3d129c90
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/auto/zips.hpp
@@ -0,0 +1,342 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_AUTO_ZIPS_HPP
+#define BOOST_HANA_TEST_AUTO_ZIPS_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/zip.hpp>
+#include <boost/hana/zip_shortest.hpp>
+#include <boost/hana/zip_shortest_with.hpp>
+#include <boost/hana/zip_with.hpp>
+
+#include <laws/base.hpp>
+#include "test_case.hpp"
+
+
+TestCase test_zip_shortest_with{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ hana::test::_injection<0> f{};
+ auto zip = hana::zip_shortest_with;
+ struct undefined { };
+
+ // zip 1
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f, MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f, MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f, MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}))
+ ));
+
+ // zip 2
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(undefined{}), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(undefined{})),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f, MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<-1>{})),
+ MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f, MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), MAKE_TUPLE(ct_eq<-1>{})),
+ MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f, MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{})),
+ MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f, MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{})),
+ MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}), f(ct_eq<2>{}, ct_eq<-2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f, MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{})),
+ MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}),
+ f(ct_eq<2>{}, ct_eq<-2>{}),
+ f(ct_eq<3>{}, ct_eq<-3>{}))
+ ));
+
+ // zip 3
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(undefined{}), MAKE_TUPLE(), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(undefined{}), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(), MAKE_TUPLE(undefined{})),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(undefined{}), MAKE_TUPLE(undefined{})),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(undefined{}), MAKE_TUPLE(), MAKE_TUPLE(undefined{})),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(undefined{}, MAKE_TUPLE(undefined{}), MAKE_TUPLE(undefined{}), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f, MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))
+ ));
+
+ // zip 4
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f,
+ MAKE_TUPLE(ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}, ct_eq<14>{}),
+ MAKE_TUPLE(ct_eq<21>{}, ct_eq<22>{}, ct_eq<23>{}),
+ MAKE_TUPLE(ct_eq<31>{}, ct_eq<32>{}, ct_eq<33>{}, ct_eq<34>{}),
+ MAKE_TUPLE(ct_eq<41>{}, ct_eq<42>{}, ct_eq<43>{}, ct_eq<44>{}, ct_eq<45>{})
+ ),
+ MAKE_TUPLE(
+ f(ct_eq<11>{}, ct_eq<21>{}, ct_eq<31>{}, ct_eq<41>{}),
+ f(ct_eq<12>{}, ct_eq<22>{}, ct_eq<32>{}, ct_eq<42>{}),
+ f(ct_eq<13>{}, ct_eq<23>{}, ct_eq<33>{}, ct_eq<43>{})
+ )
+ ));
+
+ // zip 5
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ zip(f,
+ MAKE_TUPLE(ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}, ct_eq<14>{}),
+ MAKE_TUPLE(ct_eq<21>{}, ct_eq<22>{}, ct_eq<23>{}, ct_eq<24>{}, ct_eq<25>{}),
+ MAKE_TUPLE(ct_eq<31>{}, ct_eq<32>{}, ct_eq<33>{}, ct_eq<34>{}),
+ MAKE_TUPLE(ct_eq<41>{}, ct_eq<42>{}, ct_eq<43>{}, ct_eq<44>{}, ct_eq<45>{}, ct_eq<46>{}),
+ MAKE_TUPLE(ct_eq<51>{}, ct_eq<52>{}, ct_eq<53>{}, ct_eq<54>{}, ct_eq<55>{})
+ ),
+ MAKE_TUPLE(
+ f(ct_eq<11>{}, ct_eq<21>{}, ct_eq<31>{}, ct_eq<41>{}, ct_eq<51>{}),
+ f(ct_eq<12>{}, ct_eq<22>{}, ct_eq<32>{}, ct_eq<42>{}, ct_eq<52>{}),
+ f(ct_eq<13>{}, ct_eq<23>{}, ct_eq<33>{}, ct_eq<43>{}, ct_eq<53>{}),
+ f(ct_eq<14>{}, ct_eq<24>{}, ct_eq<34>{}, ct_eq<44>{}, ct_eq<54>{})
+ )
+ ));
+}};
+
+TestCase test_zip_with{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ hana::test::_injection<0> f{};
+ struct undefined { };
+
+ // zip 1
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(undefined{}, MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f, MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f, MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f, MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}))
+ ));
+
+ // zip 2
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(undefined{}, MAKE_TUPLE(), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f, MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<-1>{})),
+ MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f, MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{})),
+ MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}), f(ct_eq<2>{}, ct_eq<-2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f,
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{})),
+ MAKE_TUPLE(
+ f(ct_eq<1>{}, ct_eq<-1>{}),
+ f(ct_eq<2>{}, ct_eq<-2>{}),
+ f(ct_eq<3>{}, ct_eq<-3>{}))
+ ));
+
+ // zip 3
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f, MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{})),
+ MAKE_TUPLE(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f,
+ MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<4>{}, ct_eq<5>{})
+ ),
+ MAKE_TUPLE(
+ f(ct_eq<0>{}, ct_eq<2>{}, ct_eq<4>{}),
+ f(ct_eq<1>{}, ct_eq<3>{}, ct_eq<5>{})
+ )
+ ));
+
+ // zip 4
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f,
+ MAKE_TUPLE(ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}),
+ MAKE_TUPLE(ct_eq<21>{}, ct_eq<22>{}, ct_eq<23>{}),
+ MAKE_TUPLE(ct_eq<31>{}, ct_eq<32>{}, ct_eq<33>{}),
+ MAKE_TUPLE(ct_eq<41>{}, ct_eq<42>{}, ct_eq<43>{})
+ ),
+ MAKE_TUPLE(
+ f(ct_eq<11>{}, ct_eq<21>{}, ct_eq<31>{}, ct_eq<41>{}),
+ f(ct_eq<12>{}, ct_eq<22>{}, ct_eq<32>{}, ct_eq<42>{}),
+ f(ct_eq<13>{}, ct_eq<23>{}, ct_eq<33>{}, ct_eq<43>{})
+ )
+ ));
+
+ // zip 5
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_with(f,
+ MAKE_TUPLE(ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}, ct_eq<14>{}),
+ MAKE_TUPLE(ct_eq<21>{}, ct_eq<22>{}, ct_eq<23>{}, ct_eq<24>{}),
+ MAKE_TUPLE(ct_eq<31>{}, ct_eq<32>{}, ct_eq<33>{}, ct_eq<34>{}),
+ MAKE_TUPLE(ct_eq<41>{}, ct_eq<42>{}, ct_eq<43>{}, ct_eq<44>{}),
+ MAKE_TUPLE(ct_eq<51>{}, ct_eq<52>{}, ct_eq<53>{}, ct_eq<54>{})
+ ),
+ MAKE_TUPLE(
+ f(ct_eq<11>{}, ct_eq<21>{}, ct_eq<31>{}, ct_eq<41>{}, ct_eq<51>{}),
+ f(ct_eq<12>{}, ct_eq<22>{}, ct_eq<32>{}, ct_eq<42>{}, ct_eq<52>{}),
+ f(ct_eq<13>{}, ct_eq<23>{}, ct_eq<33>{}, ct_eq<43>{}, ct_eq<53>{}),
+ f(ct_eq<14>{}, ct_eq<24>{}, ct_eq<34>{}, ct_eq<44>{}, ct_eq<54>{})
+ )
+ ));
+}};
+
+TestCase test_zip{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip(MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip(MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip(MAKE_TUPLE(), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip(MAKE_TUPLE(ct_eq<0>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<4>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<5>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}))
+ ));
+}};
+
+TestCase test_zip_shortest{[]{
+ namespace hana = boost::hana;
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_shortest(MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_shortest(MAKE_TUPLE(), MAKE_TUPLE()),
+ MAKE_TUPLE()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}),
+ MAKE_TUPLE(ct_eq<1>{}),
+ MAKE_TUPLE(ct_eq<2>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}, ct_eq<3>{}),
+ MAKE_TUPLE(ct_eq<1>{}, ct_eq<4>{}),
+ MAKE_TUPLE(ct_eq<2>{}, ct_eq<5>{}, ct_eq<8>{})),
+ MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ MAKE_TUPLE(ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}))
+ ));
+}};
+
+#endif // !BOOST_HANA_TEST_AUTO_ZIPS_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/applicative.hpp b/src/boost/libs/hana/test/_include/laws/applicative.hpp
new file mode 100644
index 00000000..a7de47b9
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/applicative.hpp
@@ -0,0 +1,196 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_APPLICATIVE_HPP
+#define BOOST_HANA_TEST_LAWS_APPLICATIVE_HPP
+
+#include <boost/hana/ap.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/applicative.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/curry.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/take_front.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename F, typename = when<true>>
+ struct TestApplicative : TestApplicative<F, laws> {
+ using TestApplicative<F, laws>::TestApplicative;
+ };
+
+ template <typename F>
+ struct TestApplicative<F, laws> {
+ template <typename Applicatives>
+ TestApplicative(Applicatives applicatives) {
+ hana::for_each(applicatives, [](auto a) {
+ static_assert(Applicative<decltype(a)>{}, "");
+ });
+
+ auto functions1 = hana::take_front(
+ hana::transform(applicatives, [](auto xs) {
+ return hana::transform(xs, hana::curry<2>(test::_injection<0>{}));
+ }), hana::int_c<3>);
+
+ auto functions2 = hana::take_front(
+ hana::transform(applicatives, [](auto xs) {
+ return hana::transform(xs, hana::curry<2>(test::_injection<1>{}));
+ }), hana::int_c<3>);
+
+ // identity
+ {
+ hana::for_each(applicatives, [](auto xs) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::ap(hana::lift<F>(hana::id), xs),
+ xs
+ ));
+ });
+ }
+
+ // composition
+ {
+ hana::for_each(applicatives, hana::capture(functions1, functions2)(
+ [](auto functions1, auto functions2, auto xs) {
+ hana::for_each(functions1, hana::capture(functions2, xs)(
+ [](auto functions2, auto xs, auto fs) {
+ hana::for_each(functions2, hana::capture(xs, fs)(
+ [](auto xs, auto fs, auto gs) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::ap(hana::ap(hana::lift<F>(compose), fs, gs), xs),
+ hana::ap(fs, hana::ap(gs, xs))
+ ));
+ }));}));}));
+ }
+
+ // homomorphism
+ {
+ test::_injection<0> f{};
+ test::ct_eq<3> x{};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(hana::lift<F>(f), hana::lift<F>(x)),
+ hana::lift<F>(f(x))
+ ));
+ }
+
+ // interchange
+ {
+ hana::for_each(functions1, [](auto fs) {
+ test::ct_eq<4> x{};
+ BOOST_HANA_CHECK(hana::equal(
+ hana::ap(fs, hana::lift<F>(x)),
+ hana::ap(hana::lift<F>(hana::_(x)), fs)
+ ));
+ });
+ }
+
+ // definition of transform
+ {
+ hana::for_each(applicatives, [](auto xs) {
+ test::_injection<0> f{};
+ BOOST_HANA_CHECK(hana::equal(
+ hana::transform(xs, f),
+ hana::ap(hana::lift<F>(f), xs)
+ ));
+ });
+ }
+ }
+ };
+
+ template <typename S>
+ struct TestApplicative<S, when<Sequence<S>::value>>
+ : TestApplicative<S, laws>
+ {
+ template <typename Applicatives>
+ TestApplicative(Applicatives applicatives)
+ : TestApplicative<S, laws>{applicatives}
+ {
+ _injection<0> f{};
+ _injection<1> g{};
+ using test::ct_eq;
+ constexpr auto list = make<S>;
+
+ //////////////////////////////////////////////////////////////////
+ // ap
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(), list()),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(), list(ct_eq<0>{})),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(), list(ct_eq<0>{}, ct_eq<1>{})),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(), list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(f), list()),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(f), list(ct_eq<0>{})),
+ list(f(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(f), list(ct_eq<0>{}, ct_eq<1>{})),
+ list(f(ct_eq<0>{}), f(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(f), list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ list(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(f, g), list()),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(f, g), list(ct_eq<0>{})),
+ list(f(ct_eq<0>{}), g(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(f, g), list(ct_eq<0>{}, ct_eq<1>{})),
+ list(f(ct_eq<0>{}), f(ct_eq<1>{}), g(ct_eq<0>{}), g(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(list(f, g), list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ list(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}),
+ g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}))
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // lift
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ lift<S>(ct_eq<0>{}),
+ list(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ lift<S>(ct_eq<1>{}),
+ list(ct_eq<1>{})
+ ));
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_APPLICATIVE_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/base.hpp b/src/boost/libs/hana/test/_include/laws/base.hpp
new file mode 100644
index 00000000..0f421b8a
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/base.hpp
@@ -0,0 +1,369 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_BASE_HPP
+#define BOOST_HANA_TEST_LAWS_BASE_HPP
+
+#include <boost/hana/and.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/detail/wrong.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/infix.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/fwd/concept/integral_constant.hpp>
+#include <boost/hana/fwd/core/to.hpp>
+#include <boost/hana/fwd/less.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/or.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <support/tracked.hpp>
+
+#include <type_traits>
+#include <utility>
+
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Misc
+ //////////////////////////////////////////////////////////////////////////
+ namespace test {
+ struct laws;
+
+ template <int i>
+ struct for_each_n_t {
+ static_assert(i > 0, "can't use for_each_n with i < 0");
+
+ template <typename Xs, typename F>
+ constexpr auto operator()(Xs const& xs, F const& f) const {
+ hana::for_each(xs,
+ hana::compose(
+ hana::partial(for_each_n_t<i - 1>{}, xs),
+ hana::partial(hana::partial, f)
+ )
+ );
+ }
+ };
+
+ template <>
+ struct for_each_n_t<1> {
+ template <typename Xs, typename F>
+ constexpr auto operator()(Xs const& xs, F const& f) const {
+ hana::for_each(xs, f);
+ }
+ };
+
+ template <int i>
+ constexpr for_each_n_t<i> for_each_n{};
+
+ auto foreach = hana::for_each;
+ constexpr auto foreach3 = for_each_n<3>;
+ constexpr auto foreach2 = for_each_n<2>;
+
+ struct implies_t {
+ template <typename P, typename Q>
+ constexpr decltype(auto) operator()(P&& p, Q&& q) const {
+ return hana::or_(hana::not_(static_cast<P&&>(p)),
+ static_cast<Q&&>(q));
+ }
+ };
+ constexpr auto implies = hana::infix(implies_t{});
+
+ struct iff_t {
+ template <typename P, typename Q>
+ constexpr decltype(auto) operator()(P&& p, Q&& q) const {
+ return hana::and_(implies(p, q), implies(q, p));
+ }
+ };
+ constexpr auto iff = hana::infix(iff_t{});
+
+ template <typename Cond, typename F>
+ constexpr decltype(auto) only_when_(Cond cond, F f) {
+ return hana::eval_if(cond, f, [](auto){ });
+ }
+
+ // A type with a constructor that must not be instantiated.
+ // This is to make sure we don't instantiate something else than
+ // the copy-constructor of the elements inside a container when we
+ // copy the container.
+ struct trap_construct {
+ trap_construct() = default;
+ trap_construct(trap_construct const&) = default;
+#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
+ trap_construct(trap_construct&) = default;
+#endif
+ trap_construct(trap_construct&&) = default;
+
+ template <typename X>
+ trap_construct(X&&) {
+ static_assert(detail::wrong<X>{},
+ "this constructor must not be instantiated");
+ }
+ };
+
+ // A move-only type. Useful for testing containers.
+ struct move_only {
+ move_only() = default;
+ move_only(move_only const&) = delete;
+ move_only(move_only&&) = default;
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // InjectionResult
+ //////////////////////////////////////////////////////////////////////
+ struct InjectionResult { };
+
+ template <int i, typename ...X>
+ struct injection_result {
+ using hana_tag = InjectionResult;
+ static constexpr int injection_id = i;
+ hana::tuple<X...> args;
+ Tracked tracker;
+
+ template <typename ...Y, typename = decltype(tuple<X...>{std::declval<Y>()...})>
+ constexpr explicit injection_result(Y&& ...y)
+ : args{static_cast<Y&&>(y)...}, tracker{i}
+ { }
+ };
+
+ //! A monotonic injective function.
+ //!
+ //! This is used in the unit tests, where we often just need a function
+ //! which preserves equality and order, but which also satisfies the
+ //! following law for all `Injection`s `f` and `g`:
+ //! @code
+ //! f(x) == g(x) if and only if f === g
+ //! @endcode
+ //! where `===` means _was created by the same call to `injection`_.
+ //! This allows creating several such functions in the unit tests while
+ //! conserving precious information such as the fact that
+ //! `f(g(x)) != g(f(x))`.
+ template <int i>
+ struct _injection {
+ template <typename ...X>
+ constexpr auto operator()(X&& ...x) const {
+ return injection_result<i,
+ typename std::decay<X>::type...
+ >{static_cast<X&&>(x)...};
+ }
+ };
+ } // end namespace test
+
+ template <>
+ struct equal_impl<test::InjectionResult, test::InjectionResult> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y) {
+ return hana::and_(
+ hana::bool_c<X::injection_id == Y::injection_id>,
+ hana::equal(x.args, y.args)
+ );
+ }
+ };
+
+ template <>
+ struct less_impl<test::InjectionResult, test::InjectionResult> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y) {
+ static_assert(X::injection_id == Y::injection_id,
+ "can't order the result of two different injections");
+ return hana::less(x.args, y.args);
+ }
+ };
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Integer
+ //////////////////////////////////////////////////////////////////////////
+ namespace test {
+ enum class Policy : int {
+ // One of those is mandatory
+ Constant = 1 << 0
+ , Constexpr = 1 << 1
+ , Runtime = 1 << 2
+
+ // Those are optional
+ , Tracked = 1 << 3
+ , Comparable = 1 << 4
+ , Orderable = 1 << 5
+ };
+
+ constexpr bool operator&&(Policy a, Policy b) {
+ return static_cast<int>(a) && static_cast<int>(b);
+ }
+
+ constexpr bool operator&&(Policy a, bool b) {
+ return static_cast<int>(a) && b;
+ }
+
+ constexpr bool operator&&(bool a, Policy b) {
+ return a && static_cast<int>(b);
+ }
+
+ constexpr bool operator||(Policy a, Policy b) {
+ return static_cast<int>(a) || static_cast<int>(b);
+ }
+
+ constexpr bool operator||(Policy a, bool b) {
+ return static_cast<int>(a) || b;
+ }
+
+ constexpr bool operator||(bool a, Policy b) {
+ return a || static_cast<int>(b);
+ }
+
+ constexpr bool operator!(Policy a) {
+ return !static_cast<int>(a);
+ }
+
+ constexpr Policy operator|(Policy a, Policy b) {
+ return static_cast<Policy>(static_cast<int>(a) | static_cast<int>(b));
+ }
+
+ constexpr Policy operator&(Policy a, Policy b) {
+ return static_cast<Policy>(static_cast<int>(a) & static_cast<int>(b));
+ }
+
+ template <Policy policy, typename = void>
+ struct Integer { };
+
+ template <Policy policy>
+ struct Integer<policy, std::enable_if_t<!!(policy & Policy::Constant)>> {
+ using value_type = int;
+ };
+
+ template <int i, Policy policy, typename = void>
+ struct integer {
+ static_assert(
+ !!(policy & (Policy::Constant | Policy::Constexpr | Policy::Runtime))
+ , "You must choose at least one of Constant, Constexpr and Runtime.");
+
+ static constexpr int value = i;
+ constexpr operator int() const { return value; }
+ using hana_tag = Integer<policy>;
+ Tracked tracker{i};
+ };
+
+ template <int i, Policy policy>
+ struct integer <i, policy, std::enable_if_t<!!(policy & Policy::Constexpr)>> {
+ static constexpr int value = i;
+ constexpr operator int() const { return value; }
+ using hana_tag = Integer<policy>;
+ };
+
+ template <int i>
+ struct eq : integer<i, Policy::Comparable | Policy::Runtime> { };
+
+ template <int i>
+ struct ct_eq : integer<i, Policy::Comparable | Policy::Constant> { };
+
+ template <int i>
+ struct cx_eq : integer<i, Policy::Comparable | Policy::Constexpr> { };
+
+ template <int i>
+ struct ord : integer<i, Policy::Orderable | Policy::Runtime> { };
+
+ template <int i>
+ struct ct_ord : integer<i, Policy::Orderable | Policy::Constant> { };
+
+ template <int i>
+ struct cx_ord : integer<i, Policy::Orderable | Policy::Constexpr> { };
+
+ template <int i>
+ struct _constant
+ : integer<i, Policy::Constant | Policy::Comparable | Policy::Orderable>
+ { };
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Model of Constant/IntegralConstant
+ //////////////////////////////////////////////////////////////////////////
+ template <test::Policy policy>
+ struct IntegralConstant<test::Integer<policy>> {
+ static constexpr bool value = static_cast<bool>(policy & test::Policy::Constant);
+ };
+
+ template <test::Policy policy, typename C>
+ struct to_impl<test::Integer<policy>, C, when<
+ (policy & test::Policy::Constant) &&
+ hana::IntegralConstant<C>::value
+ >>
+ : embedding<is_embedded<typename C::value_type, int>::value>
+ {
+ template <typename N>
+ static constexpr auto apply(N const&) {
+ return test::integer<N::value, policy>{};
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Model of Comparable
+ //////////////////////////////////////////////////////////////////////////
+ template <test::Policy p1, test::Policy p2>
+ struct equal_impl<test::Integer<p1>, test::Integer<p2>, when<
+ // both Comparable or Orderable
+ (p1 & (test::Policy::Comparable | test::Policy::Orderable)) &&
+ (p2 & (test::Policy::Comparable | test::Policy::Orderable)) &&
+
+ // one Constexpr and the other Constant, or both Constexpr
+ (((p1 & test::Policy::Constant) && (p2 & test::Policy::Constexpr)) ||
+ ((p1 & test::Policy::Constexpr) && (p2 & test::Policy::Constant)) ||
+ ((p1 & test::Policy::Constexpr) && (p2 & test::Policy::Constexpr)))
+ >> {
+ template <typename X, typename Y>
+ static constexpr bool apply(X const&, Y const&)
+ { return X::value == Y::value; }
+ };
+
+ template <test::Policy p1, test::Policy p2>
+ struct equal_impl<test::Integer<p1>, test::Integer<p2>, when<
+ // both Comparable or Orderable
+ (p1 & (test::Policy::Comparable | test::Policy::Orderable)) &&
+ (p2 & (test::Policy::Comparable | test::Policy::Orderable)) &&
+
+ // either one is Runtime
+ ((p1 & test::Policy::Runtime) || (p2 & test::Policy::Runtime))
+ >> {
+ template <typename X, typename Y>
+ static bool apply(X const&, Y const&)
+ { return X::value == Y::value; }
+ };
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Model of Orderable
+ //////////////////////////////////////////////////////////////////////////
+ template <test::Policy p1, test::Policy p2>
+ struct less_impl<test::Integer<p1>, test::Integer<p2>, when<
+ // both Orderable
+ (p1 & test::Policy::Orderable) && (p2 & test::Policy::Orderable) &&
+
+ // one Constexpr and the other Constant, or both Constexpr
+ (((p1 & test::Policy::Constant) && (p2 & test::Policy::Constexpr)) ||
+ ((p1 & test::Policy::Constexpr) && (p2 & test::Policy::Constant)) ||
+ ((p1 & test::Policy::Constexpr) && (p2 & test::Policy::Constexpr)))
+ >> {
+ template <typename X, typename Y>
+ static constexpr bool apply(X const&, Y const&)
+ { return X::value < Y::value; }
+ };
+
+ template <test::Policy p1, test::Policy p2>
+ struct less_impl<test::Integer<p1>, test::Integer<p2>, when<
+ // both Orderable
+ (p1 & test::Policy::Orderable) && (p2 & test::Policy::Orderable) &&
+
+ // either one is Runtime
+ ((p1 & test::Policy::Runtime) || (p2 & test::Policy::Runtime))
+ >> {
+ template <typename X, typename Y>
+ static bool apply(X const&, Y const&)
+ { return X::value < Y::value; }
+ };
+}} // end namespace boost::hana
+
+#endif // !BOOST_HANA_TEST_LAWS_BASE_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/comonad.hpp b/src/boost/libs/hana/test/_include/laws/comonad.hpp
new file mode 100644
index 00000000..82ef7b32
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/comonad.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_LAWS_COMONAD_HPP
+#define BOOST_HANA_TEST_LAWS_COMONAD_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/comonad.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/concept/foldable.hpp>
+#include <boost/hana/concept/functor.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename W, typename = when<true>>
+ struct TestComonad : TestComonad<W, laws> {
+ using TestComonad<W, laws>::TestComonad;
+ };
+
+ template <typename W>
+ struct TestComonad<W, laws> {
+ template <typename Ws>
+ TestComonad(Ws ws) {
+ hana::for_each(ws, [](auto w) {
+ static_assert(Comonad<decltype(w)>{}, "");
+
+ // extract(duplicate(w)) == w
+ BOOST_HANA_CHECK(hana::equal(
+ hana::extract(hana::duplicate(w)),
+ w
+ ));
+
+ // transform(duplicate(w), extract) == w
+ BOOST_HANA_CHECK(hana::equal(
+ hana::transform(hana::duplicate(w), extract),
+ w
+ ));
+
+ // duplicate(duplicate(w)) == transform(duplicate(w), duplicate)
+ BOOST_HANA_CHECK(hana::equal(
+ hana::duplicate(hana::duplicate(w)),
+ hana::transform(hana::duplicate(w), duplicate)
+ ));
+ });
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_COMONAD_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/comparable.hpp b/src/boost/libs/hana/test/_include/laws/comparable.hpp
new file mode 100644
index 00000000..24ce317b
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/comparable.hpp
@@ -0,0 +1,167 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_COMPARABLE_HPP
+#define BOOST_HANA_TEST_LAWS_COMPARABLE_HPP
+
+#include <boost/hana/and.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/comparing.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/concept/constant.hpp>
+#include <boost/hana/concept/product.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/value.hpp>
+
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename T, typename = hana::when<true>>
+ struct TestComparable : TestComparable<T, laws> {
+ using TestComparable<T, laws>::TestComparable;
+ };
+
+ template <typename T>
+ struct TestComparable<T, laws> {
+ template <typename Xs>
+ TestComparable(Xs xs) {
+ hana::for_each(xs, [](auto x) {
+ static_assert(hana::Comparable<decltype(x)>{}, "");
+ });
+
+ foreach2(xs, [](auto a, auto b) {
+
+ // reflexivity
+ BOOST_HANA_CHECK(
+ hana::equal(a, a)
+ );
+
+ // symmetry
+ BOOST_HANA_CHECK(
+ hana::equal(a, b) ^implies^ hana::equal(b, a)
+ );
+
+ // `not_equal` is the negation of `equal`
+ BOOST_HANA_CHECK(
+ hana::not_equal(a, b) ^iff^ hana::not_(hana::equal(a, b))
+ );
+
+ // equal.to and not_equal.to
+ BOOST_HANA_CHECK(
+ hana::equal.to(a)(b) ^iff^ hana::equal(a, b)
+ );
+
+ BOOST_HANA_CHECK(
+ hana::not_equal.to(a)(b) ^iff^ hana::not_equal(a, b)
+ );
+
+ // comparing
+ _injection<0> f{};
+ BOOST_HANA_CHECK(
+ hana::comparing(f)(a, b) ^iff^ hana::equal(f(a), f(b))
+ );
+ });
+
+ // transitivity
+ foreach3(xs, [](auto a, auto b, auto c) {
+ BOOST_HANA_CHECK(
+ hana::and_(hana::equal(a, b), hana::equal(b, c))
+ ^implies^ hana::equal(a, c)
+ );
+ });
+ }
+ };
+
+ template <typename C>
+ struct TestComparable<C, when<Constant<C>::value>>
+ : TestComparable<C, laws>
+ {
+ template <typename Xs>
+ TestComparable(Xs xs) : TestComparable<C, laws>{xs} {
+ foreach2(xs, [](auto a, auto b) {
+ BOOST_HANA_CHECK(
+ hana::value(hana::equal(a, b)) ^iff^
+ hana::equal(hana::value(a), hana::value(b))
+ );
+ });
+ }
+ };
+
+ template <typename P>
+ struct TestComparable<P, when<Product<P>::value>>
+ : TestComparable<P, laws>
+ {
+ template <typename Products>
+ TestComparable(Products products) : TestComparable<P, laws>{products} {
+ foreach2(products, [](auto x, auto y) {
+ BOOST_HANA_CHECK(
+ hana::equal(x, y) ^iff^
+ hana::and_(
+ hana::equal(hana::first(x), hana::first(y)),
+ hana::equal(hana::second(x), hana::second(y))
+ )
+ );
+ });
+ }
+ };
+
+ template <typename S>
+ struct TestComparable<S, when<Sequence<S>::value>>
+ : TestComparable<S, laws>
+ {
+ template <int i>
+ using x = _constant<i>;
+
+ template <typename Xs>
+ TestComparable(Xs xs) : TestComparable<S, laws>{xs} {
+ constexpr auto list = make<S>;
+
+ //////////////////////////////////////////////////////////////////
+ // equal
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ list(),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ list(x<0>{}),
+ list()
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ list(),
+ list(x<0>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ list(x<0>{}),
+ list(x<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ list(x<0>{}, x<1>{}),
+ list(x<0>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ list(x<0>{}, x<1>{}),
+ list(x<0>{}, x<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ list(x<0>{}, x<1>{}, x<2>{}, x<3>{}),
+ list(x<0>{}, x<1>{}, x<2>{}, x<4>{})
+ )));
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_COMPARABLE_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/constant.hpp b/src/boost/libs/hana/test/_include/laws/constant.hpp
new file mode 100644
index 00000000..1acd335e
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/constant.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_LAWS_CONSTANT_HPP
+#define BOOST_HANA_TEST_LAWS_CONSTANT_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/concept/logical.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/euclidean_ring.hpp>
+#include <laws/group.hpp>
+#include <laws/logical.hpp>
+#include <laws/monoid.hpp>
+#include <laws/orderable.hpp>
+#include <laws/ring.hpp>
+
+#include <type_traits>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename C, typename = when<true>>
+ struct TestConstant {
+ using T = typename C::value_type;
+
+ template <typename X>
+ struct wrap_arbitrary_constant {
+ static constexpr bool value = boost::hana::value<X>();
+ using hana_tag = detail::CanonicalConstant<T>;
+ };
+
+ template <typename Xs, typename Convertibles>
+ TestConstant(Xs xs, Convertibles types) {
+ hana::for_each(xs, [](auto x) {
+ static_assert(Constant<decltype(x)>{}, "");
+ });
+
+ hana::for_each(xs, hana::capture(types)([](auto types, auto c) {
+
+ // constexpr-ness of hana::value(c)
+ constexpr auto must_be_constexpr1 = hana::value(c);
+ constexpr auto must_be_constexpr2 = hana::value<decltype(c)>();
+ (void)must_be_constexpr1;
+ (void)must_be_constexpr2;
+
+ // consistency of C::value_type
+ static_assert(std::is_same<
+ T,
+ tag_of_t<decltype(hana::value(c))>
+ >{}, "");
+
+ // equivalence of value_of(c) and value<decltype(c)>
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value_of(c),
+ hana::value<decltype(c)>()
+ ));
+
+ // equivalence of value<decltype(c)>() and value(c)
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value<decltype(c)>(),
+ hana::value(c)
+ ));
+
+ // conversion from an arbitrary Constant
+ (void)to<C>(wrap_arbitrary_constant<decltype(c)>{});
+ static_assert(is_embedded<detail::CanonicalConstant<T>, C>{}, "");
+
+ hana::for_each(types, hana::capture(c)([](auto c, auto u) {
+ using U = typename decltype(u)::type;
+
+ // conversion to something to which the underlying data
+ // type can be converted.
+ BOOST_HANA_CHECK(equal(
+ to<U>(c),
+ make<U>(hana::value(c))
+ ));
+ static_assert(is_embedded<C, U>::value ^iff^ is_embedded<T, U>::value, "");
+
+ // common data type
+ static_assert(std::is_same<
+ common_t<C, detail::CanonicalConstant<U>>,
+ detail::CanonicalConstant<common_t<T, U>>
+ >{}, "");
+
+ static_assert(std::is_same<
+ common_t<detail::CanonicalConstant<U>, C>,
+ detail::CanonicalConstant<common_t<T, U>>
+ >{}, "");
+
+ static_assert(std::is_same<
+ common_t<C, U>,
+ common_t<typename C::value_type, U>
+ >{}, "");
+ }));
+ }));
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_CONSTANT_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/euclidean_ring.hpp b/src/boost/libs/hana/test/_include/laws/euclidean_ring.hpp
new file mode 100644
index 00000000..96d1fce5
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/euclidean_ring.hpp
@@ -0,0 +1,99 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_EUCLIDEAN_RING_HPP
+#define BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/concept/constant.hpp>
+#include <boost/hana/concept/euclidean_ring.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/div.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/value.hpp>
+#include <boost/hana/zero.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename D, typename = when<true>>
+ struct TestEuclideanRing : TestEuclideanRing<D, laws> {
+ using TestEuclideanRing<D, laws>::TestEuclideanRing;
+ };
+
+ template <typename D>
+ struct TestEuclideanRing<D, laws> {
+ template <typename Xs>
+ TestEuclideanRing(Xs xs) {
+ hana::for_each(xs, [](auto x) {
+ static_assert(EuclideanRing<decltype(x)>{}, "");
+ });
+
+#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735
+ zero<D>(); // force adding zero<D>'s member function to pending temploid list
+#endif
+
+ foreach2(xs, [](auto a, auto b) {
+
+ // commutativity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::mult(a, b),
+ hana::mult(b, a)
+ ));
+
+ only_when_(hana::not_equal(b, zero<D>()),
+ hana::make_lazy([](auto a, auto b) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::plus(
+ hana::mult(hana::div(a, b), b),
+ hana::mod(a, b)
+ ),
+ a
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::mod(zero<D>(), b),
+ zero<D>()
+ ));
+ })(a, b));
+
+ });
+ }
+ };
+
+ template <typename C>
+ struct TestEuclideanRing<C, when<Constant<C>::value>>
+ : TestEuclideanRing<C, laws>
+ {
+ template <typename Xs>
+ TestEuclideanRing(Xs xs) : TestEuclideanRing<C, laws>{xs} {
+ foreach2(xs, [](auto x, auto y) {
+ only_when_(hana::not_equal(zero<C>(), y),
+ hana::make_lazy([](auto x, auto y) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::div(hana::value(x), hana::value(y)),
+ hana::value(hana::div(x, y))
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::mod(hana::value(x), hana::value(y)),
+ hana::value(hana::mod(x, y))
+ ));
+
+ })(x, y));
+ });
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/foldable.hpp b/src/boost/libs/hana/test/_include/laws/foldable.hpp
new file mode 100644
index 00000000..57411f41
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/foldable.hpp
@@ -0,0 +1,1104 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_FOLDABLE_HPP
+#define BOOST_HANA_TEST_LAWS_FOLDABLE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/concept/foldable.hpp>
+#include <boost/hana/concept/product.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/count.hpp>
+#include <boost/hana/count_if.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/fold.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/functional/curry.hpp>
+#include <boost/hana/functional/demux.hpp>
+#include <boost/hana/functional/flip.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/maximum.hpp>
+#include <boost/hana/minimum.hpp>
+#include <boost/hana/monadic_fold_left.hpp>
+#include <boost/hana/monadic_fold_right.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/product.hpp>
+#include <boost/hana/reverse_fold.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/size.hpp>
+#include <boost/hana/sum.hpp>
+#include <boost/hana/unpack.hpp>
+#include <boost/hana/value.hpp>
+
+#include <laws/base.hpp>
+#include <support/identity.hpp>
+
+#include <vector>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename F, typename = when<true>>
+ struct TestFoldable : TestFoldable<F, laws> {
+ using TestFoldable<F, laws>::TestFoldable;
+ };
+
+ template <typename F>
+ struct TestFoldable<F, laws> {
+ template <typename Foldables>
+ TestFoldable(Foldables foldables) {
+ hana::for_each(foldables, [](auto xs) {
+ static_assert(Foldable<decltype(xs)>{}, "");
+
+ _injection<0> f{};
+ ct_eq<999> s{};
+
+ // equivalence of size(xs) and length(xs)
+ BOOST_HANA_CHECK(hana::equal(
+ hana::length(xs),
+ hana::size(xs)
+ ));
+
+ // equivalence of fold with fold_left and
+ // of reverse_fold with fold_right
+ BOOST_HANA_CHECK(hana::equal(
+ hana::fold(xs, s, f),
+ hana::fold_left(xs, s, f)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::reverse_fold(xs, s, f),
+ hana::fold_right(xs, s, hana::flip(f))
+ ));
+
+ only_when_(hana::not_equal(hana::length(xs), hana::size_c<0>),
+ hana::make_lazy([](auto f, auto xs) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::fold(xs, f),
+ hana::fold_left(xs, f)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::reverse_fold(xs, f),
+ hana::fold_right(xs, hana::flip(f))
+ ));
+ })(f, xs));
+
+ // equivalence of count(xs, val) and count_if(xs, equal.to(val))
+ struct not_there { };
+ BOOST_HANA_CHECK(hana::equal(
+ hana::count(xs, not_there{}),
+ hana::count_if(xs, equal.to(not_there{}))
+ ));
+
+ hana::for_each(xs, hana::capture(xs)([](auto xs, auto value) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::count(xs, value),
+ hana::count_if(xs, equal.to(value))
+ ));
+ }));
+ });
+ }
+ };
+
+ template <typename P>
+ struct TestFoldable<P, when<Product<P>::value>>
+ : TestFoldable<P, laws>
+ {
+ template <typename Products>
+ TestFoldable(Products products) : TestFoldable<P, laws>{products} {
+ hana::for_each(products, [](auto p) {
+ _injection<0> f{};
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::unpack(p, f),
+ f(hana::first(p), hana::second(p))
+ ));
+ });
+ }
+ };
+
+ template <typename S>
+ struct TestFoldable<S, when<Sequence<S>::value>>
+ : TestFoldable<S, laws>
+ {
+ template <int i>
+ using x = _constant<i>;
+
+ template <int i>
+ using ord = _constant<i>;
+
+ struct undefined { };
+
+ template <typename Xs>
+ TestFoldable(Xs xs) : TestFoldable<S, laws>{xs} {
+ _injection<0> f{};
+ auto z = x<999>{};
+ constexpr auto list = make<S>;
+
+ //////////////////////////////////////////////////////////////////
+ // fold_left (with initial state)
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_left(list(), z, undefined{}),
+ z
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_left(list(x<1>{}), z, f),
+ f(z, x<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_left(list(x<1>{}, x<2>{}), z, f),
+ f(f(z, x<1>{}), x<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_left(list(x<1>{}, x<2>{}, x<3>{}), z, f),
+ f(f(f(z, x<1>{}), x<2>{}), x<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_left(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), z, f),
+ f(f(f(f(z, x<1>{}), x<2>{}), x<3>{}), x<4>{})
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ fold_left(list(1), z, f),
+ f(z, 1)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ fold_left(list(1, '2'), z, f),
+ f(f(z, 1), '2')
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ fold_left(list(1, '2', 3.3), z, f),
+ f(f(f(z, 1), '2'), 3.3)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ fold_left(list(1, '2', 3.3, 4.4f), z, f),
+ f(f(f(f(z, 1), '2'), 3.3), 4.4f)
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // fold_left (without initial state)
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_left(list(z), undefined{}),
+ z
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_left(list(z, x<2>{}), f),
+ f(z, x<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_left(list(z, x<2>{}, x<3>{}), f),
+ f(f(z, x<2>{}), x<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_left(list(z, x<2>{}, x<3>{}, x<4>{}), f),
+ f(f(f(z, x<2>{}), x<3>{}), x<4>{})
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // fold_right (with initial state)
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_right(list(), z, undefined{}),
+ z
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_right(list(x<0>{}), z, f),
+ f(x<0>{}, z)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_right(list(x<0>{}, x<1>{}), z, f),
+ f(x<0>{}, f(x<1>{}, z))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_right(list(x<0>{}, x<1>{}, x<2>{}), z, f),
+ f(x<0>{}, f(x<1>{}, f(x<2>{}, z)))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_right(list(x<0>{}, x<1>{}, x<2>{}, x<3>{}), z, f),
+ f(x<0>{}, f(x<1>{}, f(x<2>{}, f(x<3>{}, z))))
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ fold_right(list(1), z, f),
+ f(1, z)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ fold_right(list(1, '2'), z, f),
+ f(1, f('2', z))
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ fold_right(list(1, '2', 3.3), z, f),
+ f(1, f('2', f(3.3, z)))
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ fold_right(list(1, '2', 3.3, 4.4f), z, f),
+ f(1, f('2', f(3.3, f(4.4f, z))))
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // fold_right (without initial state)
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_right(list(z), undefined{}),
+ z
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_right(list(x<1>{}, z), f),
+ f(x<1>{}, z)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_right(list(x<1>{}, x<2>{}, z), f),
+ f(x<1>{}, f(x<2>{}, z))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ fold_right(list(x<1>{}, x<2>{}, x<3>{}, z), f),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, z)))
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // monadic_fold_left (with initial state)
+ //////////////////////////////////////////////////////////////////
+ {
+ using M = ::Identity;
+ auto f = hana::demux(::identity)(test::_injection<0>{});
+ auto s = x<999>{};
+ auto fp = hana::curry<2>(hana::flip(f));
+ constexpr auto mfold = monadic_fold_left<M>;
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(), s, undefined{}),
+ lift<M>(s)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}), s, f),
+ f(s, x<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}), s, f),
+ chain(f(s, x<1>{}), fp(x<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}), s, f),
+ chain(chain(f(s, x<1>{}), fp(x<2>{})), fp(x<3>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), s, f),
+ chain(chain(chain(f(s, x<1>{}), fp(x<2>{})), fp(x<3>{})), fp(x<4>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), s, f),
+ chain(chain(chain(chain(f(s, x<1>{}), fp(x<2>{})), fp(x<3>{})), fp(x<4>{})), fp(x<5>{}))
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // monadic_fold_left (without initial state)
+ //////////////////////////////////////////////////////////////////
+ {
+ using M = ::Identity;
+ auto f = hana::demux(::identity)(test::_injection<0>{});
+ auto fp = hana::curry<2>(hana::flip(f));
+ constexpr auto mfold = monadic_fold_left<M>;
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}), undefined{}),
+ lift<M>(x<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}), f),
+ f(x<1>{}, x<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}), f),
+ chain(f(x<1>{}, x<2>{}), fp(x<3>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), f),
+ chain(chain(f(x<1>{}, x<2>{}), fp(x<3>{})), fp(x<4>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), f),
+ chain(chain(chain(f(x<1>{}, x<2>{}), fp(x<3>{})), fp(x<4>{})), fp(x<5>{}))
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // monadic_fold_right (with initial state)
+ //////////////////////////////////////////////////////////////////
+ {
+ using M = ::Identity;
+ auto f = hana::demux(::identity)(test::_injection<0>{});
+ auto s = x<999>{};
+ auto fp = hana::curry<2>(f);
+ // flipping `chain` makes the right associativity easier to see
+ auto chain = hana::flip(hana::chain);
+ constexpr auto mfold = monadic_fold_right<M>;
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(), s, undefined{}),
+ lift<M>(s)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}), s, f),
+ f(x<1>{}, s)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}), s, f),
+ chain(fp(x<1>{}), f(x<2>{}, s))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}), s, f),
+ chain(fp(x<1>{}), chain(fp(x<2>{}), f(x<3>{}, s)))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), s, f),
+ chain(fp(x<1>{}), chain(fp(x<2>{}), chain(fp(x<3>{}), f(x<4>{}, s))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), s, f),
+ chain(fp(x<1>{}), chain(fp(x<2>{}), chain(fp(x<3>{}), chain(fp(x<4>{}), f(x<5>{}, s)))))
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // monadic_fold_right (without initial state)
+ //////////////////////////////////////////////////////////////////
+ {
+ using M = ::Identity;
+ auto f = hana::demux(::identity)(test::_injection<0>{});
+ auto fp = hana::curry<2>(f);
+ // flipping `chain` makes the right associativity easier to see
+ auto chain = hana::flip(hana::chain);
+ constexpr auto mfold = monadic_fold_right<M>;
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}), undefined{}),
+ lift<M>(x<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}), f),
+ f(x<1>{}, x<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}), f),
+ chain(fp(x<1>{}), f(x<2>{}, x<3>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), f),
+ chain(fp(x<1>{}), chain(fp(x<2>{}), f(x<3>{}, x<4>{})))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), f),
+ chain(fp(x<1>{}), chain(fp(x<2>{}), chain(fp(x<3>{}), f(x<4>{}, x<5>{}))))
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // length
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ length(list()), size_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ length(list(undefined{})), size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ length(list(undefined{}, undefined{})), size_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ length(list(undefined{}, undefined{}, undefined{})), size_c<3>
+ ));
+
+ int i = 0; // non-constexpr
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ length(list(i, i)),
+ size_c<2>
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // maximum (without a custom predicate)
+ //////////////////////////////////////////////////////////////////
+ {
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<0>{})),
+ ord<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<0>{}, ord<1>{})),
+ ord<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<1>{}, ord<0>{})),
+ ord<1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<0>{}, ord<1>{}, ord<2>{})),
+ ord<2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<1>{}, ord<0>{}, ord<2>{})),
+ ord<2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<1>{}, ord<2>{}, ord<0>{})),
+ ord<2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<2>{}, ord<1>{}, ord<0>{})),
+ ord<2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<2>{}, ord<0>{}, ord<1>{})),
+ ord<2>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<0>{}, ord<1>{}, ord<2>{}, ord<3>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<1>{}, ord<0>{}, ord<2>{}, ord<3>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<1>{}, ord<2>{}, ord<0>{}, ord<3>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<1>{}, ord<2>{}, ord<3>{}, ord<0>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<2>{}, ord<1>{}, ord<3>{}, ord<0>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<2>{}, ord<3>{}, ord<1>{}, ord<0>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<2>{}, ord<3>{}, ord<0>{}, ord<1>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<3>{}, ord<2>{}, ord<0>{}, ord<1>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<3>{}, ord<0>{}, ord<2>{}, ord<1>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<3>{}, ord<0>{}, ord<1>{}, ord<2>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<0>{}, ord<2>{}, ord<3>{}, ord<1>{})),
+ ord<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ maximum(list(ord<0>{}, ord<3>{}, ord<1>{}, ord<2>{})),
+ ord<3>{}
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{0})),
+ int{0}
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{0}, long{1})),
+ long{1}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{1}, long{0})),
+ int{1}
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{0}, 1ll, long{2})),
+ long{2}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{1}, 0ll, long{2})),
+ long{2}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{1}, 2ll, long{0})),
+ 2ll
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{2}, 1ll, long{0})),
+ int{2}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{2}, 0ll, long{1})),
+ int{2}
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{0}, 1ll, long{2}, short{3})),
+ short{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{1}, 0ll, long{2}, short{3})),
+ short{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{1}, 2ll, long{0}, short{3})),
+ short{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{1}, 2ll, long{3}, short{0})),
+ long{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{2}, 1ll, long{3}, short{0})),
+ long{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{2}, 3ll, long{1}, short{0})),
+ 3ll
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{2}, 3ll, long{0}, short{1})),
+ 3ll
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{3}, 2ll, long{0}, short{1})),
+ int{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{3}, 0ll, long{2}, short{1})),
+ int{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{3}, 0ll, long{1}, short{2})),
+ int{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{0}, 2ll, long{3}, short{1})),
+ long{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{0}, 3ll, long{1}, short{2})),
+ 3ll
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{0}, 1ll, long_c<2>)),
+ long{2}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ maximum(list(int{0}, long_c<1>, 2ll)),
+ 2ll
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // minimum (without a custom predicate)
+ //////////////////////////////////////////////////////////////////
+ {
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<6>{})),
+ ord<6>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<6>{}, ord<7>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<7>{}, ord<6>{})),
+ ord<6>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<6>{}, ord<7>{}, ord<8>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<7>{}, ord<6>{}, ord<8>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<7>{}, ord<8>{}, ord<6>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<8>{}, ord<7>{}, ord<6>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<8>{}, ord<6>{}, ord<7>{})),
+ ord<6>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<6>{}, ord<7>{}, ord<8>{}, ord<9>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<7>{}, ord<6>{}, ord<8>{}, ord<9>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<7>{}, ord<8>{}, ord<6>{}, ord<9>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<7>{}, ord<8>{}, ord<9>{}, ord<6>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<8>{}, ord<7>{}, ord<9>{}, ord<6>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<8>{}, ord<9>{}, ord<7>{}, ord<6>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<8>{}, ord<9>{}, ord<6>{}, ord<7>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<9>{}, ord<8>{}, ord<6>{}, ord<7>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<9>{}, ord<6>{}, ord<8>{}, ord<7>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<9>{}, ord<6>{}, ord<7>{}, ord<8>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<6>{}, ord<8>{}, ord<9>{}, ord<7>{})),
+ ord<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ minimum(list(ord<6>{}, ord<9>{}, ord<7>{}, ord<8>{})),
+ ord<6>{}
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{4})),
+ int{4}
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{4}, short{5})),
+ int{4}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{5}, short{4})),
+ short{4}
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{4}, short{5}, long{6})),
+ int{4}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{7}, short{6}, long{8})),
+ short{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{7}, short{8}, long{6})),
+ long{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{8}, short{7}, long{6})),
+ long{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{8}, short{6}, long{7})),
+ short{6}
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{6}, short{7}, long{8}, 9ll)),
+ int{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{7}, short{6}, long{8}, 9ll)),
+ short{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{7}, short{8}, long{6}, 9ll)),
+ long{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{7}, short{8}, long{9}, 6ll)),
+ 6ll
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{8}, short{7}, long{9}, 6ll)),
+ 6ll
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{8}, short{9}, long{7}, 6ll)),
+ 6ll
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{8}, short{9}, long{6}, 7ll)),
+ long{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{9}, short{8}, long{6}, 7ll)),
+ long{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{9}, short{6}, long{8}, 7ll)),
+ short{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{9}, short{6}, long{7}, 8ll)),
+ short{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{6}, short{8}, long{9}, 7ll)),
+ int{6}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{6}, short{9}, long{7}, 8ll)),
+ int{6}
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(int{3}, short{4}, long_c<5>)),
+ int{3}
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ minimum(list(ord<33>{}, short{45}, long{46})),
+ ord<33>{}
+ ));
+ }
+
+
+ //////////////////////////////////////////////////////////////////
+ // count_if
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(), id), size_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<1>), id), size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<0>), id), size_c<0>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<1>, char_c<1>), id), size_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<1>, char_c<0>), id), size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<0>, char_c<1>), id), size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<0>, char_c<0>), id), size_c<0>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<1>, char_c<1>, long_c<1>), id), size_c<3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<1>, char_c<1>, long_c<0>), id), size_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<1>, char_c<0>, long_c<1>), id), size_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<1>, char_c<0>, long_c<0>), id), size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<0>, char_c<1>, long_c<1>), id), size_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<0>, char_c<1>, long_c<0>), id), size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<0>, char_c<0>, long_c<1>), id), size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ count_if(list(int_c<0>, char_c<0>, long_c<0>), id), size_c<0>
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{1}), id), 1u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{0}), id), 0u
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{1}, char{1}), id), 2u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{1}, char{0}), id), 1u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{0}, char{1}), id), 1u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{0}, char{0}), id), 0u
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{1}, char{1}, double{1}), id), 3u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{1}, char{1}, double{0}), id), 2u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{1}, char{0}, double{1}), id), 2u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{1}, char{0}, double{0}), id), 1u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{0}, char{1}, double{1}), id), 2u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{0}, char{1}, double{0}), id), 1u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{0}, char{0}, double{1}), id), 1u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(int{0}, char{0}, double{0}), id), 0u
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_LAMBDA auto is_even = [](auto x) {
+ return x % 2 == 0;
+ };
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(), is_even), 0u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(1), is_even), 0u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(2), is_even), 1u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(1, 2), is_even), 1u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(1, 2, 3), is_even), 1u
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ count_if(list(1, 2, 3, 4), is_even), 2u
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // count
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::count(list(), undefined{}),
+ size_c<0>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::count(list(ct_eq<0>{}), undefined{}),
+ size_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::count(list(ct_eq<0>{}), ct_eq<0>{}),
+ size_c<1>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::count(list(ct_eq<0>{}, ct_eq<1>{}), undefined{}),
+ size_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::count(list(ct_eq<0>{}, ct_eq<1>{}), ct_eq<0>{}),
+ size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::count(list(ct_eq<0>{}, ct_eq<1>{}), ct_eq<1>{}),
+ size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::count(list(ct_eq<0>{}, ct_eq<0>{}), ct_eq<0>{}),
+ size_c<2>
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // product
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ product<integral_constant_tag<int>>(list()),
+ int_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ product<integral_constant_tag<int>>(list(int_c<2>)),
+ int_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ product<integral_constant_tag<int>>(list(int_c<2>, int_c<3>)),
+ int_c<2 * 3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ product<integral_constant_tag<int>>(list(int_c<2>, int_c<3>, int_c<4>)),
+ int_c<2 * 3 * 4>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ product<integral_constant_tag<int>>(list(int_c<2>, int_c<3>, int_c<4>, int_c<5>)),
+ int_c<2 * 3 * 4 * 5>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ product<integral_constant_tag<unsigned long>>(list()),
+ ulong_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ product<integral_constant_tag<unsigned long>>(list(ulong_c<2>, ulong_c<3>, ulong_c<4>)),
+ ulong_c<2 * 3 * 4>
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ product<int>(list(2)),
+ 2
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ product<int>(list(2, 3)),
+ 2 * 3
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ product<int>(list(2, 3, 4)),
+ 2 * 3 * 4
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ product<int>(list(2, 3, 4, 5)),
+ 2 * 3 * 4 * 5
+ ));
+
+
+ //////////////////////////////////////////////////////////////////
+ // sum
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ sum<integral_constant_tag<int>>(list()),
+ int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ sum<integral_constant_tag<int>>(list(int_c<1>)),
+ int_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ sum<integral_constant_tag<int>>(list(int_c<1>, int_c<2>)),
+ int_c<1 + 2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ sum<integral_constant_tag<int>>(list(int_c<1>, int_c<2>, int_c<3>)),
+ int_c<1 + 2 + 3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ sum<integral_constant_tag<int>>(list(int_c<1>, int_c<2>, int_c<3>, int_c<4>)),
+ int_c<1 + 2 + 3 + 4>
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ sum<integral_constant_tag<unsigned long>>(list()),
+ ulong_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ sum<integral_constant_tag<unsigned long>>(list(ulong_c<1>, ulong_c<2>, ulong_c<3>)),
+ ulong_c<1 + 2 + 3>
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ sum<int>(list(1)), 1
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ sum<int>(list(1, 2)), 1 + 2
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ sum<int>(list(1, 2, 3)), 1 + 2 + 3
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ sum<int>(list(1, 2, 3, 4)), 1 + 2 + 3 + 4
+ ));
+
+
+ //////////////////////////////////////////////////////////////////
+ // unpack
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ unpack(list(), f),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ unpack(list(x<0>{}), f),
+ f(x<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ unpack(list(x<0>{}, x<1>{}), f),
+ f(x<0>{}, x<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ unpack(list(x<0>{}, x<1>{}, x<2>{}), f),
+ f(x<0>{}, x<1>{}, x<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ unpack(list(x<0>{}, x<1>{}, x<2>{}, x<3>{}), f),
+ f(x<0>{}, x<1>{}, x<2>{}, x<3>{})
+ ));
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_FOLDABLE_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/functor.hpp b/src/boost/libs/hana/test/_include/laws/functor.hpp
new file mode 100644
index 00000000..d1ddbb4d
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/functor.hpp
@@ -0,0 +1,250 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_FUNCTOR_HPP
+#define BOOST_HANA_TEST_LAWS_FUNCTOR_HPP
+
+#include <boost/hana/adjust.hpp>
+#include <boost/hana/adjust_if.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/concept/functor.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/fill.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/replace.hpp>
+#include <boost/hana/replace_if.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename F, typename = when<true>>
+ struct TestFunctor : TestFunctor<F, laws> {
+ using TestFunctor<F, laws>::TestFunctor;
+ };
+
+ template <typename F>
+ struct TestFunctor<F, laws> {
+ template <typename Xs, typename Elements>
+ TestFunctor(Xs xs, Elements elements) {
+ hana::for_each(xs, hana::capture(elements)([](auto elements, auto x) {
+ static_assert(Functor<decltype(x)>{}, "");
+
+ test::_injection<0> f{};
+ test::_injection<1> g{};
+
+ // identity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::transform(x, id),
+ x
+ ));
+
+ // composition
+ BOOST_HANA_CHECK(hana::equal(
+ hana::transform(x, hana::compose(f, g)),
+ hana::transform(hana::transform(x, g), f)
+ ));
+
+ // method definitions in terms of transform/adjust_if
+ hana::for_each(elements, hana::capture(x, f, elements)(
+ [](auto x, auto f, auto elements, auto value) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::adjust(x, value, f),
+ hana::adjust_if(x, hana::equal.to(value), f)
+ ));
+
+ hana::for_each(elements, hana::capture(x, value)(
+ [](auto x, auto oldval, auto newval) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::replace(x, oldval, newval),
+ hana::replace_if(x, hana::equal.to(oldval), newval)
+ ));
+ }));
+ }));
+
+ auto pred = hana::always(true_c);
+ BOOST_HANA_CHECK(hana::equal(
+ hana::adjust_if(x, pred, f),
+ hana::transform(x, [=](auto z) {
+ return hana::eval_if(pred(z),
+ hana::make_lazy(f)(z),
+ hana::make_lazy(z)
+ );
+ })
+ ));
+
+ test::_constant<0> v{};
+ BOOST_HANA_CHECK(hana::equal(
+ hana::replace_if(x, pred, v),
+ hana::adjust_if(x, pred, hana::always(v))
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::fill(x, v),
+ hana::replace_if(x, hana::always(true_c), v)
+ ));
+
+ }));
+ }
+ };
+
+ template <typename S>
+ struct TestFunctor<S, when<Sequence<S>::value>>
+ : TestFunctor<S, laws>
+ {
+ struct undefined { };
+
+ template <typename Xs, typename Elements>
+ TestFunctor(Xs xs, Elements elements)
+ : TestFunctor<S, laws>{xs, elements}
+ {
+ using test::ct_eq;
+ using test::cx_eq;
+ constexpr auto list = make<S>;
+
+ //////////////////////////////////////////////////////////////////
+ // replace_if
+ //////////////////////////////////////////////////////////////////
+ {
+ auto a = ct_eq<888>{};
+ auto b = ct_eq<999>{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(), undefined{}, undefined{}),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(ct_eq<0>{}), equal.to(a), undefined{}),
+ list(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(a), equal.to(a), b),
+ list(b)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(ct_eq<0>{}, ct_eq<1>{}), equal.to(a), undefined{}),
+ list(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(a, ct_eq<1>{}), equal.to(a), b),
+ list(b, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(ct_eq<0>{}, a), equal.to(a), b),
+ list(ct_eq<0>{}, b)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(a, a), equal.to(a), b),
+ list(b, b)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), equal.to(a), undefined{}),
+ list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(a, ct_eq<1>{}, ct_eq<2>{}), equal.to(a), b),
+ list(b, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(ct_eq<0>{}, a, ct_eq<2>{}), equal.to(a), b),
+ list(ct_eq<0>{}, b, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(ct_eq<0>{}, ct_eq<1>{}, a), equal.to(a), b),
+ list(ct_eq<0>{}, ct_eq<1>{}, b)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(a, ct_eq<1>{}, a), equal.to(a), b),
+ list(b, ct_eq<1>{}, b)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(list(a, ct_eq<1>{}, a, ct_eq<3>{}, a), equal.to(a), b),
+ list(b, ct_eq<1>{}, b, ct_eq<3>{}, b)
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // replace
+ //////////////////////////////////////////////////////////////////
+ {
+ auto a = ct_eq<888>{};
+ auto b = ct_eq<999>{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(), undefined{}, undefined{}),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(ct_eq<0>{}), a, undefined{}),
+ list(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(a), a, b),
+ list(b)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(ct_eq<0>{}, ct_eq<1>{}), a, undefined{}),
+ list(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(a, ct_eq<1>{}), a, b),
+ list(b, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(ct_eq<0>{}, a), a, b),
+ list(ct_eq<0>{}, b)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(a, a), a, b),
+ list(b, b)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), a, undefined{}),
+ list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(a, ct_eq<1>{}, ct_eq<2>{}), a, b),
+ list(b, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(ct_eq<0>{}, a, ct_eq<2>{}), a, b),
+ list(ct_eq<0>{}, b, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(ct_eq<0>{}, ct_eq<1>{}, a), a, b),
+ list(ct_eq<0>{}, ct_eq<1>{}, b)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(a, ct_eq<1>{}, a), a, b),
+ list(b, ct_eq<1>{}, b)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace(list(a, ct_eq<1>{}, a, ct_eq<3>{}, a), a, b),
+ list(b, ct_eq<1>{}, b, ct_eq<3>{}, b)
+ ));
+ }
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_FUNCTOR_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/group.hpp b/src/boost/libs/hana/test/_include/laws/group.hpp
new file mode 100644
index 00000000..b9eeab77
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/group.hpp
@@ -0,0 +1,93 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_GROUP_HPP
+#define BOOST_HANA_TEST_LAWS_GROUP_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/concept/group.hpp>
+#include <boost/hana/lazy.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename G, typename = when<true>>
+ struct TestGroup : TestGroup<G, laws> {
+ using TestGroup<G, laws>::TestGroup;
+ };
+
+ template <typename G>
+ struct TestGroup<G, laws> {
+ template <typename Xs>
+ TestGroup(Xs xs) {
+ hana::for_each(xs, [](auto x) {
+ static_assert(Group<decltype(x)>{}, "");
+ });
+
+#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735
+ zero<G>(); // force adding zero<G>'s member function to pending temploid list
+#endif
+
+ foreach2(xs, [](auto x, auto y) {
+
+ // left inverse
+ BOOST_HANA_CHECK(hana::equal(
+ hana::plus(x, hana::negate(x)),
+ zero<G>()
+ ));
+
+ // right inverse
+ BOOST_HANA_CHECK(hana::equal(
+ hana::plus(hana::negate(x), x),
+ zero<G>()
+ ));
+
+ // default definition of minus
+ BOOST_HANA_CHECK(hana::equal(
+ hana::minus(x, y),
+ hana::plus(x, hana::negate(y))
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::minus(y, x),
+ hana::plus(y, hana::negate(x))
+ ));
+
+ // default definition of negate
+ BOOST_HANA_CHECK(hana::equal(
+ hana::negate(hana::negate(x)),
+ x
+ ));
+ });
+ }
+ };
+
+ template <typename C>
+ struct TestGroup<C, when<Constant<C>::value>>
+ : TestGroup<C, laws>
+ {
+ template <typename Xs>
+ TestGroup(Xs xs) : TestGroup<C, laws>{xs} {
+ foreach2(xs, [](auto x, auto y) {
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::negate(hana::value(x)),
+ hana::value(hana::negate(x))
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::minus(hana::value(x), hana::value(y)),
+ hana::value(hana::minus(x, y))
+ ));
+
+ });
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_GROUP_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/hashable.hpp b/src/boost/libs/hana/test/_include/laws/hashable.hpp
new file mode 100644
index 00000000..0fbd8f33
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/hashable.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_TEST_LAWS_HASHABLE_HPP
+#define BOOST_HANA_TEST_LAWS_HASHABLE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/hashable.hpp>
+#include <boost/hana/core/default.hpp>
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/hash.hpp>
+#include <boost/hana/if.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename G, typename = when<true>>
+ struct TestHashable : TestHashable<G, laws> {
+ using TestHashable<G, laws>::TestHashable;
+ };
+
+ template <typename H>
+ struct TestHashable<H, laws> {
+ template <typename Xs>
+ TestHashable(Xs xs) {
+ hana::for_each(xs, [](auto x) {
+ static_assert(Hashable<decltype(x)>{}, "");
+ });
+
+ hana::for_each(xs, [&](auto const& x) {
+ hana::for_each(xs, [&](auto const& y) {
+ using X = hana::tag_of_t<decltype(x)>;
+ using Y = hana::tag_of_t<decltype(y)>;
+ constexpr bool comparable = !hana::is_default<
+ hana::equal_impl<X, Y>
+ >::value;
+
+ hana::if_(hana::bool_c<comparable>,
+ [](auto const& x, auto const& y) {
+ BOOST_HANA_CHECK(
+ hana::equal(x, y)
+ ^implies^
+ hana::equal(hana::hash(x), hana::hash(y))
+ );
+ },
+ [](auto...) { }
+ )(x, y);
+ });
+ });
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_HASHABLE_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/iterable.hpp b/src/boost/libs/hana/test/_include/laws/iterable.hpp
new file mode 100644
index 00000000..d6d84c5e
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/iterable.hpp
@@ -0,0 +1,195 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_ITERABLE_HPP
+#define BOOST_HANA_TEST_LAWS_ITERABLE_HPP
+
+#include <boost/hana/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/concept/foldable.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename It, typename = hana::when<true>>
+ struct TestIterable : TestIterable<It, laws> {
+ using TestIterable<It, laws>::TestIterable;
+ };
+
+ template <typename It>
+ struct TestIterable<It, laws> {
+ template <typename Xs>
+ TestIterable(Xs xs) {
+ hana::for_each(xs, [](auto xs) {
+ static_assert(Iterable<decltype(xs)>{}, "");
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::is_empty(xs) ^iff^ hana::is_empty(hana::to<tuple_tag>(xs))
+ );
+
+ only_when_(hana::not_(hana::is_empty(xs)), hana::make_lazy([](auto xs) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::front(xs),
+ hana::front(hana::to<tuple_tag>(xs))
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::to<tuple_tag>(hana::drop_front_exactly(xs)),
+ hana::drop_front_exactly(hana::to<tuple_tag>(xs))
+ ));
+
+ // methods
+ // back(xs) == at(xs, length(xs)-1)
+ BOOST_HANA_CHECK(hana::equal(
+ hana::back(xs),
+ hana::at(xs, hana::minus(hana::length(xs), hana::size_c<1>))
+ ));
+
+ })(xs));
+
+ // drop_front(xs, 0) == xs
+ BOOST_HANA_CHECK(hana::equal(
+ hana::drop_front(xs, size_c<0>),
+ xs
+ ));
+
+ // at(xs, n) == front(drop_front(xs, n))
+ hana::for_each(hana::make_range(size_c<0>, hana::length(xs)),
+ hana::capture(xs)([](auto xs, auto n) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::at(xs, n),
+ hana::front(hana::drop_front(xs, n))
+ ));
+ }));
+
+ // Searchable
+ hana::eval_if(hana::is_empty(xs),
+ hana::make_lazy([](auto xs) {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::not_(hana::any_of(xs, hana::always(true_c)))
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(xs, hana::always(true_c)),
+ nothing
+ ));
+ })(xs),
+ hana::make_lazy([](auto xs) {
+ BOOST_HANA_CHECK(
+ hana::any_of(xs, hana::always(true_c))
+ );
+ BOOST_HANA_CHECK(
+ hana::not_(hana::any_of(xs, hana::always(false_c)))
+ );
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::find_if(xs, hana::always(true_c)),
+ hana::just(hana::front(xs))
+ ));
+ })(xs)
+ );
+
+ });
+ }
+ };
+
+ template <typename S>
+ struct TestIterable<S, when<Sequence<S>::value>>
+ : TestIterable<S, laws>
+ {
+ template <int i>
+ using x = ct_eq<i>;
+
+ template <int i = 0>
+ struct invalid { };
+
+ struct undefined { };
+
+ template <typename Xs>
+ TestIterable(Xs xs) : TestIterable<S, laws>{xs} {
+ constexpr auto list = make<S>;
+
+ //////////////////////////////////////////////////////////////////
+ // front
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ front(list(x<0>{})),
+ x<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ front(list(x<0>{}, invalid<>{})),
+ x<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ front(list(x<0>{}, invalid<1>{}, invalid<2>{})),
+ x<0>{}
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ front(list(1)), 1
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ front(list(1, '2')), 1
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ front(list(1, '2', 3.3)), 1
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // back
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ back(list(x<0>{})),
+ x<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ back(list(invalid<0>{}, x<1>{})),
+ x<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ back(list(invalid<0>{}, invalid<1>{}, x<2>{})),
+ x<2>{}
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ back(list(1)), 1
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ back(list(1, '2')), '2'
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ back(list(1, '2', 3.3)), 3.3
+ ));
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_ITERABLE_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/logical.hpp b/src/boost/libs/hana/test/_include/laws/logical.hpp
new file mode 100644
index 00000000..df993276
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/logical.hpp
@@ -0,0 +1,137 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_LOGICAL_HPP
+#define BOOST_HANA_TEST_LAWS_LOGICAL_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/concept/logical.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename L, typename = when<true>>
+ struct TestLogical : TestLogical<L, laws> {
+ using TestLogical<L, laws>::TestLogical;
+ };
+
+ template <typename L>
+ struct TestLogical<L, laws> {
+ template <typename Xs, typename Pred, typename F>
+ static void for_each_such_that(Xs xs, Pred pred, F f) {
+ hana::for_each(xs, [&pred, &f](auto x) {
+ hana::eval_if(pred(x),
+ hana::make_lazy(f)(x),
+ [](auto) { }
+ );
+ });
+ }
+
+ template <typename Xs>
+ TestLogical(Xs xs) {
+ hana::for_each(xs, [](auto x) {
+ static_assert(Logical<decltype(x)>{}, "");
+ });
+
+ foreach3(xs, hana::capture(xs)([](auto xs, auto a, auto b, auto c) {
+ auto true_valued = [](auto x) {
+ return hana::if_(x, true_c, false_c);
+ };
+ auto false_valued = [](auto x) {
+ return hana::if_(x, false_c, true_c);
+ };
+
+ // associativity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::or_(a, hana::or_(b, c)),
+ hana::or_(hana::or_(a, b), c)
+ ));
+ BOOST_HANA_CHECK(hana::equal(
+ hana::and_(a, hana::and_(b, c)),
+ hana::and_(hana::and_(a, b), c)
+ ));
+
+ // equivalence through commutativity
+ BOOST_HANA_CHECK(
+ hana::or_(a, b) ^iff^ hana::or_(b, a)
+ );
+ BOOST_HANA_CHECK(
+ hana::and_(a, b) ^iff^ hana::and_(b, a)
+ );
+
+ // absorption
+ BOOST_HANA_CHECK(hana::equal(
+ hana::or_(a, hana::and_(a, b)), a
+ ));
+ BOOST_HANA_CHECK(hana::equal(
+ hana::and_(a, hana::or_(a, b)), a
+ ));
+
+ // left identity
+ TestLogical::for_each_such_that(xs, true_valued,
+ hana::capture(a)([](auto a, auto t) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::and_(t, a), a
+ ));
+ }));
+ TestLogical::for_each_such_that(xs, false_valued,
+ hana::capture(a)([](auto a, auto f) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::or_(f, a), a
+ ));
+ }));
+
+ // distributivity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::or_(a, hana::and_(b, c)),
+ hana::and_(hana::or_(a, b), hana::or_(a, c))
+ ));
+ BOOST_HANA_CHECK(hana::equal(
+ hana::and_(a, hana::or_(b, c)),
+ hana::or_(hana::and_(a, b), hana::and_(a, c))
+ ));
+
+ // complements
+ BOOST_HANA_CHECK(true_valued(hana::or_(a, hana::not_(a))));
+ BOOST_HANA_CHECK(false_valued(hana::and_(a, hana::not_(a))));
+
+ }));
+ }
+ };
+
+ template <typename C>
+ struct TestLogical<C, when<Constant<C>::value>>
+ : TestLogical<C, laws>
+ {
+ template <typename Xs>
+ TestLogical(Xs xs) : TestLogical<C, laws>{xs} {
+ foreach2(xs, [](auto x, auto y) {
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value(hana::not_(x)),
+ hana::not_(hana::value(x))
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value(hana::and_(x, y)),
+ hana::and_(hana::value(x), hana::value(y))
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value(hana::or_(x, y)),
+ hana::or_(hana::value(x), hana::value(y))
+ ));
+
+ });
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_LOGICAL_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/monad.hpp b/src/boost/libs/hana/test/_include/laws/monad.hpp
new file mode 100644
index 00000000..25a23d41
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/monad.hpp
@@ -0,0 +1,222 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_MONAD_HPP
+#define BOOST_HANA_TEST_LAWS_MONAD_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/concept/monad.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/flatten.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/monadic_compose.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename M, typename = when<true>>
+ struct TestMonad : TestMonad<M, laws> {
+ using TestMonad<M, laws>::TestMonad;
+ };
+
+ template <typename M>
+ struct TestMonad<M, laws> {
+ // Xs are Monads over something
+ // XXs are Monads over Monads over something
+ template <typename Xs, typename XXs>
+ TestMonad(Xs xs, XXs xxs) {
+ hana::for_each(xs, [](auto m) {
+ static_assert(Monad<decltype(m)>{}, "");
+
+ auto f = hana::compose(lift<M>, test::_injection<0>{});
+ auto g = hana::compose(lift<M>, test::_injection<1>{});
+ auto h = hana::compose(lift<M>, test::_injection<2>{});
+ auto x = test::ct_eq<0>{};
+
+ //////////////////////////////////////////////////////////////
+ // Laws formulated with `monadic_compose`
+ //////////////////////////////////////////////////////////////
+ // associativity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::monadic_compose(h, hana::monadic_compose(g, f))(x),
+ hana::monadic_compose(hana::monadic_compose(h, g), f)(x)
+ ));
+
+ // left identity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::monadic_compose(lift<M>, f)(x),
+ f(x)
+ ));
+
+ // right identity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::monadic_compose(f, lift<M>)(x),
+ f(x)
+ ));
+
+ //////////////////////////////////////////////////////////////
+ // Laws formulated with `chain`
+ //
+ // This just provides us with some additional cross-checking,
+ // but the documentation does not mention those.
+ //////////////////////////////////////////////////////////////
+ BOOST_HANA_CHECK(hana::equal(
+ hana::chain(hana::lift<M>(x), f),
+ f(x)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::chain(m, lift<M>),
+ m
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::chain(m, [f, g](auto x) {
+ return hana::chain(f(x), g);
+ }),
+ hana::chain(hana::chain(m, f), g)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::transform(m, f),
+ hana::chain(m, hana::compose(lift<M>, f))
+ ));
+
+ //////////////////////////////////////////////////////////////
+ // Consistency of method definitions
+ //////////////////////////////////////////////////////////////
+ // consistency of `chain`
+ BOOST_HANA_CHECK(hana::equal(
+ hana::chain(m, f),
+ hana::flatten(hana::transform(m, f))
+ ));
+
+ // consistency of `monadic_compose`
+ BOOST_HANA_CHECK(hana::equal(
+ hana::monadic_compose(f, g)(x),
+ hana::chain(g(x), f)
+ ));
+ });
+
+ // consistency of `flatten`
+ hana::for_each(xxs, [](auto mm) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::flatten(mm),
+ hana::chain(mm, hana::id)
+ ));
+ });
+ }
+ };
+
+ template <typename S>
+ struct TestMonad<S, when<Sequence<S>::value>>
+ : TestMonad<S, laws>
+ {
+ template <typename Xs, typename XXs>
+ TestMonad(Xs xs, XXs xxs)
+ : TestMonad<S, laws>{xs, xxs}
+ {
+ constexpr auto list = make<S>;
+
+ //////////////////////////////////////////////////////////////////
+ // flatten
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(list(list(), list())),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(list(list(ct_eq<0>{}), list())),
+ list(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(list(list(), list(ct_eq<0>{}))),
+ list(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(list(list(ct_eq<0>{}), list(ct_eq<1>{}))),
+ list(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(list(
+ list(ct_eq<0>{}, ct_eq<1>{}),
+ list(),
+ list(ct_eq<2>{}, ct_eq<3>{}),
+ list(ct_eq<4>{})
+ )),
+ list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ ));
+
+ // just make sure we don't double move; this happened in hana::tuple
+ hana::flatten(list(list(Tracked{1}, Tracked{2})));
+
+ //////////////////////////////////////////////////////////////////
+ // chain
+ //////////////////////////////////////////////////////////////////
+ {
+ test::_injection<0> f{};
+ auto g = hana::compose(list, f);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(list(), g),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(list(ct_eq<1>{}), g),
+ list(f(ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(list(ct_eq<1>{}, ct_eq<2>{}), g),
+ list(f(ct_eq<1>{}), f(ct_eq<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(list(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), g),
+ list(f(ct_eq<1>{}), f(ct_eq<2>{}), f(ct_eq<3>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(list(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), g),
+ list(f(ct_eq<1>{}), f(ct_eq<2>{}), f(ct_eq<3>{}), f(ct_eq<4>{}))
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // monadic_compose
+ //////////////////////////////////////////////////////////////////
+ {
+ test::_injection<0> f{};
+ test::_injection<1> g{};
+
+ auto mf = [=](auto x) { return list(f(x), f(f(x))); };
+ auto mg = [=](auto x) { return list(g(x), g(g(x))); };
+
+ auto x = test::ct_eq<0>{};
+ BOOST_HANA_CHECK(hana::equal(
+ hana::monadic_compose(mf, mg)(x),
+ list(f(g(x)), f(f(g(x))), f(g(g(x))), f(f(g(g(x)))))
+ ));
+ }
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_MONAD_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/monad_plus.hpp b/src/boost/libs/hana/test/_include/laws/monad_plus.hpp
new file mode 100644
index 00000000..406320c9
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/monad_plus.hpp
@@ -0,0 +1,616 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_MONAD_PLUS_HPP
+#define BOOST_HANA_TEST_LAWS_MONAD_PLUS_HPP
+
+#include <boost/hana/append.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/concat.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/concept/monad_plus.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/cycle.hpp>
+#include <boost/hana/empty.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/filter.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/prefix.hpp>
+#include <boost/hana/prepend.hpp>
+#include <boost/hana/remove.hpp>
+#include <boost/hana/remove_if.hpp>
+#include <boost/hana/replicate.hpp>
+#include <boost/hana/suffix.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename M, typename = when<true>>
+ struct TestMonadPlus : TestMonadPlus<M, laws> {
+ using TestMonadPlus<M, laws>::TestMonadPlus;
+ };
+
+ template <typename M>
+ struct TestMonadPlus<M, laws> {
+ template <typename Xs, typename Predicates, typename Values>
+ TestMonadPlus(Xs xs, Predicates predicates, Values values) {
+#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735
+ empty<M>(); // force adding empty<M>'s member function to pending temploid list
+#endif
+
+ hana::for_each(xs, [](auto a) {
+ static_assert(MonadPlus<decltype(a)>{}, "");
+
+ // left identity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::concat(hana::empty<M>(), a),
+ a
+ ));
+
+ // right identity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::concat(a, hana::empty<M>()),
+ a
+ ));
+
+ // absorption
+ auto f = hana::compose(lift<M>, test::_injection<0>{});
+ BOOST_HANA_CHECK(hana::equal(
+ hana::chain(hana::empty<M>(), f),
+ hana::empty<M>()
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::chain(a, hana::always(hana::empty<M>())),
+ hana::empty<M>()
+ ));
+
+ });
+
+ // associativity
+ foreach3(xs, [](auto a, auto b, auto c) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::concat(a, hana::concat(b, c)),
+ hana::concat(hana::concat(a, b), c)
+ ));
+ });
+
+ // Default method definitions
+ hana::for_each(xs, hana::capture(predicates, values)(
+ [](auto predicates, auto values, auto x) {
+
+ // remove_if(x, pred) == filter(x, negated pred)
+ hana::for_each(predicates, hana::capture(x)([](auto x, auto pred) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::remove_if(x, pred),
+ hana::filter(x, hana::compose(hana::not_, pred))
+ ));
+ }));
+
+ // remove(x, value) == remove_if(x, equal.to(value))
+ hana::for_each(values, hana::capture(x)([](auto x, auto value) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::remove(x, value),
+ hana::remove_if(x, hana::equal.to(value))
+ ));
+ }));
+ }));
+ }
+ };
+
+ template <typename S>
+ struct TestMonadPlus<S, when<Sequence<S>::value>>
+ : TestMonadPlus<S, laws>
+ {
+ template <int i>
+ using eq = test::ct_eq<i>;
+
+ struct undefined { };
+
+ template <typename Xs, typename Predicates, typename Values>
+ TestMonadPlus(Xs xs, Predicates predicates, Values values)
+ : TestMonadPlus<S, laws>{xs, predicates, values}
+ {
+ auto z = eq<999>{};
+ constexpr auto list = make<S>;
+
+ //////////////////////////////////////////////////////////////////
+ // empty
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::empty<S>(), list()
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // concat
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(), list()),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(), list(eq<0>{})),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(), list(eq<0>{}, eq<1>{})),
+ list(eq<0>{}, eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(eq<0>{}), list()),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(eq<0>{}), list(eq<1>{})),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(eq<0>{}), list(eq<1>{}, eq<2>{})),
+ list(eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(eq<0>{}, eq<1>{}), list()),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(eq<0>{}, eq<1>{}), list(eq<2>{})),
+ list(eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(eq<0>{}, eq<1>{}), list(eq<2>{}, eq<3>{})),
+ list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{})
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ concat(list(), list()),
+ list()
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ concat(list(1), list()),
+ list(1)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ concat(list(), list(1)),
+ list(1)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ concat(list(1), list('2')),
+ list(1, '2')
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ concat(list(1, '2'), list(3.3)),
+ list(1, '2', 3.3)
+ ));
+
+
+ //////////////////////////////////////////////////////////////////
+ // filter
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(), undefined{}),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(z), not_equal.to(z)),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(eq<1>{}), not_equal.to(z)),
+ list(eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(eq<1>{}, eq<2>{}), not_equal.to(z)),
+ list(eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(z, eq<2>{}), not_equal.to(z)),
+ list(eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(eq<1>{}, z), not_equal.to(z)),
+ list(eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(z, eq<2>{}, eq<3>{}), not_equal.to(z)),
+ list(eq<2>{}, eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(eq<1>{}, z, eq<3>{}), not_equal.to(z)),
+ list(eq<1>{}, eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(eq<1>{}, eq<2>{}, z), not_equal.to(z)),
+ list(eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(eq<1>{}, z, z), not_equal.to(z)),
+ list(eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(z, eq<2>{}, z), not_equal.to(z)),
+ list(eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(z, z, eq<3>{}), not_equal.to(z)),
+ list(eq<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ filter(list(eq<1>{}, eq<2>{}, eq<3>{}, eq<4>{}, z), not_equal.to(z)),
+ list(eq<1>{}, eq<2>{}, eq<3>{}, eq<4>{})
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // prepend
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ prepend(list(), eq<0>{}),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ prepend(list(eq<1>{}), eq<0>{}),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ prepend(list(eq<1>{}, eq<2>{}), eq<0>{}),
+ list(eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ prepend(list(eq<1>{}, eq<2>{}, eq<3>{}), eq<0>{}),
+ list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{})
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ prepend(list(), 1),
+ list(1)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ prepend(list('2'), 1),
+ list(1, '2')
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ prepend(list('2', 3.3), 1),
+ list(1, '2', 3.3)
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // append
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ append(list(), eq<0>{}),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ append(list(eq<0>{}), eq<1>{}),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ append(list(eq<0>{}, eq<1>{}), eq<2>{}),
+ list(eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ append(list(), 1), list(1)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ append(list(1), '2'), list(1, '2')
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(equal(
+ append(list(1, '2'), 3.3), list(1, '2', 3.3)
+ ));
+
+
+ //////////////////////////////////////////////////////////////////
+ // cycle
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(), size_c<0>),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(), size_c<1>),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(), size_c<2>),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(), size_c<3>),
+ list()
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}), size_c<0>),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}), size_c<1>),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}), size_c<2>),
+ list(eq<0>{}, eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}), size_c<3>),
+ list(eq<0>{}, eq<0>{}, eq<0>{})
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}, eq<1>{}), size_c<0>),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}, eq<1>{}), size_c<1>),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}, eq<1>{}), size_c<2>),
+ list(eq<0>{}, eq<1>{}, eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}, eq<1>{}), size_c<3>),
+ list(eq<0>{}, eq<1>{}, eq<0>{}, eq<1>{}, eq<0>{}, eq<1>{})
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}, eq<1>{}, eq<2>{}), size_c<0>),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}, eq<1>{}, eq<2>{}), size_c<1>),
+ list(eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}, eq<1>{}, eq<2>{}), size_c<2>),
+ list(eq<0>{}, eq<1>{}, eq<2>{}, eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ cycle(list(eq<0>{}, eq<1>{}, eq<2>{}), size_c<3>),
+ list(eq<0>{}, eq<1>{}, eq<2>{}, eq<0>{}, eq<1>{}, eq<2>{}, eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // remove_if
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(), undefined{}),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(eq<0>{}), equal.to(z)),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(z), equal.to(z)),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(eq<0>{}, eq<1>{}), equal.to(z)),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(z, eq<1>{}), equal.to(z)),
+ list(eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(eq<0>{}, z), equal.to(z)),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(z, z), equal.to(z)),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(eq<0>{}, eq<1>{}, eq<2>{}), equal.to(z)),
+ list(eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(eq<0>{}, eq<1>{}, z), equal.to(z)),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(eq<0>{}, z, eq<2>{}), equal.to(z)),
+ list(eq<0>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(z, eq<1>{}, eq<2>{}), equal.to(z)),
+ list(eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(z, z, eq<2>{}), equal.to(z)),
+ list(eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(eq<0>{}, z, z), equal.to(z)),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ remove_if(list(z, z, z), equal.to(z)),
+ list()
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // remove
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(), undefined{}),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(eq<0>{}), z),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(z), z),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(eq<0>{}, eq<1>{}), z),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(z, eq<1>{}), z),
+ list(eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(eq<0>{}, z), z),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(z, z), z),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(eq<0>{}, eq<1>{}, eq<2>{}), z),
+ list(eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(eq<0>{}, eq<1>{}, z), z),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(eq<0>{}, z, eq<2>{}), z),
+ list(eq<0>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(z, eq<1>{}, eq<2>{}), z),
+ list(eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(z, z, eq<2>{}), z),
+ list(eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(eq<0>{}, z, z), z),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ hana::remove(list(z, z, z), z),
+ list()
+ ));
+
+ //////////////////////////////////////////////////////////////////
+ // replicate
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ replicate<S>(eq<0>{}, size_c<0>),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ replicate<S>(eq<0>{}, size_c<1>),
+ list(eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ replicate<S>(eq<0>{}, size_c<2>),
+ list(eq<0>{}, eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ replicate<S>(eq<0>{}, size_c<3>),
+ list(eq<0>{}, eq<0>{}, eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ replicate<S>(eq<0>{}, size_c<4>),
+ list(eq<0>{}, eq<0>{}, eq<0>{}, eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ replicate<S>(eq<0>{}, size_c<5>),
+ list(eq<0>{}, eq<0>{}, eq<0>{}, eq<0>{}, eq<0>{})
+ ));
+
+
+ //////////////////////////////////////////////////////////////////
+ // prefix
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ prefix(list(), z),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ prefix(list(eq<0>{}), z),
+ list(z, eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ prefix(list(eq<0>{}, eq<1>{}), z),
+ list(z, eq<0>{}, z, eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ prefix(list(eq<0>{}, eq<1>{}, eq<2>{}), z),
+ list(z, eq<0>{}, z, eq<1>{}, z, eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ prefix(list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}), z),
+ list(z, eq<0>{}, z, eq<1>{}, z, eq<2>{}, z, eq<3>{})
+ ));
+
+
+ //////////////////////////////////////////////////////////////////
+ // suffix
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ suffix(list(), z),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ suffix(list(eq<0>{}), z),
+ list(eq<0>{}, z)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ suffix(list(eq<0>{}, eq<1>{}), z),
+ list(eq<0>{}, z, eq<1>{}, z)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ suffix(list(eq<0>{}, eq<1>{}, eq<2>{}), z),
+ list(eq<0>{}, z, eq<1>{}, z, eq<2>{}, z)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ suffix(list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}), z),
+ list(eq<0>{}, z, eq<1>{}, z, eq<2>{}, z, eq<3>{}, z)
+ ));
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_MONAD_PLUS_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/monoid.hpp b/src/boost/libs/hana/test/_include/laws/monoid.hpp
new file mode 100644
index 00000000..d500992a
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/monoid.hpp
@@ -0,0 +1,86 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_MONOID_HPP
+#define BOOST_HANA_TEST_LAWS_MONOID_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/concept/monoid.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename M, typename = when<true>>
+ struct TestMonoid : TestMonoid<M, laws> {
+ using TestMonoid<M, laws>::TestMonoid;
+ };
+
+ template <typename M>
+ struct TestMonoid<M, laws> {
+ template <typename Xs>
+ TestMonoid(Xs xs) {
+#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735
+ zero<M>(); // force adding zero<M>'s member function to pending temploid list
+#endif
+
+ hana::for_each(xs, hana::capture(xs)([](auto xs, auto a) {
+ static_assert(Monoid<decltype(a)>{}, "");
+
+ // left identity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::plus(zero<M>(), a),
+ a
+ ));
+
+ // right identity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::plus(a, zero<M>()),
+ a
+ ));
+
+ hana::for_each(xs,
+ hana::capture(xs, a)([](auto xs, auto a, auto b) {
+ hana::for_each(xs,
+ hana::capture(a, b)([](auto a, auto b, auto c) {
+ // associativity
+ BOOST_HANA_CHECK(equal(
+ hana::plus(a, hana::plus(b, c)),
+ hana::plus(hana::plus(a, b), c)
+ ));
+ }));
+ }));
+
+ }));
+ }
+ };
+
+ template <typename C>
+ struct TestMonoid<C, when<Constant<C>::value>>
+ : TestMonoid<C, laws>
+ {
+ template <typename Xs>
+ TestMonoid(Xs xs) : TestMonoid<C, laws>{xs} {
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value(zero<C>()),
+ zero<typename C::value_type>()
+ ));
+
+ foreach2(xs, [](auto x, auto y) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::plus(hana::value(x), hana::value(y)),
+ hana::value(hana::plus(x, y))
+ ));
+ });
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_MONOID_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/orderable.hpp b/src/boost/libs/hana/test/_include/laws/orderable.hpp
new file mode 100644
index 00000000..f49ea7f8
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/orderable.hpp
@@ -0,0 +1,182 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_ORDERABLE_HPP
+#define BOOST_HANA_TEST_LAWS_ORDERABLE_HPP
+
+#include <boost/hana/and.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/constant.hpp>
+#include <boost/hana/concept/orderable.hpp>
+#include <boost/hana/concept/product.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/greater_equal.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/less_equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/or.hpp>
+#include <boost/hana/ordering.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/value.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename T, typename = when<true>>
+ struct TestOrderable : TestOrderable<T, laws> {
+ using TestOrderable<T, laws>::TestOrderable;
+ };
+
+ template <typename T>
+ struct TestOrderable<T, laws> {
+ template <typename Xs>
+ TestOrderable(Xs xs) {
+ hana::for_each(xs, [](auto x) {
+ static_assert(Orderable<decltype(x)>{}, "");
+ });
+
+ foreach2(xs, [](auto a, auto b) {
+
+ // antisymmetry
+ BOOST_HANA_CHECK(
+ hana::and_(hana::less_equal(a, b), hana::less_equal(b, a))
+ ^implies^ hana::equal(a, b)
+ );
+
+ // totality
+ BOOST_HANA_CHECK(
+ hana::or_(hana::less_equal(a, b), hana::less_equal(b, a))
+ );
+
+ // other methods in terms of `less_equal`
+ BOOST_HANA_CHECK(
+ hana::less(a, b) ^iff^ hana::not_(hana::less_equal(b, a))
+ );
+
+ BOOST_HANA_CHECK(
+ hana::greater(a, b) ^iff^ hana::less(b, a)
+ );
+
+ BOOST_HANA_CHECK(
+ hana::greater_equal(a, b) ^iff^ hana::not_(hana::less(a, b))
+ );
+
+ // less.than & al.
+ BOOST_HANA_CHECK(hana::less.than(a)(b) ^iff^ hana::less(b, a));
+ BOOST_HANA_CHECK(hana::greater.than(a)(b) ^iff^ hana::greater(b, a));
+ BOOST_HANA_CHECK(hana::less_equal.than(a)(b) ^iff^ hana::less_equal(b, a));
+ BOOST_HANA_CHECK(hana::greater_equal.than(a)(b) ^iff^ hana::greater_equal(b, a));
+
+ // ordering
+ _injection<0> f{}; // test::_injection is also monotonic
+ BOOST_HANA_CHECK(
+ hana::ordering(f)(a, b) ^iff^ hana::less(f(a), f(b))
+ );
+ });
+
+ // transitivity
+ foreach3(xs, [](auto a, auto b, auto c) {
+ BOOST_HANA_CHECK(
+ hana::and_(hana::less_equal(a, b), hana::less_equal(b, c))
+ ^implies^ hana::less_equal(a, c)
+ );
+ });
+ }
+ };
+
+ template <typename C>
+ struct TestOrderable<C, when<Constant<C>::value>>
+ : TestOrderable<C, laws>
+ {
+ template <typename Xs>
+ TestOrderable(Xs xs) : TestOrderable<C, laws>{xs} {
+ foreach2(xs, [](auto a, auto b) {
+
+ BOOST_HANA_CHECK(
+ hana::value(hana::less(a, b)) ^iff^
+ hana::less(hana::value(a), hana::value(b))
+ );
+
+ });
+ }
+ };
+
+ template <typename P>
+ struct TestOrderable<P, when<Product<P>::value>>
+ : TestOrderable<P, laws>
+ {
+ template <typename Products>
+ TestOrderable(Products products)
+ : TestOrderable<P, laws>{products}
+ {
+ foreach2(products, [](auto x, auto y) {
+ BOOST_HANA_CHECK(
+ hana::less(x, y) ^iff^
+ hana::or_(
+ hana::less(hana::first(x), hana::first(y)),
+ hana::and_(
+ hana::equal(hana::first(x), hana::first(y)),
+ hana::less(hana::second(x), hana::second(y))
+ )
+ )
+ );
+ });
+ }
+ };
+
+ template <typename S>
+ struct TestOrderable<S, when<Sequence<S>::value>>
+ : TestOrderable<S, laws>
+ {
+ struct invalid { };
+
+ template <typename Xs>
+ TestOrderable(Xs xs) : TestOrderable<S, laws>{xs} {
+ constexpr auto list = make<S>;
+
+ //////////////////////////////////////////////////////////////////
+ // less
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ list(),
+ list()
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ list(),
+ list(invalid{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ list(invalid{}),
+ list()
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ list(ct_ord<0>{}),
+ list(ct_ord<7>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ list(ct_ord<1>{}),
+ list(ct_ord<0>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ list(ct_ord<0>{}, ct_ord<1>{}, ct_ord<8>{}),
+ list(ct_ord<0>{}, ct_ord<1>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ list(ct_ord<0>{}, ct_ord<0>{}, ct_ord<8>{}),
+ list(ct_ord<0>{}, ct_ord<1>{})
+ ));
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_ORDERABLE_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/product.hpp b/src/boost/libs/hana/test/_include/laws/product.hpp
new file mode 100644
index 00000000..18e5a15d
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/product.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_LAWS_PRODUCT_HPP
+#define BOOST_HANA_TEST_LAWS_PRODUCT_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/product.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/second.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename P, typename = when<true>>
+ struct TestProduct : TestProduct<P, laws> {
+ using TestProduct<P, laws>::TestProduct;
+ };
+
+ template <typename P>
+ struct TestProduct<P, laws> {
+ template <typename Elements>
+ TestProduct(Elements elements) {
+ foreach2(elements, [](auto x, auto y) {
+ static_assert(Product<decltype(hana::make<P>(x, y))>{}, "");
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::first(hana::make<P>(x, y)),
+ x
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::second(hana::make<P>(x, y)),
+ y
+ ));
+ });
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_PRODUCT_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/ring.hpp b/src/boost/libs/hana/test/_include/laws/ring.hpp
new file mode 100644
index 00000000..4afbca05
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/ring.hpp
@@ -0,0 +1,125 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_RING_HPP
+#define BOOST_HANA_TEST_LAWS_RING_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/concept/constant.hpp>
+#include <boost/hana/concept/monoid.hpp>
+#include <boost/hana/concept/ring.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/one.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/power.hpp>
+#include <boost/hana/value.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename R, typename = when<true>>
+ struct TestRing : TestRing<R, laws> {
+ using TestRing<R, laws>::TestRing;
+ };
+
+ template <typename R>
+ struct TestRing<R, laws> {
+ template <typename Xs>
+ TestRing(Xs xs) {
+#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735
+ one<R>(); // force adding one<R>'s member function to pending temploid list
+#endif
+
+ hana::for_each(xs, hana::capture(xs)([](auto xs, auto x) {
+ static_assert(Ring<decltype(x)>{}, "");
+
+ foreach2(xs, hana::capture(x)([](auto x, auto y, auto z) {
+ // associativity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::mult(x, hana::mult(y, z)),
+ hana::mult(hana::mult(x, y), z)
+ ));
+
+ // distributivity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::mult(x, hana::plus(y, z)),
+ hana::plus(hana::mult(x, y), hana::mult(x, z))
+ ));
+ }));
+
+ // right identity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::mult(x, one<R>()), x
+ ));
+
+ // left identity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::mult(one<R>(), x), x
+ ));
+
+ // power
+ BOOST_HANA_CHECK(hana::equal(
+ hana::power(x, int_c<0>),
+ one<R>()
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::power(x, int_c<1>),
+ x
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::power(x, int_c<2>),
+ hana::mult(x, x)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::power(x, int_c<3>),
+ hana::mult(hana::mult(x, x), x)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::power(x, int_c<4>),
+ hana::mult(hana::mult(hana::mult(x, x), x), x)
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::power(x, int_c<5>),
+ hana::mult(hana::mult(hana::mult(hana::mult(x, x), x), x), x)
+ ));
+
+ }));
+ }
+ };
+
+ template <typename C>
+ struct TestRing<C, when<Constant<C>::value>>
+ : TestRing<C, laws>
+ {
+ template <typename Xs>
+ TestRing(Xs xs) : TestRing<C, laws>{xs} {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value(one<C>()),
+ one<typename C::value_type>()
+ ));
+
+ foreach2(xs, [](auto x, auto y) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::mult(hana::value(x), hana::value(y)),
+ hana::value(hana::mult(x, y))
+ ));
+ });
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_RING_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/searchable.hpp b/src/boost/libs/hana/test/_include/laws/searchable.hpp
new file mode 100644
index 00000000..ae55b06e
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/searchable.hpp
@@ -0,0 +1,611 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_SEARCHABLE_HPP
+#define BOOST_HANA_TEST_LAWS_SEARCHABLE_HPP
+
+#include <boost/hana/all.hpp>
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/any.hpp>
+#include <boost/hana/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concat.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/concept/searchable.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/core/is_a.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/is_disjoint.hpp>
+#include <boost/hana/is_subset.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/none.hpp>
+#include <boost/hana/none_of.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <support/numeric.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename S, typename = when<true>>
+ struct TestSearchable : TestSearchable<S, laws> {
+ using TestSearchable<S, laws>::TestSearchable;
+ };
+
+ template <typename S>
+ struct TestSearchable<S, laws> {
+ template <typename Searchables, typename Keys>
+ TestSearchable(Searchables searchables, Keys keys) {
+ hana::for_each(searchables, [](auto xs) {
+ static_assert(Searchable<decltype(xs)>{}, "");
+ });
+
+ auto predicates = hana::concat(
+ hana::to_tuple(hana::transform(keys, equal.to)),
+ hana::make_tuple(
+ hana::always(false_c),
+ hana::always(true_c)
+ )
+ );
+
+ hana::for_each(searchables, hana::capture(searchables, keys, predicates)(
+ [](auto searchables, auto keys, auto predicates, auto xs) {
+ hana::for_each(predicates, hana::capture(xs)(
+ [](auto xs, auto p) {
+ // any_of(xs, p) <=> !all_of(xs, negated p)
+ // <=> !none_of(xs, p)
+ BOOST_HANA_CHECK(
+ hana::any_of(xs, p) ^iff^
+ hana::not_(hana::all_of(xs, hana::compose(not_, p)))
+ );
+
+ BOOST_HANA_CHECK(
+ hana::any_of(xs, p) ^iff^
+ hana::not_(hana::none_of(xs, p))
+ );
+ }));
+
+ // any(xs) <=> any_of(xs, id)
+ // all(xs) <=> all_of(xs, id)
+ // none(xs) <=> none_of(xs, id)
+ auto all_logicals = hana::all_of(xs, [](auto x) {
+ return hana::bool_c<hana::Logical<decltype(x)>::value>;
+ });
+ only_when_(all_logicals, hana::make_lazy([](auto xs) {
+ BOOST_HANA_CHECK(
+ hana::any(xs) ^iff^ hana::any_of(xs, id)
+ );
+
+ BOOST_HANA_CHECK(
+ hana::all(xs) ^iff^ hana::all_of(xs, hana::id)
+ );
+
+ BOOST_HANA_CHECK(
+ hana::none(xs) ^iff^ hana::none_of(xs, hana::id)
+ );
+ })(xs));
+
+ // find_if(xs, always(false_c)) == nothing
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(xs, hana::always(hana::false_c)),
+ hana::nothing
+ ));
+
+ hana::for_each(searchables, hana::capture(xs)([](auto xs, auto ys) {
+ // is_subset(xs, ys) <=> all_of(xs, [](auto x) { return contains(ys, x); })
+ BOOST_HANA_CHECK(
+ hana::is_subset(xs, ys) ^iff^
+ hana::all_of(xs, hana::partial(hana::contains, ys))
+ );
+
+ // is_disjoint(xs, ys) <=> none_of(xs, [](auto x) { return contains(ys, x); })
+ BOOST_HANA_CHECK(
+ hana::is_disjoint(xs, ys) ^iff^
+ hana::none_of(xs, hana::partial(hana::contains, ys))
+ );
+ }));
+
+ hana::for_each(keys, hana::capture(xs)([](auto xs, auto key) {
+ // find(xs, x) == find_if(xs, [](auto y) { return y == x; })
+ BOOST_HANA_CHECK(hana::equal(
+ hana::find(xs, key),
+ hana::find_if(xs, hana::equal.to(key))
+ ));
+
+ // contains(xs, x) <=> any_of(xs, [](auto y) { return y == x; })
+ BOOST_HANA_CHECK(
+ hana::contains(xs, key) ^iff^
+ hana::any_of(xs, hana::equal.to(key))
+ );
+
+ only_when_(hana::contains(xs, key),
+ hana::make_lazy([](auto xs, auto key) {
+ // at_key(xs, key) == find(xs, key).value()
+ BOOST_HANA_CHECK(hana::equal(
+ hana::at_key(xs, key),
+ hana::find(xs, key).value()
+ ));
+ })(xs, key)
+ );
+ }));
+ }));
+ }
+ };
+
+ template <typename S>
+ struct TestSearchable<S, when<Sequence<S>::value>>
+ : TestSearchable<S, laws>
+ {
+ template <int i>
+ using x = _constant<i>;
+
+ template <int = 0>
+ struct invalid { };
+
+ struct undefined { };
+
+ template <typename Xs, typename Keys>
+ TestSearchable(Xs xs, Keys keys)
+ : TestSearchable<S, laws>{xs, keys}
+ {
+ constexpr auto list = make<S>;
+
+ BOOST_HANA_CONSTEXPR_LAMBDA auto is_even = [](auto x) {
+ return x % 2 == 0;
+ };
+
+ auto c = numeric; // a minimal comparable
+ auto logical = numeric;
+
+ //////////////////////////////////////////////////////////////////
+ // any_of
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::not_(hana::any_of(list(), equal.to(x<9>{})))
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::not_(hana::any_of(list(x<0>{}), equal.to(x<9>{})))
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(list(x<0>{}), equal.to(x<0>{}))
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(list(x<0>{}, invalid<1>{}), equal.to(x<0>{}))
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(list(x<0>{}, invalid<1>{}, invalid<2>{}), equal.to(x<0>{}))
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::not_(hana::any_of(list(x<0>{}, x<1>{}), equal.to(x<9>{})))
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(list(x<0>{}, x<1>{}), equal.to(x<1>{}))
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(list(x<0>{}, x<1>{}, invalid<2>{}), equal.to(x<1>{}))
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(list(x<0>{}, x<1>{}, invalid<2>{}, invalid<3>{}), equal.to(x<1>{}))
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::not_(hana::any_of(list(x<0>{}, x<1>{}, x<2>{}), equal.to(x<9>{})))
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(list(x<0>{}, x<1>{}, x<2>{}), equal.to(x<2>{}))
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(list(x<0>{}, x<1>{}, x<2>{}, nothing), equal.to(x<2>{}))
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::any_of(list(x<0>{}, x<1>{}, x<2>{}, nothing, nothing), equal.to(x<2>{}))
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::not_(hana::any_of(list(), invalid<>{}))
+ );
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::any_of(list(c(0)), equal.to(c(0)))
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::not_(hana::any_of(list(c(0)), equal.to(c(1))))
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::not_(hana::any_of(list(1), is_even))
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::any_of(list(2), is_even)
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::any_of(list(1, 2), is_even)
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::not_(hana::any_of(list(1, 3), is_even))
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(
+ hana::any_of(list(1, 3, 4), is_even)
+ );
+
+ //////////////////////////////////////////////////////////////////
+ // any
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any(list())));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::any(list(logical(true))));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::any(list(logical(false)))));
+
+
+ //////////////////////////////////////////////////////////////////
+ // all_of
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(
+ all_of(list(), invalid<>{})
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(
+ all_of(list(c(0)), equal.to(c(0)))
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(
+ not_(all_of(list(c(0)), equal.to(c(1))))
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(not_(
+ all_of(list(c(0), c(1)), equal.to(c(0)))
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(
+ all_of(list(c(0), c(0)), equal.to(c(0)))
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(not_(all_of(list(1), is_even)));
+ BOOST_HANA_CONSTEXPR_CHECK(all_of(list(2), is_even));
+ BOOST_HANA_CONSTEXPR_CHECK(all_of(list(2, 4), is_even));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(all_of(list(1, 2), is_even)));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(all_of(list(1, 3), is_even)));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(all_of(list(1, 3, 4), is_even)));
+
+
+ //////////////////////////////////////////////////////////////////
+ // all
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(all(list()));
+ BOOST_HANA_CONSTEXPR_CHECK(all(list(logical(true))));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(all(list(logical(false)))));
+ BOOST_HANA_CONSTEXPR_CHECK(all(list(logical(true), logical(true))));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(all(list(logical(true), logical(false)))));
+
+ //////////////////////////////////////////////////////////////////
+ // none_of
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(none_of(list(), invalid<>{}));
+ BOOST_HANA_CONSTEXPR_CHECK(none_of(list(c(0)), equal.to(c(1))));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(none_of(list(c(0)), equal.to(c(0)))));
+
+ BOOST_HANA_CONSTEXPR_CHECK(none_of(list(1), is_even));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(none_of(list(2), is_even)));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(none_of(list(1, 2), is_even)));
+ BOOST_HANA_CONSTEXPR_CHECK(none_of(list(1, 3), is_even));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(none_of(list(1, 3, 4), is_even)));
+
+
+ //////////////////////////////////////////////////////////////////
+ // none
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(none(list()));
+ BOOST_HANA_CONSTEXPR_CHECK(none(list(logical(false))));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(none(list(logical(true)))));
+
+ //////////////////////////////////////////////////////////////////
+ // find_if
+ //////////////////////////////////////////////////////////////////
+ {
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(), equal.to(x<9>{})),
+ nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}), equal.to(x<9>{})),
+ nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}), equal.to(x<0>{})),
+ just(x<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, invalid<1>{}), equal.to(x<0>{})),
+ just(x<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, invalid<1>{}, invalid<2>{}), equal.to(x<0>{})),
+ just(x<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, x<1>{}), equal.to(x<9>{})),
+ nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, x<1>{}), equal.to(x<1>{})),
+ just(x<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, x<1>{}, invalid<2>{}), equal.to(x<1>{})),
+ just(x<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, x<1>{}, invalid<2>{}, invalid<3>{}), equal.to(x<1>{})),
+ just(x<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, x<1>{}, x<2>{}), equal.to(x<9>{})),
+ nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, x<1>{}, x<2>{}), equal.to(x<2>{})),
+ just(x<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, x<1>{}, x<2>{}, nothing), equal.to(x<2>{})),
+ just(x<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(list(x<0>{}, x<1>{}, x<2>{}, nothing, nothing), equal.to(x<2>{})),
+ just(x<2>{})
+ ));
+
+ // Make sure find_if works with an lvalue sequence. hana::tuple
+ // used to have a bug that broke this.
+ auto const const_lvalue = list(x<0>{}, x<1>{}, x<2>{});
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(const_lvalue, equal.to(x<1>{})),
+ just(x<1>{})
+ ));
+
+ auto lvalue = list(x<0>{}, x<1>{}, x<2>{});
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find_if(lvalue, equal.to(x<1>{})),
+ just(x<1>{})
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // find
+ //////////////////////////////////////////////////////////////////
+ {
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(), invalid<>{}),
+ nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}), x<9>{}),
+ nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}), x<0>{}),
+ just(x<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, invalid<1>{}), x<0>{}),
+ just(x<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, invalid<1>{}, invalid<2>{}), x<0>{}),
+ just(x<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, x<1>{}), x<9>{}),
+ nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, x<1>{}), x<1>{}),
+ just(x<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, x<1>{}, invalid<2>{}), x<1>{}),
+ just(x<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, x<1>{}, invalid<2>{}, invalid<3>{}), x<1>{}),
+ just(x<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, x<1>{}, x<2>{}), x<9>{}),
+ nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, x<1>{}, x<2>{}), x<2>{}),
+ just(x<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, x<1>{}, x<2>{}, nothing), x<2>{}),
+ just(x<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ find(list(x<0>{}, x<1>{}, x<2>{}, nothing, nothing), x<2>{}),
+ just(x<2>{})
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // at_key
+ //////////////////////////////////////////////////////////////////
+ {
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ at_key(list(x<0>{}), x<0>{}),
+ x<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ at_key(list(x<0>{}, x<1>{}), x<0>{}),
+ x<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ at_key(list(x<0>{}, x<1>{}), x<1>{}),
+ x<1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ at_key(list(x<0>{}, x<1>{}, x<2>{}), x<0>{}),
+ x<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ at_key(list(x<0>{}, x<1>{}, x<2>{}), x<1>{}),
+ x<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ at_key(list(x<0>{}, x<1>{}, x<2>{}), x<2>{}),
+ x<2>{}
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // contains
+ //////////////////////////////////////////////////////////////////
+ {
+ BOOST_HANA_CONSTANT_CHECK(not_(
+ contains(list(), undefined{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(not_(
+ contains(list(x<0>{}), x<999>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(
+ contains(list(x<0>{}), x<0>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ contains(list(x<0>{}, x<1>{}), x<1>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ contains(list(x<0>{}, x<1>{}, x<3>{}), x<3>{})
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(contains(list(c(0)), c(0)));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(contains(list(c(0)), c(1))));
+
+ // infix application
+ BOOST_HANA_CONSTANT_CHECK(
+ list(x<0>{}, x<1>{}) ^contains^ x<1>{}
+ );
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // in
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTEXPR_CHECK(c(0) ^in^ list(c(0)));
+ BOOST_HANA_CONSTEXPR_CHECK(not_(c(1) ^in^ list(c(0))));
+
+ //////////////////////////////////////////////////////////////////
+ // is_subset
+ //////////////////////////////////////////////////////////////////
+ {
+ BOOST_HANA_CONSTANT_CHECK(is_subset(
+ list(), list(undefined{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(not_(is_subset(
+ list(undefined{}), list()
+ )));
+
+ BOOST_HANA_CONSTEXPR_CHECK(is_subset(
+ list(c(0)), list(c(0))
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(is_subset(
+ list(c(0)), list(c(0), c(1))
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(not_(is_subset(
+ list(c(0)), list(c(1))
+ )));
+
+ // infix application
+ BOOST_HANA_CONSTANT_CHECK(
+ list(x<0>{}) ^is_subset^ list(x<1>{}, x<0>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ list(x<0>{}, x<1>{}) ^is_subset^ list(x<1>{}, x<0>{})
+ );
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // is_disjoint
+ //////////////////////////////////////////////////////////////////
+ {
+ BOOST_HANA_CONSTANT_CHECK(is_disjoint(
+ list(),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(is_disjoint(
+ list(),
+ list(undefined{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(is_disjoint(
+ list(undefined{}),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(is_disjoint(
+ list(x<0>{}),
+ list(x<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(is_disjoint(
+ list(x<1>{}),
+ list(x<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint(
+ list(x<0>{}),
+ list(x<0>{})
+ )));
+
+
+ BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint(
+ list(x<0>{}, x<1>{}),
+ list(x<0>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint(
+ list(x<0>{}),
+ list(x<0>{}, x<1>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint(
+ list(x<1>{}, x<0>{}),
+ list(x<0>{}, x<1>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint(
+ list(x<0>{}, x<1>{}),
+ list(x<1>{}, x<2>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(is_disjoint(
+ list(x<0>{}, x<1>{}),
+ list(x<2>{}, x<3>{})
+ ));
+ }
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_SEARCHABLE_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/sequence.hpp b/src/boost/libs/hana/test/_include/laws/sequence.hpp
new file mode 100644
index 00000000..cc04590e
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/sequence.hpp
@@ -0,0 +1,133 @@
+// Copyright Louis Dionne 2013-2017
+// 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_TEST_LAWS_SEQUENCE_HPP
+#define BOOST_HANA_TEST_LAWS_SEQUENCE_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+#include <support/seq.hpp>
+
+#include <type_traits>
+#include <vector>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename S, typename = when<true>>
+ struct TestSequence : TestSequence<S, laws> {
+ using TestSequence<S, laws>::TestSequence;
+ };
+
+ template <typename S>
+ struct TestSequence<S, laws> {
+ template <int i>
+ using eq = integer<i,
+ Policy::Comparable
+ | Policy::Constant
+ >;
+
+ template <int i>
+ using cx_eq = integer<i,
+ Policy::Comparable
+ | Policy::Constexpr
+ >;
+
+ template <int i>
+ using ord = integer<i,
+ Policy::Orderable
+ | Policy::Constant
+ >;
+
+ struct undefined { };
+
+ TestSequence() {
+ constexpr auto list = make<S>; (void)list;
+ constexpr auto foldable = ::seq; (void)foldable;
+
+ //////////////////////////////////////////////////////////////////
+ // Check for Sequence<...>
+ //////////////////////////////////////////////////////////////////
+ static_assert(Sequence<decltype(list())>{}, "");
+ static_assert(Sequence<decltype(list(1))>{}, "");
+ static_assert(Sequence<decltype(list(1, '2'))>{}, "");
+ static_assert(Sequence<decltype(list(1, '2', 3.4))>{}, "");
+
+ //////////////////////////////////////////////////////////////////
+ // Check for basic tag consistency
+ //////////////////////////////////////////////////////////////////
+ struct Random;
+ static_assert(std::is_same<tag_of_t<decltype(list())>, S>{}, "");
+ static_assert(std::is_same<tag_of_t<decltype(list(1))>, S>{}, "");
+ static_assert(std::is_same<tag_of_t<decltype(list(1, '2'))>, S>{}, "");
+ static_assert(std::is_same<tag_of_t<decltype(list(1, '2', 3.3))>, S>{}, "");
+ static_assert(!std::is_same<tag_of_t<Random>, S>{}, "");
+
+ //////////////////////////////////////////////////////////////////
+ // Foldable -> Sequence conversion
+ //////////////////////////////////////////////////////////////////
+ {
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ to<S>(foldable()),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ to<S>(foldable(eq<0>{})),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ to<S>(foldable(eq<0>{}, eq<1>{})),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ to<S>(foldable(eq<0>{}, eq<1>{}, eq<2>{})),
+ list(eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ to<S>(foldable(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{})),
+ list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{})
+ ));
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // make (tautological given our definition of `list`)
+ //////////////////////////////////////////////////////////////////
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ make<S>(),
+ list()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ make<S>(eq<0>{}),
+ list(eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ make<S>(eq<0>{}, eq<1>{}),
+ list(eq<0>{}, eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ make<S>(eq<0>{}, eq<1>{}, eq<2>{}),
+ list(eq<0>{}, eq<1>{}, eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(equal(
+ make<S>(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}),
+ list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{})
+ ));
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_SEQUENCE_HPP
diff --git a/src/boost/libs/hana/test/_include/laws/templates/seq.hpp b/src/boost/libs/hana/test/_include/laws/templates/seq.hpp
new file mode 100644
index 00000000..72438fc5
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/templates/seq.hpp
@@ -0,0 +1,132 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/functional/always.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/applicative.hpp>
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/functor.hpp>
+#include <laws/iterable.hpp>
+#include <laws/monad.hpp>
+#include <laws/monad_plus.hpp>
+#include <laws/orderable.hpp>
+#include <laws/searchable.hpp>
+#include <laws/sequence.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+using hana::test::ct_ord;
+
+
+int main() {
+ auto eqs = hana::make_tuple(
+ ::seq()
+ , ::seq(ct_eq<0>{})
+ , ::seq(ct_eq<0>{}, ct_eq<1>{})
+ , ::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , ::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ );
+ (void)eqs;
+
+ auto nested_eqs = hana::make_tuple(
+ ::seq()
+ , ::seq(
+ ::seq(ct_eq<0>{}))
+ , ::seq(
+ ::seq(ct_eq<0>{}),
+ ::seq(ct_eq<1>{}, ct_eq<2>{}))
+ , ::seq(
+ ::seq(ct_eq<0>{}),
+ ::seq(ct_eq<1>{}, ct_eq<2>{}),
+ ::seq(ct_eq<3>{}, ct_eq<4>{}))
+ );
+ (void)nested_eqs;
+
+ auto eq_keys = hana::make_tuple(ct_eq<0>{}, ct_eq<3>{}, ct_eq<10>{});
+ (void)eq_keys;
+
+ auto predicates = hana::make_tuple(
+ hana::equal.to(ct_eq<0>{}), hana::equal.to(ct_eq<3>{}), hana::equal.to(ct_eq<10>{}),
+ hana::always(hana::true_c), hana::always(hana::false_c)
+ );
+ (void)predicates;
+
+ auto ords = hana::make_tuple(
+ ::seq()
+ , ::seq(ct_ord<0>{})
+ , ::seq(ct_ord<0>{}, ct_ord<1>{})
+ , ::seq(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{})
+ , ::seq(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, ct_ord<3>{})
+ );
+ (void)ords;
+
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable, Orderable
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_ORDERABLE
+ hana::test::TestComparable<::Seq>{eqs};
+ hana::test::TestOrderable<::Seq>{ords};
+#endif
+
+#ifdef BOOST_HANA_TEST_ITERABLE
+ //////////////////////////////////////////////////////////////////////////
+ // Foldable
+ //////////////////////////////////////////////////////////////////////////
+ hana::test::TestFoldable<::Seq>{eqs};
+
+ //////////////////////////////////////////////////////////////////////////
+ // Iterable
+ //////////////////////////////////////////////////////////////////////////
+ {
+ hana::test::TestIterable<::Seq>{eqs};
+ }
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Searchable
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_SEARCHABLE
+ {
+ hana::test::TestSearchable<::Seq>{eqs, eq_keys};
+
+ auto bools = hana::make_tuple(
+ ::seq(hana::true_c)
+ , ::seq(hana::false_c)
+ , ::seq(hana::true_c, hana::true_c)
+ , ::seq(hana::true_c, hana::false_c)
+ , ::seq(hana::false_c, hana::true_c)
+ , ::seq(hana::false_c, hana::false_c)
+ );
+ hana::test::TestSearchable<::Seq>{bools, hana::make_tuple(hana::true_c, hana::false_c)};
+ }
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Functor, Applicative, Monad
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_MONAD
+ hana::test::TestFunctor<::Seq>{eqs, eq_keys};
+ hana::test::TestApplicative<::Seq>{eqs};
+ hana::test::TestMonad<::Seq>{eqs, nested_eqs};
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // MonadPlus
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_MONAD_PLUS
+ hana::test::TestMonadPlus<::Seq>{eqs, predicates, eq_keys};
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sequence
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_SEQUENCE
+ hana::test::TestSequence<::Seq>{};
+#endif
+}
diff --git a/src/boost/libs/hana/test/_include/support/cnumeric.hpp b/src/boost/libs/hana/test/_include/support/cnumeric.hpp
new file mode 100644
index 00000000..51575a40
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/cnumeric.hpp
@@ -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)
+
+#ifndef TEST_SUPPORT_CNUMERIC_HPP
+#define TEST_SUPPORT_CNUMERIC_HPP
+
+#include <boost/hana/concept/integral_constant.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/fwd/core/to.hpp>
+#include <boost/hana/fwd/equal.hpp>
+#include <boost/hana/fwd/less.hpp>
+
+
+template <typename T>
+struct CNumeric { using value_type = T; };
+
+template <typename T, T v>
+struct cnumeric_t {
+ static constexpr T value = v;
+ using hana_tag = CNumeric<T>;
+ constexpr operator T() const { return value; }
+};
+
+template <typename T, T v>
+constexpr cnumeric_t<T, v> cnumeric{};
+
+template <typename T, T v>
+constexpr cnumeric_t<T, v> make_cnumeric() { return {}; }
+
+namespace boost { namespace hana {
+ // Constant and IntegralConstant
+ template <typename T>
+ struct IntegralConstant<CNumeric<T>> {
+ static constexpr bool value = true;
+ };
+
+ template <typename T, typename C>
+ struct to_impl<CNumeric<T>, C, when<
+ hana::IntegralConstant<C>::value
+ >>
+ : embedding<is_embedded<typename C::value_type, T>::value>
+ {
+ template <typename N>
+ static constexpr auto apply(N const&)
+ { return cnumeric<T, N::value>; }
+ };
+
+ // Comparable
+ template <typename T, typename U>
+ struct equal_impl<CNumeric<T>, CNumeric<U>> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X const&, Y const&)
+ { return cnumeric<bool, X::value == Y::value>; }
+ };
+
+ // Orderable
+ template <typename T, typename U>
+ struct less_impl<CNumeric<T>, CNumeric<U>> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X const&, Y const&)
+ { return cnumeric<bool, (X::value < Y::value)>; }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_CNUMERIC_HPP
diff --git a/src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp b/src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp
new file mode 100644
index 00000000..bdc234af
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp
@@ -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)
+
+#ifndef TEST_SUPPORT_CONSTEXPR_MOVE_ONLY_HPP
+#define TEST_SUPPORT_CONSTEXPR_MOVE_ONLY_HPP
+
+#include <boost/hana/bool.hpp>
+#include <boost/hana/fwd/hash.hpp>
+#include <boost/hana/type.hpp>
+
+#include <utility>
+
+
+// A move-only type that's also a literal type. It is also Comparable and
+// Hashable so it can be used in associative containers.
+template <int i>
+struct ConstexprMoveOnly {
+ constexpr ConstexprMoveOnly() { }
+ constexpr ConstexprMoveOnly(ConstexprMoveOnly const&) = delete;
+ constexpr ConstexprMoveOnly& operator=(ConstexprMoveOnly const&) = delete;
+ constexpr ConstexprMoveOnly(ConstexprMoveOnly&&) { }
+};
+
+template <int i, int j>
+constexpr auto operator==(ConstexprMoveOnly<i> const&, ConstexprMoveOnly<j> const&)
+{ return boost::hana::bool_c<i == j>; }
+
+template <int i, int j>
+constexpr auto operator!=(ConstexprMoveOnly<i> const&, ConstexprMoveOnly<j> const&)
+{ return boost::hana::bool_c<i != j>; }
+
+namespace boost { namespace hana {
+ template <int i>
+ struct hash_impl<ConstexprMoveOnly<i>> {
+ static constexpr auto apply(ConstexprMoveOnly<i> const&)
+ { return hana::type_c<ConstexprMoveOnly<i>>; };
+ };
+}}
+
+#endif // !TEST_SUPPORT_CONSTEXPR_MOVE_ONLY_HPP
diff --git a/src/boost/libs/hana/test/_include/support/counter.hpp b/src/boost/libs/hana/test/_include/support/counter.hpp
new file mode 100644
index 00000000..4640363d
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/counter.hpp
@@ -0,0 +1,56 @@
+// 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)
+
+#ifndef TEST_SUPPORT_COUNTER_HPP
+#define TEST_SUPPORT_COUNTER_HPP
+
+#include <boost/hana/fwd/at.hpp>
+#include <boost/hana/fwd/concept/iterable.hpp>
+#include <boost/hana/fwd/drop_front.hpp>
+#include <boost/hana/fwd/is_empty.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+
+// Counter - an infinite iterable for the masses
+
+struct Counter_tag { };
+
+template <std::size_t N = 0>
+struct Counter {
+ using hana_tag = Counter_tag;
+ static constexpr std::size_t value = N;
+};
+
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Iterable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct at_impl<Counter_tag> {
+ template <typename T, typename N>
+ static constexpr decltype(auto) apply(T, N) {
+ return hana::size_c<T::value + N::value>;
+ }
+ };
+
+ template <>
+ struct drop_front_impl<Counter_tag> {
+ template <typename T, typename N>
+ static constexpr auto apply(T, N) {
+ return Counter<T::value + N::value>{};
+ }
+ };
+
+ template <>
+ struct is_empty_impl<Counter_tag> {
+ template <typename Xs>
+ static constexpr auto apply(Xs)
+ -> hana::false_
+ { return {}; }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_COUNTER_HPP
diff --git a/src/boost/libs/hana/test/_include/support/equivalence_class.hpp b/src/boost/libs/hana/test/_include/support/equivalence_class.hpp
new file mode 100644
index 00000000..c5e8d72e
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/equivalence_class.hpp
@@ -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)
+
+#ifndef TEST_SUPPORT_EQUIVALENCE_CLASS_HPP
+#define TEST_SUPPORT_EQUIVALENCE_CLASS_HPP
+
+#include <boost/hana/fwd/equal.hpp>
+
+
+struct EquivalenceClass { };
+
+template <typename Token, typename T>
+struct equivalence_class_impl {
+ Token equivalence_class;
+ T unwrap;
+ using hana_tag = EquivalenceClass;
+};
+
+template <typename Token, typename X>
+constexpr equivalence_class_impl<Token, X> equivalence_class(Token token, X x) {
+ return {token, x};
+}
+
+namespace boost { namespace hana {
+ template <>
+ struct equal_impl<EquivalenceClass, EquivalenceClass> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return hana::equal(x.equivalence_class, y.equivalence_class); }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_EQUIVALENCE_CLASS_HPP
diff --git a/src/boost/libs/hana/test/_include/support/identity.hpp b/src/boost/libs/hana/test/_include/support/identity.hpp
new file mode 100644
index 00000000..c6799cbe
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/identity.hpp
@@ -0,0 +1,159 @@
+// Copyright Louis Dionne 2013-2017
+// 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 TEST_SUPPORT_IDENTITY_HPP
+#define TEST_SUPPORT_IDENTITY_HPP
+
+#include <boost/hana/chain.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/fwd/adjust_if.hpp>
+#include <boost/hana/fwd/ap.hpp>
+#include <boost/hana/fwd/equal.hpp>
+#include <boost/hana/fwd/flatten.hpp>
+#include <boost/hana/fwd/less.hpp>
+#include <boost/hana/fwd/lift.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <type_traits>
+
+
+struct Identity;
+
+template <typename T>
+struct identity_t {
+ T value;
+ using hana_tag = Identity;
+};
+
+struct make_identity {
+ template <typename T>
+ constexpr identity_t<typename std::decay<T>::type> operator()(T&& t) const {
+ return {static_cast<T&&>(t)};
+ }
+};
+
+constexpr make_identity identity{};
+
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct equal_impl<Identity, Identity> {
+ template <typename Id1, typename Id2>
+ static constexpr auto apply(Id1 x, Id2 y)
+ { return hana::equal(x.value, y.value); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Orderable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct less_impl<Identity, Identity> {
+ template <typename Id1, typename Id2>
+ static constexpr auto apply(Id1 x, Id2 y)
+ { return hana::less(x.value, y.value); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Functor
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD
+ // BOOST_HANA_TEST_FUNCTOR_ADJUST_MCD_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD
+ template <>
+ struct transform_impl<Identity> {
+ template <typename Id, typename F>
+ static constexpr auto apply(Id self, F f)
+ { return ::identity(f(self.value)); }
+ };
+#else
+ template <>
+ struct adjust_if_impl<Identity> {
+ struct get_value {
+ template <typename T>
+ constexpr auto operator()(T t) const { return t.value; }
+ };
+
+ template <typename Id, typename P, typename F>
+ static constexpr auto apply(Id self, P p, F f) {
+ auto x = hana::eval_if(p(self.value),
+ hana::make_lazy(hana::compose(f, get_value{}))(self),
+ hana::make_lazy(get_value{})(self)
+ );
+ return ::identity(x);
+ }
+ };
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Applicative
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_APPLICATIVE_FULL_MCD
+ // BOOST_HANA_TEST_APPLICATIVE_MONAD_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct lift_impl<Identity> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return ::identity(x); }
+ };
+#ifdef BOOST_HANA_TEST_APPLICATIVE_FULL_MCD
+ template <>
+ struct ap_impl<Identity> {
+ template <typename F, typename X>
+ static constexpr auto apply(F f, X x)
+ { return ::identity(f.value(x.value)); }
+ };
+#else
+ template <>
+ struct ap_impl<Identity> {
+ template <typename F, typename X>
+ static constexpr decltype(auto) apply(F&& f, X&& x) {
+ return hana::chain(
+ static_cast<F&&>(f),
+ hana::partial(hana::transform, static_cast<X&&>(x))
+ );
+ }
+ };
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Monad
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_MONAD_FLATTEN_MCD
+ // BOOST_HANA_TEST_MONAD_CHAIN_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_MONAD_FLATTEN_MCD
+ template <>
+ struct flatten_impl<Identity> {
+ template <typename Id>
+ static constexpr auto apply(Id self)
+ { return self.value; }
+ };
+#else
+ template <>
+ struct chain_impl<Identity> {
+ template <typename X, typename F>
+ static constexpr auto apply(X x, F f)
+ { return f(x.value); }
+ };
+#endif
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_IDENTITY_HPP
diff --git a/src/boost/libs/hana/test/_include/support/minimal_product.hpp b/src/boost/libs/hana/test/_include/support/minimal_product.hpp
new file mode 100644
index 00000000..1fe39f78
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/minimal_product.hpp
@@ -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)
+
+#ifndef TEST_SUPPORT_MINIMAL_PRODUCT_HPP
+#define TEST_SUPPORT_MINIMAL_PRODUCT_HPP
+
+#include <boost/hana/fwd/core/make.hpp>
+#include <boost/hana/fwd/first.hpp>
+#include <boost/hana/fwd/second.hpp>
+
+#include <type_traits>
+
+
+struct MinimalProduct;
+
+template <typename X, typename Y>
+struct product_t {
+ X fst;
+ Y snd;
+ using hana_tag = MinimalProduct;
+};
+
+struct make_minimal_product {
+ template <typename T, typename U>
+ constexpr product_t<typename std::decay<T>::type,
+ typename std::decay<U>::type>
+ operator()(T&& t, U&& u) const {
+ return {static_cast<T&&>(t), static_cast<U&&>(u)};
+ }
+};
+
+constexpr make_minimal_product minimal_product{};
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Product
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct make_impl<MinimalProduct> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return ::minimal_product(x, y); }
+ };
+
+ template <>
+ struct first_impl<MinimalProduct> {
+ template <typename P>
+ static constexpr decltype(auto) apply(P&& p)
+ { return p.fst; }
+ };
+
+ template <>
+ struct second_impl<MinimalProduct> {
+ template <typename P>
+ static constexpr decltype(auto) apply(P&& p)
+ { return p.snd; }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_MINIMAL_PRODUCT_HPP
diff --git a/src/boost/libs/hana/test/_include/support/numeric.hpp b/src/boost/libs/hana/test/_include/support/numeric.hpp
new file mode 100644
index 00000000..2aebe766
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/numeric.hpp
@@ -0,0 +1,175 @@
+// Copyright Louis Dionne 2013-2017
+// 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 TEST_SUPPORT_NUMERIC_HPP
+#define TEST_SUPPORT_NUMERIC_HPP
+
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/eval.hpp>
+#include <boost/hana/fwd/div.hpp>
+#include <boost/hana/fwd/equal.hpp>
+#include <boost/hana/fwd/eval_if.hpp>
+#include <boost/hana/fwd/less.hpp>
+#include <boost/hana/fwd/minus.hpp>
+#include <boost/hana/fwd/mod.hpp>
+#include <boost/hana/fwd/mult.hpp>
+#include <boost/hana/fwd/negate.hpp>
+#include <boost/hana/fwd/not.hpp>
+#include <boost/hana/fwd/one.hpp>
+#include <boost/hana/fwd/plus.hpp>
+#include <boost/hana/fwd/while.hpp>
+#include <boost/hana/fwd/zero.hpp>
+
+
+struct numeric_type {
+ constexpr explicit numeric_type(int v) : value(v) { }
+ int value;
+ constexpr operator int() const { return value; }
+};
+
+using Numeric = boost::hana::tag_of_t<numeric_type>;
+
+struct numeric_t {
+ constexpr numeric_type operator()(int x) const {
+ return numeric_type{x};
+ }
+};
+constexpr numeric_t numeric{};
+
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct equal_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value == y.value); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Orderable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct less_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y) {
+ // Workaround a _weird_ GCC bug:
+ // error: parse error in template argument list
+ // bool cmp = (x.value < y.value);
+ // ^
+ int xv = x.value, yv = y.value;
+ return numeric(xv < yv);
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Logical
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct eval_if_impl<Numeric> {
+ template <typename C, typename T, typename E>
+ static constexpr auto apply(C const& c, T&& t, E&& e) {
+ return c.value ? hana::eval(static_cast<T&&>(t))
+ : hana::eval(static_cast<E&&>(e));
+ }
+ };
+
+ template <>
+ struct not_impl<Numeric> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return numeric(!x.value); }
+ };
+
+ template <>
+ struct while_impl<Numeric> {
+ template <typename Pred, typename State, typename F>
+ static constexpr auto apply(Pred pred, State state, F f)
+ -> decltype(true ? f(state) : state)
+ {
+ if (pred(state))
+ return hana::while_(pred, f(state), f);
+ else
+ return state;
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Monoid
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct plus_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value + y.value); }
+ };
+
+ template <>
+ struct zero_impl<Numeric> {
+ static constexpr auto apply()
+ { return numeric(0); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Group
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_GROUP_NEGATE_MCD
+ // BOOST_HANA_TEST_GROUP_MINUS_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+#if defined(BOOST_HANA_TEST_GROUP_NEGATE_MCD)
+ template <>
+ struct negate_impl<Numeric> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return numeric(-x.value); }
+ };
+#else
+ template <>
+ struct minus_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value - y.value); }
+ };
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Ring
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct mult_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value * y.value); }
+ };
+
+ template <>
+ struct one_impl<Numeric> {
+ static constexpr auto apply()
+ { return numeric(1); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // EuclideanRing
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct div_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value / y.value); }
+ };
+
+ template <>
+ struct mod_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value % y.value); }
+ };
+}} // end namespace boost::hana
+
+#endif //! TEST_SUPPORT_NUMERIC_HPP
diff --git a/src/boost/libs/hana/test/_include/support/seq.hpp b/src/boost/libs/hana/test/_include/support/seq.hpp
new file mode 100644
index 00000000..ee222dc0
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/seq.hpp
@@ -0,0 +1,122 @@
+// Copyright Louis Dionne 2013-2017
+// 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 TEST_SUPPORT_SEQ_HPP
+#define TEST_SUPPORT_SEQ_HPP
+
+#include <boost/hana/fwd/at.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/fold_left.hpp>
+#include <boost/hana/fwd/is_empty.hpp>
+#include <boost/hana/fwd/length.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+
+
+struct Seq;
+
+template <typename Storage>
+struct seq_type {
+ explicit constexpr seq_type(Storage s) : storage(s) { }
+ Storage storage;
+ using hana_tag = Seq;
+};
+
+struct seq_t {
+ template <typename ...Xs>
+ constexpr auto operator()(Xs&& ...xs) const {
+ auto storage = boost::hana::make_tuple(xs...);
+ return seq_type<decltype(storage)>(storage);
+ }
+};
+constexpr seq_t seq{};
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Foldable
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+ // BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD
+ // BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+ template <>
+ struct fold_left_impl<Seq> {
+ template <typename Xs, typename S, typename F>
+ static constexpr auto apply(Xs xs, S s, F f) {
+ return hana::fold_left(xs.storage, s, f);
+ }
+
+ template <typename Xs, typename F>
+ static constexpr auto apply(Xs xs, F f) {
+ return hana::fold_left(xs.storage, f);
+ }
+ };
+#elif defined(BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD)
+ template <>
+ struct length_impl<Seq> {
+ template <typename Xs>
+ static constexpr auto apply(Xs const& xs) {
+ return hana::length(xs.storage);
+ }
+ };
+#else
+ template <>
+ struct unpack_impl<Seq> {
+ template <typename Xs, typename F>
+ static constexpr auto apply(Xs xs, F f)
+ { return hana::unpack(xs.storage, f); }
+ };
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Iterable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct at_impl<Seq> {
+ template <typename Xs, typename N>
+ static constexpr decltype(auto) apply(Xs&& xs, N&& n) {
+ return hana::at(static_cast<Xs&&>(xs).storage, n);
+ }
+ };
+
+ template <>
+ struct drop_front_impl<Seq> {
+ template <typename Xs, typename N>
+ static constexpr auto apply(Xs xs, N n) {
+ return hana::unpack(hana::drop_front(xs.storage, n), ::seq);
+ }
+ };
+
+ template <>
+ struct is_empty_impl<Seq> {
+ template <typename Xs>
+ static constexpr auto apply(Xs xs) {
+ return hana::is_empty(xs.storage);
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sequence
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct Sequence<Seq> {
+ static constexpr bool value = true;
+ };
+
+ template <>
+ struct make_impl<Seq> {
+ template <typename ...Xs>
+ static constexpr auto apply(Xs&& ...xs) {
+ return ::seq(static_cast<Xs&&>(xs)...);
+ }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_SEQ_HPP
diff --git a/src/boost/libs/hana/test/_include/support/tracked.hpp b/src/boost/libs/hana/test/_include/support/tracked.hpp
new file mode 100644
index 00000000..215ffba4
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/tracked.hpp
@@ -0,0 +1,120 @@
+// Copyright Louis Dionne 2013-2017
+// 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 TEST_SUPPORT_TRACKED_HPP
+#define TEST_SUPPORT_TRACKED_HPP
+
+// Define this if you want Tracked objects to print information to stderr.
+// #define TRACKED_PRINT_STUFF
+
+#include <boost/hana/assert.hpp>
+
+#ifdef TRACKED_PRINT_STUFF
+# include <iostream>
+#endif
+
+#include <iosfwd>
+
+
+struct Tracked {
+ enum class State { CONSTRUCTED, MOVED_FROM, DESTROYED };
+
+ int value;
+ State state;
+
+ explicit Tracked(int k) : value{k}, state{State::CONSTRUCTED} {
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "constructing " << *this << '\n';
+#endif
+ }
+
+ Tracked(Tracked const& t) : value{t.value}, state{State::CONSTRUCTED} {
+ BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM &&
+ "copying a moved-from object");
+
+ BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED &&
+ "copying a destroyed object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "copying " << *this << '\n';
+#endif
+ }
+
+ Tracked(Tracked&& t) : value{t.value}, state{State::CONSTRUCTED} {
+ BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM &&
+ "double moving from an object");
+
+ BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED &&
+ "moving from a destroyed object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "moving " << t << '\n';
+#endif
+ t.state = State::MOVED_FROM;
+ }
+
+ Tracked& operator=(Tracked const& other) {
+ BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED &&
+ "assigning to a destroyed object");
+
+ BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM &&
+ "assigning a moved-from object");
+
+ BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED &&
+ "assigning a destroyed object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "assigning " << other << " to " << *this << '\n';
+#endif
+ this->value = other.value;
+ return *this;
+ }
+
+ Tracked& operator=(Tracked&& other) {
+ BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED &&
+ "assigning to a destroyed object");
+
+ BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM &&
+ "double-moving from an object");
+
+ BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED &&
+ "assigning a destroyed object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "assigning " << other << " to " << *this << '\n';
+#endif
+ this->value = other.value;
+ other.state = State::MOVED_FROM;
+ return *this;
+ }
+
+ ~Tracked() {
+ BOOST_HANA_RUNTIME_CHECK(state != State::DESTROYED &&
+ "double-destroying an object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "destructing " << *this << '\n';
+#endif
+ state = State::DESTROYED;
+ }
+
+ template <typename CharT, typename Traits>
+ friend std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os, Tracked const& t) {
+ os << "Tracked{" << t.value << "}";
+ switch (t.state) {
+ case State::CONSTRUCTED:
+ os << "[ok]"; break;
+ case State::MOVED_FROM:
+ os << "[moved from]"; break;
+ case State::DESTROYED:
+ os << "[destroyed]"; break;
+ default:
+ BOOST_HANA_RUNTIME_CHECK(false && "never reached");
+ }
+ return os;
+ }
+};
+
+#endif // !TEST_SUPPORT_TRACKED_HPP
diff --git a/src/boost/libs/hana/test/_include/support/tracked_move_only.hpp b/src/boost/libs/hana/test/_include/support/tracked_move_only.hpp
new file mode 100644
index 00000000..03e9d5da
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/tracked_move_only.hpp
@@ -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)
+
+#ifndef TEST_SUPPORT_TRACKED_MOVE_ONLY_HPP
+#define TEST_SUPPORT_TRACKED_MOVE_ONLY_HPP
+
+#include <boost/hana/bool.hpp>
+#include <boost/hana/fwd/hash.hpp>
+#include <boost/hana/type.hpp>
+
+#include <support/tracked.hpp>
+
+#include <utility>
+
+
+// A move-only type that's Tracked. It is also Comparable and Hashable so it
+// can be used in associative containers.
+template <int i>
+struct TrackedMoveOnly : Tracked {
+ TrackedMoveOnly() : Tracked(i) { }
+ TrackedMoveOnly(TrackedMoveOnly const&) = delete;
+ TrackedMoveOnly& operator=(TrackedMoveOnly const&) = delete;
+ TrackedMoveOnly(TrackedMoveOnly&& x)
+ : Tracked(std::move(x))
+ { }
+};
+
+template <int i, int j>
+constexpr auto operator==(TrackedMoveOnly<i> const&, TrackedMoveOnly<j> const&)
+{ return boost::hana::bool_c<i == j>; }
+
+template <int i, int j>
+constexpr auto operator!=(TrackedMoveOnly<i> const&, TrackedMoveOnly<j> const&)
+{ return boost::hana::bool_c<i != j>; }
+
+namespace boost { namespace hana {
+ template <int i>
+ struct hash_impl<TrackedMoveOnly<i>> {
+ static constexpr auto apply(TrackedMoveOnly<i> const&)
+ { return hana::type_c<TrackedMoveOnly<i>>; };
+ };
+}}
+
+#endif // !TEST_SUPPORT_TRACKED_MOVE_ONLY_HPP
diff --git a/src/boost/libs/hana/test/assert/commas.cpp b/src/boost/libs/hana/test/assert/commas.cpp
new file mode 100644
index 00000000..0027c480
--- /dev/null
+++ b/src/boost/libs/hana/test/assert/commas.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 <support/cnumeric.hpp>
+namespace hana = boost::hana;
+
+
+// This test makes sure that we can use conditions with multiple comma-separated
+// arguments to the non-MSG versions of the BOOST_HANA_XXX_ASSERT macros.
+
+template <bool value, typename ...>
+bool runtime_bool() { return value; }
+
+template <bool value, typename ...>
+auto constant_bool() { return make_cnumeric<bool, value>(); }
+
+int main() {
+ BOOST_HANA_CONSTANT_ASSERT(constant_bool<true, void>());
+ BOOST_HANA_CONSTANT_ASSERT(constant_bool<true, void, void>());
+ BOOST_HANA_CONSTANT_ASSERT(constant_bool<true, void, void, void>());
+
+ BOOST_HANA_RUNTIME_ASSERT(runtime_bool<true, void>());
+ BOOST_HANA_RUNTIME_ASSERT(runtime_bool<true, void, void>());
+ BOOST_HANA_RUNTIME_ASSERT(runtime_bool<true, void, void, void>());
+
+ BOOST_HANA_ASSERT(runtime_bool<true, void>());
+ BOOST_HANA_ASSERT(runtime_bool<true, void, void>());
+ BOOST_HANA_ASSERT(runtime_bool<true, void, void, void>());
+ BOOST_HANA_ASSERT(constant_bool<true, void>());
+ BOOST_HANA_ASSERT(constant_bool<true, void, void>());
+ BOOST_HANA_ASSERT(constant_bool<true, void, void, void>());
+}
diff --git a/src/boost/libs/hana/test/assert/constant.cpp b/src/boost/libs/hana/test/assert/constant.cpp
new file mode 100644
index 00000000..3eca58c1
--- /dev/null
+++ b/src/boost/libs/hana/test/assert/constant.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 <support/cnumeric.hpp>
+namespace hana = boost::hana;
+
+
+template <bool value>
+auto constant_bool() { return make_cnumeric<bool, value>(); }
+
+template <bool value>
+constexpr auto constexpr_constant_bool() { return make_cnumeric<bool, value>(); }
+
+
+// Make sure it works at global scope
+BOOST_HANA_CONSTANT_ASSERT(constant_bool<true>());
+BOOST_HANA_CONSTANT_ASSERT_MSG(constant_bool<true>(), "message");
+
+// Make sure it works at namespace scope
+namespace ns {
+ BOOST_HANA_CONSTANT_ASSERT(constant_bool<true>());
+ BOOST_HANA_CONSTANT_ASSERT_MSG(constant_bool<true>(), "message");
+}
+
+// Make sure it works in a constexpr context
+constexpr bool constexpr_context() {
+ BOOST_HANA_CONSTANT_ASSERT(constexpr_constant_bool<true>());
+ BOOST_HANA_CONSTANT_ASSERT_MSG(constexpr_constant_bool<true>(), "message");
+ return true;
+}
+static_assert(constexpr_context(), "");
+
+
+int main() {
+ // Make sure it works at function scope
+ BOOST_HANA_CONSTANT_ASSERT(constant_bool<true>());
+ BOOST_HANA_CONSTANT_ASSERT_MSG(constant_bool<true>(), "message");
+
+ // Make sure it works inside a lambda
+ auto lambda = []{
+ BOOST_HANA_CONSTANT_ASSERT(constant_bool<true>());
+ BOOST_HANA_CONSTANT_ASSERT_MSG(constant_bool<true>(), "message");
+ };
+ lambda();
+
+ // Make sure we can reference a local variable
+ auto yes = constant_bool<true>();
+ BOOST_HANA_CONSTANT_ASSERT(yes);
+ BOOST_HANA_CONSTANT_ASSERT_MSG(yes, "message");
+}
diff --git a/src/boost/libs/hana/test/assert/constexpr.cpp b/src/boost/libs/hana/test/assert/constexpr.cpp
new file mode 100644
index 00000000..dd26c34c
--- /dev/null
+++ b/src/boost/libs/hana/test/assert/constexpr.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>
+namespace hana = boost::hana;
+
+
+template <bool value>
+bool runtime_bool() { return value; }
+
+template <bool value>
+constexpr bool constexpr_bool() { return value; }
+
+
+int main() {
+ // Make sure it works at function scope
+ BOOST_HANA_CONSTEXPR_ASSERT(runtime_bool<true>());
+ BOOST_HANA_CONSTEXPR_ASSERT(constexpr_bool<true>());
+ BOOST_HANA_CONSTEXPR_ASSERT_MSG(runtime_bool<true>(), "message");
+ BOOST_HANA_CONSTEXPR_ASSERT_MSG(constexpr_bool<true>(), "message");
+
+ // Make sure we can reference a local variable
+ auto rt_yes = runtime_bool<true>();
+ constexpr auto cx_yes = constexpr_bool<true>();
+ BOOST_HANA_CONSTEXPR_ASSERT(rt_yes);
+ BOOST_HANA_CONSTEXPR_ASSERT(cx_yes);
+ BOOST_HANA_CONSTEXPR_ASSERT_MSG(rt_yes, "message");
+ BOOST_HANA_CONSTEXPR_ASSERT_MSG(cx_yes, "message");
+}
diff --git a/src/boost/libs/hana/test/assert/flexible.cpp b/src/boost/libs/hana/test/assert/flexible.cpp
new file mode 100644
index 00000000..207eb4d8
--- /dev/null
+++ b/src/boost/libs/hana/test/assert/flexible.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 <support/cnumeric.hpp>
+namespace hana = boost::hana;
+
+
+template <bool value>
+bool runtime_bool() { return value; }
+
+template <bool value>
+auto constant_bool() { return make_cnumeric<bool, value>(); }
+
+
+int main() {
+ // Make sure it works at function scope
+ BOOST_HANA_ASSERT(runtime_bool<true>());
+ BOOST_HANA_ASSERT(constant_bool<true>());
+
+ BOOST_HANA_ASSERT_MSG(runtime_bool<true>(), "message");
+ BOOST_HANA_ASSERT_MSG(constant_bool<true>(), "message");
+
+ // Make sure we can reference a local variable
+ auto ct_yes = constant_bool<true>();
+ BOOST_HANA_ASSERT(ct_yes);
+ BOOST_HANA_ASSERT_MSG(ct_yes, "message");
+
+ auto rt_yes = runtime_bool<true>();
+ BOOST_HANA_ASSERT(rt_yes);
+ BOOST_HANA_ASSERT_MSG(rt_yes, "message");
+}
diff --git a/src/boost/libs/hana/test/assert/lambdas.cpp b/src/boost/libs/hana/test/assert/lambdas.cpp
new file mode 100644
index 00000000..900dbd4e
--- /dev/null
+++ b/src/boost/libs/hana/test/assert/lambdas.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 <support/cnumeric.hpp>
+namespace hana = boost::hana;
+
+
+// This test makes sure that we can use lambdas inside the various
+// BOOST_HANA_XXX_ASSERT macros.
+
+template <bool value>
+bool runtime_bool() { return value; }
+
+template <bool value>
+auto constant_bool() { return make_cnumeric<bool, value>(); }
+
+int main() {
+ BOOST_HANA_CONSTANT_ASSERT([]{ return constant_bool<true>(); }());
+ BOOST_HANA_RUNTIME_ASSERT([]{ return runtime_bool<true>(); }());
+ BOOST_HANA_ASSERT([] { return constant_bool<true>(); }());
+ BOOST_HANA_ASSERT([] { return runtime_bool<true>(); }());
+}
diff --git a/src/boost/libs/hana/test/assert/runtime.cpp b/src/boost/libs/hana/test/assert/runtime.cpp
new file mode 100644
index 00000000..7db4e4be
--- /dev/null
+++ b/src/boost/libs/hana/test/assert/runtime.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>
+namespace hana = boost::hana;
+
+
+template <bool value>
+bool runtime_bool() { return value; }
+
+
+int main() {
+ // Make sure it works at function scope
+ BOOST_HANA_RUNTIME_ASSERT(runtime_bool<true>());
+ BOOST_HANA_RUNTIME_ASSERT_MSG(runtime_bool<true>(), "message");
+
+ // Make sure we can reference a local variable
+ auto yes = runtime_bool<true>();
+ BOOST_HANA_RUNTIME_ASSERT(yes);
+ BOOST_HANA_RUNTIME_ASSERT_MSG(yes, "message");
+}
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/_specs.hpp b/src/boost/libs/hana/test/basic_tuple/auto/_specs.hpp
new file mode 100644
index 00000000..a54b0466
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/_specs.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_BASIC_TUPLE_AUTO_SPECS_HPP
+#define BOOST_HANA_TEST_BASIC_TUPLE_AUTO_SPECS_HPP
+
+#include <boost/hana/basic_tuple.hpp>
+
+
+#define MAKE_TUPLE(...) ::boost::hana::make_basic_tuple(__VA_ARGS__)
+#define TUPLE_TYPE(...) ::boost::hana::basic_tuple<__VA_ARGS__>
+#define TUPLE_TAG ::boost::hana::basic_tuple_tag
+
+#endif // !BOOST_HANA_TEST_BASIC_TUPLE_AUTO_SPECS_HPP
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/all_of.cpp b/src/boost/libs/hana/test/basic_tuple/auto/all_of.cpp
new file mode 100644
index 00000000..f3e974ff
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/all_of.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 "_specs.hpp"
+#include <auto/all_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/any_of.cpp b/src/boost/libs/hana/test/basic_tuple/auto/any_of.cpp
new file mode 100644
index 00000000..3065d017
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/any_of.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 "_specs.hpp"
+#include <auto/any_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/ap.cpp b/src/boost/libs/hana/test/basic_tuple/auto/ap.cpp
new file mode 100644
index 00000000..59c9cb75
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/ap.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 "_specs.hpp"
+#include <auto/ap.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/at.cpp b/src/boost/libs/hana/test/basic_tuple/auto/at.cpp
new file mode 100644
index 00000000..60526533
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/at.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 "_specs.hpp"
+#include <auto/at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/cartesian_product.cpp b/src/boost/libs/hana/test/basic_tuple/auto/cartesian_product.cpp
new file mode 100644
index 00000000..b0795e8d
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/cartesian_product.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 "_specs.hpp"
+#include <auto/cartesian_product.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/drop_back.cpp b/src/boost/libs/hana/test/basic_tuple/auto/drop_back.cpp
new file mode 100644
index 00000000..b283844d
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/drop_back.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 "_specs.hpp"
+#include <auto/drop_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/drop_front.cpp b/src/boost/libs/hana/test/basic_tuple/auto/drop_front.cpp
new file mode 100644
index 00000000..a39d6f45
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/drop_front.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 "_specs.hpp"
+#include <auto/drop_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/drop_while.cpp b/src/boost/libs/hana/test/basic_tuple/auto/drop_while.cpp
new file mode 100644
index 00000000..18907f03
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/drop_while.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 "_specs.hpp"
+#include <auto/drop_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/for_each.cpp b/src/boost/libs/hana/test/basic_tuple/auto/for_each.cpp
new file mode 100644
index 00000000..714fe03c
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/for_each.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 "_specs.hpp"
+#include <auto/for_each.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/group.cpp b/src/boost/libs/hana/test/basic_tuple/auto/group.cpp
new file mode 100644
index 00000000..0669b496
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/group.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 "_specs.hpp"
+#include <auto/group.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/index_if.cpp b/src/boost/libs/hana/test/basic_tuple/auto/index_if.cpp
new file mode 100644
index 00000000..ef37fe65
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/index_if.cpp
@@ -0,0 +1,9 @@
+// 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 "_specs.hpp"
+#include <auto/index_if.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/insert.cpp b/src/boost/libs/hana/test/basic_tuple/auto/insert.cpp
new file mode 100644
index 00000000..e8efc6dc
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/insert.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 "_specs.hpp"
+#include <auto/insert.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/insert_range.cpp b/src/boost/libs/hana/test/basic_tuple/auto/insert_range.cpp
new file mode 100644
index 00000000..05ac5774
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/insert_range.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 "_specs.hpp"
+#include <auto/insert_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/intersperse.cpp b/src/boost/libs/hana/test/basic_tuple/auto/intersperse.cpp
new file mode 100644
index 00000000..185c814a
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/intersperse.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 "_specs.hpp"
+#include <auto/intersperse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/is_empty.cpp b/src/boost/libs/hana/test/basic_tuple/auto/is_empty.cpp
new file mode 100644
index 00000000..f175f7dd
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/is_empty.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 "_specs.hpp"
+#include <auto/is_empty.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/length.cpp b/src/boost/libs/hana/test/basic_tuple/auto/length.cpp
new file mode 100644
index 00000000..55111dd6
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/length.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 "_specs.hpp"
+#include <auto/length.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/lexicographical_compare.cpp b/src/boost/libs/hana/test/basic_tuple/auto/lexicographical_compare.cpp
new file mode 100644
index 00000000..4d2f3edf
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/lexicographical_compare.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 "_specs.hpp"
+#include <auto/lexicographical_compare.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/make.cpp b/src/boost/libs/hana/test/basic_tuple/auto/make.cpp
new file mode 100644
index 00000000..f90514f1
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/make.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 "_specs.hpp"
+#include <auto/make.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/none_of.cpp b/src/boost/libs/hana/test/basic_tuple/auto/none_of.cpp
new file mode 100644
index 00000000..b56a27b4
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/none_of.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 "_specs.hpp"
+#include <auto/none_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/partition.cpp b/src/boost/libs/hana/test/basic_tuple/auto/partition.cpp
new file mode 100644
index 00000000..ba9621a6
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/partition.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 "_specs.hpp"
+#include <auto/partition.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/permutations.cpp b/src/boost/libs/hana/test/basic_tuple/auto/permutations.cpp
new file mode 100644
index 00000000..3c1a6e85
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/permutations.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 "_specs.hpp"
+#include <auto/permutations.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/remove_at.cpp b/src/boost/libs/hana/test/basic_tuple/auto/remove_at.cpp
new file mode 100644
index 00000000..5b7c5af4
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/remove_at.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 "_specs.hpp"
+#include <auto/remove_at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/remove_range.cpp b/src/boost/libs/hana/test/basic_tuple/auto/remove_range.cpp
new file mode 100644
index 00000000..6d7c6e09
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/remove_range.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 "_specs.hpp"
+#include <auto/remove_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/reverse.cpp b/src/boost/libs/hana/test/basic_tuple/auto/reverse.cpp
new file mode 100644
index 00000000..342278df
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/reverse.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 "_specs.hpp"
+#include <auto/reverse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/scans.cpp b/src/boost/libs/hana/test/basic_tuple/auto/scans.cpp
new file mode 100644
index 00000000..36dd3243
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/scans.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 "_specs.hpp"
+#include <auto/scans.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/sequence.cpp b/src/boost/libs/hana/test/basic_tuple/auto/sequence.cpp
new file mode 100644
index 00000000..4ed01e85
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/sequence.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 "_specs.hpp"
+#include <auto/sequence.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/slice.cpp b/src/boost/libs/hana/test/basic_tuple/auto/slice.cpp
new file mode 100644
index 00000000..3e20df95
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/slice.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 "_specs.hpp"
+#include <auto/slice.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/sort.cpp b/src/boost/libs/hana/test/basic_tuple/auto/sort.cpp
new file mode 100644
index 00000000..f639ddeb
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/sort.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 "_specs.hpp"
+#include <auto/sort.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/span.cpp b/src/boost/libs/hana/test/basic_tuple/auto/span.cpp
new file mode 100644
index 00000000..297b7f17
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/span.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 "_specs.hpp"
+#include <auto/span.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/take_back.cpp b/src/boost/libs/hana/test/basic_tuple/auto/take_back.cpp
new file mode 100644
index 00000000..2a91d7d4
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/take_back.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 "_specs.hpp"
+#include <auto/take_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/take_front.cpp b/src/boost/libs/hana/test/basic_tuple/auto/take_front.cpp
new file mode 100644
index 00000000..9a48d2b8
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/take_front.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 "_specs.hpp"
+#include <auto/take_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/take_while.cpp b/src/boost/libs/hana/test/basic_tuple/auto/take_while.cpp
new file mode 100644
index 00000000..e58c99ac
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/take_while.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 "_specs.hpp"
+#include <auto/take_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/transform.cpp b/src/boost/libs/hana/test/basic_tuple/auto/transform.cpp
new file mode 100644
index 00000000..306c1bc3
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/transform.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 "_specs.hpp"
+#include <auto/transform.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/unfolds.cpp b/src/boost/libs/hana/test/basic_tuple/auto/unfolds.cpp
new file mode 100644
index 00000000..f8bac9dd
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/unfolds.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 "_specs.hpp"
+#include <auto/unfolds.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/unique.cpp b/src/boost/libs/hana/test/basic_tuple/auto/unique.cpp
new file mode 100644
index 00000000..9c1dc715
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/unique.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 "_specs.hpp"
+#include <auto/unique.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/auto/zips.cpp b/src/boost/libs/hana/test/basic_tuple/auto/zips.cpp
new file mode 100644
index 00000000..32ec5cc8
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/auto/zips.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 "_specs.hpp"
+#include <auto/zips.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/basic_tuple/cnstr.copy.cpp b/src/boost/libs/hana/test/basic_tuple/cnstr.copy.cpp
new file mode 100644
index 00000000..5949156f
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/cnstr.copy.cpp
@@ -0,0 +1,86 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/basic_tuple.hpp>
+
+#include <laws/base.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Empty { };
+
+int main() {
+ {
+ using T = hana::basic_tuple<>;
+ T t0;
+ T t_implicit = t0;
+ T t_explicit(t0);
+
+ (void)t_explicit;
+ (void)t_implicit;
+ }
+ {
+ using T = hana::basic_tuple<int>;
+ T t0(2);
+ T t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ }
+ {
+ using T = hana::basic_tuple<int, char>;
+ T t0(2, 'a');
+ T t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ }
+ {
+ using T = hana::basic_tuple<int, char, std::string>;
+ const T t0(2, 'a', "some text");
+ T t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "some text");
+ }
+ {
+ using T = hana::basic_tuple<int>;
+ constexpr T t0(2);
+ constexpr T t = t0;
+ static_assert(hana::at_c<0>(t) == 2, "");
+ }
+ {
+ using T = hana::basic_tuple<Empty>;
+ constexpr T t0{};
+ constexpr T t = t0;
+ constexpr Empty e = hana::at_c<0>(t); (void)e;
+ }
+ {
+ struct T { };
+ struct U { };
+
+ constexpr hana::basic_tuple<T, U> binary{};
+ constexpr hana::basic_tuple<T, U> copy_implicit = binary;
+ constexpr hana::basic_tuple<T, U> copy_explicit(binary);
+
+ (void)copy_implicit;
+ (void)copy_explicit;
+ }
+
+ // This used to fail
+ {
+ hana::basic_tuple<
+ hana::test::ct_eq<0>,
+ hana::test::ct_eq<2>,
+ hana::test::ct_eq<4>
+ > tuple{};
+
+ hana::basic_tuple<
+ hana::test::ct_eq<0>,
+ hana::test::ct_eq<2>,
+ hana::test::ct_eq<4>
+ > copy(tuple);
+ }
+}
diff --git a/src/boost/libs/hana/test/basic_tuple/construct.cpp b/src/boost/libs/hana/test/basic_tuple/construct.cpp
new file mode 100644
index 00000000..38b5e0a5
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/construct.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>
+namespace hana = boost::hana;
+
+
+template <int i>
+struct x { };
+
+
+int main() {
+ constexpr hana::basic_tuple<> empty{}; (void)empty;
+
+ constexpr hana::basic_tuple<int, float> xs{1, 2.3f}; (void)xs;
+ constexpr auto ys = hana::basic_tuple<int, float>{1, 2.3f};
+ constexpr auto copy = ys; (void)copy;
+}
diff --git a/src/boost/libs/hana/test/basic_tuple/laws.cpp b/src/boost/libs/hana/test/basic_tuple/laws.cpp
new file mode 100644
index 00000000..d6a299be
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/laws.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/basic_tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/foldable.hpp>
+#include <laws/functor.hpp>
+#include <laws/iterable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto eq_tuples = hana::make_basic_tuple(
+ hana::make_basic_tuple()
+ , hana::make_basic_tuple(ct_eq<0>{})
+ , hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ , hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ , hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})
+ );
+
+ auto eq_values = hana::make_basic_tuple(
+ ct_eq<0>{},
+ ct_eq<2>{},
+ ct_eq<4>{}
+ );
+
+ hana::test::TestFunctor<hana::basic_tuple_tag>{eq_tuples, eq_values};
+ hana::test::TestFoldable<hana::basic_tuple_tag>{eq_tuples};
+ hana::test::TestIterable<hana::basic_tuple_tag>{eq_tuples};
+}
diff --git a/src/boost/libs/hana/test/basic_tuple/length.cpp b/src/boost/libs/hana/test/basic_tuple/length.cpp
new file mode 100644
index 00000000..53d25256
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/length.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/basic_tuple.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_basic_tuple()),
+ hana::size_c<0>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_basic_tuple(ct_eq<0>{})),
+ hana::size_c<1>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{})),
+ hana::size_c<2>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ hana::size_c<3>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})),
+ hana::size_c<4>
+ ));
+}
diff --git a/src/boost/libs/hana/test/basic_tuple/make.cpp b/src/boost/libs/hana/test/basic_tuple/make.cpp
new file mode 100644
index 00000000..92e49543
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/make.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/basic_tuple.hpp>
+#include <boost/hana/core/make.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+struct x { };
+
+int main() {
+ auto xs1 = hana::make<hana::basic_tuple_tag>(); (void)xs1;
+ auto xs2 = hana::make<hana::basic_tuple_tag>(x<0>{}); (void)xs2;
+ auto xs3 = hana::make<hana::basic_tuple_tag>(x<0>{}, x<1>{}); (void)xs3;
+ auto xs4 = hana::make<hana::basic_tuple_tag>(x<0>{}, x<1>{}, x<2>{}); (void)xs4;
+}
diff --git a/src/boost/libs/hana/test/basic_tuple/unpack.cpp b/src/boost/libs/hana/test/basic_tuple/unpack.cpp
new file mode 100644
index 00000000..012bb007
--- /dev/null
+++ b/src/boost/libs/hana/test/basic_tuple/unpack.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/basic_tuple.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_basic_tuple(), f),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_basic_tuple(ct_eq<0>{}), f),
+ f(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{}), f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_basic_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), f),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/builtin_array.cpp b/src/boost/libs/hana/test/builtin_array.cpp
new file mode 100644
index 00000000..f3e26957
--- /dev/null
+++ b/src/boost/libs/hana/test/builtin_array.cpp
@@ -0,0 +1,121 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/bool.hpp>
+#include <boost/hana/concept/foldable.hpp>
+#include <boost/hana/concept/searchable.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+#include <laws/foldable.hpp>
+#include <laws/searchable.hpp>
+
+#include <cstddef>
+namespace hana = boost::hana;
+
+
+template <typename T, std::size_t n>
+using array = T[n];
+
+int main() {
+ // We can't check the laws because builtin arrays can't be passed
+ // to functions.
+
+ //////////////////////////////////////////////////////////////////////////
+ // Foldable
+ //////////////////////////////////////////////////////////////////////////
+ {
+ int a[] = {1};
+ int b[] = {1, 2};
+ int c[] = {1, 2, 3};
+ int d[] = {1, 2, 3, 4};
+
+ // unpack
+ {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::unpack(a, f),
+ f(1)
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::unpack(b, f),
+ f(1, 2)
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::unpack(c, f),
+ f(1, 2, 3)
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::unpack(d, f),
+ f(1, 2, 3, 4)
+ ));
+ }
+
+ static_assert(hana::Foldable<int[3]>::value, "");
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Searchable
+ //////////////////////////////////////////////////////////////////////////
+ {
+ // any_of
+ {
+ static_assert(
+ hana::not_(hana::any_of(array<int, 1>{0}, hana::equal.to(1)))
+ , "");
+
+ static_assert(
+ hana::any_of(array<int, 2>{0, 1}, hana::equal.to(0))
+ , "");
+ static_assert(
+ hana::any_of(array<int, 2>{0, 1}, hana::equal.to(1))
+ , "");
+ static_assert(
+ hana::not_(hana::any_of(array<int, 2>{0, 1}, hana::equal.to(2)))
+ , "");
+
+ static_assert(
+ hana::any_of(array<int, 3>{0, 1, 2}, hana::equal.to(0))
+ , "");
+ static_assert(
+ hana::any_of(array<int, 3>{0, 1, 2}, hana::equal.to(1))
+ , "");
+ static_assert(
+ hana::any_of(array<int, 3>{0, 1, 2}, hana::equal.to(2))
+ , "");
+ static_assert(
+ hana::not_(hana::any_of(array<int, 3>{0, 1, 2}, hana::equal.to(3)))
+ , "");
+ }
+
+ // find_if
+ // Note: Because we need the predicate to return a Constant, this
+ // is incredibly not powerful.
+ {
+ static_assert(hana::equal(
+ hana::find_if(array<int, 1>{0}, hana::always(hana::true_c)),
+ hana::just(0)
+ ), "");
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(array<int, 1>{0}, hana::always(hana::false_c)),
+ hana::nothing
+ ));
+ }
+
+ static_assert(hana::Searchable<int[3]>::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/comparable.cpp b/src/boost/libs/hana/test/comparable.cpp
new file mode 100644
index 00000000..0c968a35
--- /dev/null
+++ b/src/boost/libs/hana/test/comparable.cpp
@@ -0,0 +1,70 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/comparable.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// Minimal EqualityComparable types
+struct eq1 { int value; };
+struct eq2 {
+ int value;
+ constexpr operator eq1() const { return {value}; }
+};
+
+template <typename T, typename U, typename = std::enable_if_t<
+ (std::is_same<T, eq1>{} || std::is_same<T, eq2>{}) &&
+ (std::is_same<U, eq1>{} || std::is_same<U, eq2>{})
+>>
+constexpr bool operator==(T a, U b)
+{ return a.value == b.value; }
+
+template <typename T, typename U, typename = std::enable_if_t<
+ (std::is_same<T, eq1>{} || std::is_same<T, eq2>{}) &&
+ (std::is_same<U, eq1>{} || std::is_same<U, eq2>{})
+>>
+constexpr bool operator!=(T a, U b)
+{ return !(a == b); }
+
+
+int main() {
+ // equal
+ {
+ // Two objects of different data types are unequal by default,
+ // and no model is provided for two objects of the same data type.
+ struct Random1 { }; struct Random2 { };
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(Random1{}, Random2{})));
+ static_assert(!hana::Comparable<Random1>::value, "");
+ static_assert(!hana::Comparable<Random2>::value, "");
+
+ // Provided model for EqualityComparable types
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(eq1{0}, eq1{0}));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(eq1{0}, eq1{1})));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(eq1{1}, eq1{0})));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(eq1{0}, eq2{0}));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(eq1{0}, eq2{1})));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(eq1{1}, eq2{0})));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(eq2{0}, eq1{0}));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(eq2{0}, eq1{1})));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(eq2{1}, eq1{0})));
+ }
+
+ // laws
+ hana::test::TestComparable<int>{hana::make_tuple(0,1,2,3,4,5)};
+ hana::test::TestComparable<unsigned int>{hana::make_tuple(0u,1u,2u,3u,4u,5u)};
+ hana::test::TestComparable<long>{hana::make_tuple(0l,1l,2l,3l,4l,5l)};
+ hana::test::TestComparable<unsigned long>{hana::make_tuple(0ul,1ul,2ul,3ul,4ul,5ul)};
+ hana::test::TestComparable<eq1>{hana::make_tuple(eq1{0}, eq1{1}, eq1{2}, eq1{3}, eq1{4})};
+}
diff --git a/src/boost/libs/hana/test/concept/constant/arithmetic.cpp b/src/boost/libs/hana/test/concept/constant/arithmetic.cpp
new file mode 100644
index 00000000..e01403ba
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/constant/arithmetic.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 "minimal.hpp"
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/euclidean_ring.hpp>
+#include <laws/group.hpp>
+#include <laws/monoid.hpp>
+#include <laws/ring.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto ints = hana::make_tuple(
+ minimal_constant<int, -3>{},
+ minimal_constant<int, 0>{},
+ minimal_constant<int, 1>{},
+ minimal_constant<int, 2>{},
+ minimal_constant<int, 3>{}
+ );
+
+ hana::test::TestMonoid<minimal_constant_tag<int>>{ints};
+ hana::test::TestGroup<minimal_constant_tag<int>>{ints};
+ hana::test::TestRing<minimal_constant_tag<int>>{ints};
+ hana::test::TestEuclideanRing<minimal_constant_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/concept/constant/comparable.cpp b/src/boost/libs/hana/test/concept/constant/comparable.cpp
new file mode 100644
index 00000000..697a2389
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/constant/comparable.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 "minimal.hpp"
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto ints = hana::make_tuple(
+ minimal_constant<int, -3>{},
+ minimal_constant<int, 0>{},
+ minimal_constant<int, 1>{},
+ minimal_constant<int, 2>{},
+ minimal_constant<int, 3>{}
+ );
+
+ hana::test::TestComparable<minimal_constant_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/concept/constant/laws.cpp b/src/boost/libs/hana/test/concept/constant/laws.cpp
new file mode 100644
index 00000000..5b132e3f
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/constant/laws.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 "minimal.hpp"
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/constant.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto ints = hana::make_tuple(
+ minimal_constant<int, -3>{},
+ minimal_constant<int, 0>{},
+ minimal_constant<int, 1>{},
+ minimal_constant<int, 2>{},
+ minimal_constant<int, 3>{}
+ );
+
+ constexpr auto convertible_types = hana::tuple_t<int, long, long long>;
+
+ hana::test::TestConstant<minimal_constant_tag<int>>{ints, convertible_types};
+}
diff --git a/src/boost/libs/hana/test/concept/constant/logical.cpp b/src/boost/libs/hana/test/concept/constant/logical.cpp
new file mode 100644
index 00000000..980273aa
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/constant/logical.cpp
@@ -0,0 +1,191 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include "minimal.hpp"
+
+#include <boost/hana/and.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/or.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/while.hpp>
+
+#include <laws/base.hpp>
+#include <laws/logical.hpp>
+namespace hana = boost::hana;
+
+
+struct invalid { };
+
+int main() {
+ constexpr auto bools = hana::make_tuple(
+ minimal_constant<bool, false>{},
+ minimal_constant<bool, true>{}
+ );
+
+ hana::test::TestLogical<minimal_constant_tag<bool>>{bools};
+
+
+ constexpr auto true_ = minimal_constant<bool, true>{};
+ constexpr auto false_ = minimal_constant<bool, false>{};
+
+ // not_
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::not_(true_), false_));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::not_(false_), true_));
+ }
+
+ // and_
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::and_(true_),
+ true_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::and_(false_),
+ false_
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::and_(true_, true_),
+ true_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::and_(true_, false_),
+ false_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::and_(false_, invalid{}),
+ false_
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::and_(true_, true_, true_),
+ true_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::and_(true_, true_, false_),
+ false_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::and_(true_, false_, invalid{}),
+ false_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::and_(false_, invalid{}, invalid{}),
+ false_
+ ));
+ }
+
+ // or_
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::or_(true_),
+ true_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::or_(false_),
+ false_
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::or_(false_, false_),
+ false_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::or_(false_, true_),
+ true_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::or_(true_, invalid{}),
+ true_
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::or_(false_, false_, false_),
+ false_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::or_(false_, false_, true_),
+ true_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::or_(false_, true_, invalid{}),
+ true_
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::or_(true_, invalid{}, invalid{}),
+ true_
+ ));
+ }
+
+ // if_
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::if_(true_, hana::test::ct_eq<3>{}, hana::test::ct_eq<4>{}),
+ hana::test::ct_eq<3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::if_(false_, hana::test::ct_eq<3>{}, hana::test::ct_eq<4>{}),
+ hana::test::ct_eq<4>{}
+ ));
+ }
+
+ // eval_if
+ {
+ auto t = [](auto) { return hana::test::ct_eq<2>{}; };
+ auto e = [](auto) { return hana::test::ct_eq<3>{}; };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval_if(true_, t, invalid{}),
+ hana::test::ct_eq<2>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval_if(false_, invalid{}, e),
+ hana::test::ct_eq<3>{}
+ ));
+ }
+
+ // while_
+ {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::while_(hana::not_equal.to(hana::test::ct_eq<0>{}), hana::test::ct_eq<0>{}, invalid{}),
+ hana::test::ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::while_(hana::not_equal.to(f(hana::test::ct_eq<0>{})), hana::test::ct_eq<0>{}, f),
+ f(hana::test::ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::while_(hana::not_equal.to(f(f(hana::test::ct_eq<0>{}))), hana::test::ct_eq<0>{}, f),
+ f(f(hana::test::ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::while_(hana::not_equal.to(f(f(f(hana::test::ct_eq<0>{})))), hana::test::ct_eq<0>{}, f),
+ f(f(f(hana::test::ct_eq<0>{})))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::while_(hana::not_equal.to(f(f(f(f(hana::test::ct_eq<0>{}))))), hana::test::ct_eq<0>{}, f),
+ f(f(f(f(hana::test::ct_eq<0>{}))))
+ ));
+
+ // Make sure it can be called with an lvalue state:
+ auto state = hana::test::ct_eq<0>{};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::while_(hana::not_equal.to(f(f(f(f(hana::test::ct_eq<0>{}))))), state, f),
+ f(f(f(f(hana::test::ct_eq<0>{}))))
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/concept/constant/mcd.cpp b/src/boost/libs/hana/test/concept/constant/mcd.cpp
new file mode 100644
index 00000000..f45327cd
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/constant/mcd.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 "minimal.hpp"
+
+#include <boost/hana/concept/constant.hpp>
+#include <boost/hana/value.hpp>
+namespace hana = boost::hana;
+
+
+// Make sure we really satisfy Constant.
+static_assert(hana::Constant<minimal_constant<int, 0>>::value, "");
+static_assert(hana::Constant<minimal_constant<int, 1>>::value, "");
+static_assert(hana::Constant<minimal_constant<int, 2>>::value, "");
+static_assert(hana::Constant<minimal_constant<int, 3>>::value, "");
+
+// Make sure we can use hana::value<> properly.
+static_assert(hana::value<minimal_constant<int, 0>>() == 0, "");
+static_assert(hana::value<minimal_constant<int, 1>>() == 1, "");
+static_assert(hana::value<minimal_constant<int, 2>>() == 2, "");
+static_assert(hana::value<minimal_constant<int, 3>>() == 3, "");
+
+// Check the equivalence between `value(...)` and `value<decltype(...)>()`.
+static_assert(hana::value(minimal_constant<int, 0>{}) == hana::value<minimal_constant<int, 0>>(), "");
+static_assert(hana::value(minimal_constant<int, 1>{}) == hana::value<minimal_constant<int, 1>>(), "");
+static_assert(hana::value(minimal_constant<int, 2>{}) == hana::value<minimal_constant<int, 2>>(), "");
+static_assert(hana::value(minimal_constant<int, 3>{}) == hana::value<minimal_constant<int, 3>>(), "");
+
+
+int main() { }
diff --git a/src/boost/libs/hana/test/concept/constant/minimal.hpp b/src/boost/libs/hana/test/concept/constant/minimal.hpp
new file mode 100644
index 00000000..ebc2ae11
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/constant/minimal.hpp
@@ -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)
+
+#ifndef TEST_CONCEPT_CONSTANT_MINIMAL_HPP
+#define TEST_CONCEPT_CONSTANT_MINIMAL_HPP
+
+#include <boost/hana/concept/constant.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/fwd/core/to.hpp>
+#include <boost/hana/value.hpp>
+
+
+template <typename T>
+struct minimal_constant_tag {
+ using value_type = T;
+};
+
+template <typename T, T v>
+struct minimal_constant {
+ using hana_tag = minimal_constant_tag<T>;
+ static constexpr T value_ = v;
+};
+
+namespace boost { namespace hana {
+ template <typename T>
+ struct value_impl<minimal_constant_tag<T>> {
+ template <typename N>
+ static constexpr T apply() { return N::value_; }
+ };
+
+ template <typename T, typename C>
+ struct to_impl<minimal_constant_tag<T>, C, hana::when<
+ hana::Constant<C>::value &&
+ hana::is_convertible<typename C::value_type, T>::value
+ >>
+ : hana::embedding<hana::is_embedded<typename C::value_type, T>::value>
+ {
+ template <typename N>
+ static constexpr auto apply(N const&)
+ { return minimal_constant<T, hana::value<N>()>{}; }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_CONCEPT_CONSTANT_MINIMAL_HPP
diff --git a/src/boost/libs/hana/test/concept/constant/orderable.cpp b/src/boost/libs/hana/test/concept/constant/orderable.cpp
new file mode 100644
index 00000000..08aba261
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/constant/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 "minimal.hpp"
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/orderable.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto ints = hana::make_tuple(
+ minimal_constant<int, -3>{},
+ minimal_constant<int, 0>{},
+ minimal_constant<int, 1>{},
+ minimal_constant<int, 2>{},
+ minimal_constant<int, 3>{}
+ );
+
+ hana::test::TestOrderable<minimal_constant_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/concept/constant/to.cpp b/src/boost/libs/hana/test/concept/constant/to.cpp
new file mode 100644
index 00000000..8500b1d9
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/constant/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 "minimal.hpp"
+
+#include <boost/hana/concept/constant.hpp>
+#include <boost/hana/core/to.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::is_convertible<minimal_constant_tag<bool>, bool>::value, "");
+static_assert(hana::to<bool>(minimal_constant<bool, true>{}) == true, "");
+
+static_assert(hana::is_convertible<minimal_constant_tag<int>, int>::value, "");
+static_assert(hana::to<int>(minimal_constant<int, 1>{}) == 1, "");
+
+static_assert(hana::is_convertible<minimal_constant_tag<long>, long>::value, "");
+static_assert(hana::to<long>(minimal_constant<long, 1>{}) == 1l, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/concept/integral_constant.cpp b/src/boost/libs/hana/test/concept/integral_constant.cpp
new file mode 100644
index 00000000..ad69759f
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/integral_constant.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/concept/constant.hpp>
+#include <boost/hana/concept/integral_constant.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/fwd/core/to.hpp>
+#include <boost/hana/value.hpp>
+namespace hana = boost::hana;
+
+
+// Define a simple model of IntegralConstant
+struct constant_tag { using value_type = int; };
+template <int i>
+struct constant {
+ static constexpr int value = i;
+ using hana_tag = constant_tag;
+};
+
+namespace boost { namespace hana {
+ template <>
+ struct IntegralConstant<constant_tag> {
+ static constexpr bool value = true;
+ };
+
+ template <typename From>
+ struct to_impl<constant_tag, From, when<IntegralConstant<From>::value>> {
+ template <typename N>
+ static constexpr auto apply(N const&)
+ { return constant<N::value>{}; }
+ };
+}}
+
+// Make sure we really satisfy IntegralConstant<>.
+static_assert(hana::IntegralConstant<constant<0>>::value, "");
+static_assert(hana::IntegralConstant<constant<1>>::value, "");
+static_assert(hana::IntegralConstant<constant<2>>::value, "");
+
+// Make sure we're also a model of Constant automatically.
+static_assert(hana::Constant<constant<0>>::value, "");
+static_assert(hana::Constant<constant<1>>::value, "");
+static_assert(hana::Constant<constant<2>>::value, "");
+
+// Make sure we have the hana::value<> function defined automatically.
+static_assert(hana::value<constant<0>>() == 0, "");
+static_assert(hana::value<constant<1>>() == 1, "");
+static_assert(hana::value<constant<2>>() == 2, "");
+static_assert(hana::value<constant<3>>() == 3, "");
+
+
+int main() { }
diff --git a/src/boost/libs/hana/test/concept/sequence/iterable.cpp b/src/boost/libs/hana/test/concept/sequence/iterable.cpp
new file mode 100644
index 00000000..75df0b1b
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/sequence/iterable.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_ITERABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/concept/sequence/monad.cpp b/src/boost/libs/hana/test/concept/sequence/monad.cpp
new file mode 100644
index 00000000..8de1861f
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/sequence/monad.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_MONAD
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/concept/sequence/monad_plus.cpp b/src/boost/libs/hana/test/concept/sequence/monad_plus.cpp
new file mode 100644
index 00000000..3af644d2
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/sequence/monad_plus.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_MONAD_PLUS
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/concept/sequence/orderable.cpp b/src/boost/libs/hana/test/concept/sequence/orderable.cpp
new file mode 100644
index 00000000..802ae289
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/sequence/orderable.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_ORDERABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/concept/sequence/searchable.cpp b/src/boost/libs/hana/test/concept/sequence/searchable.cpp
new file mode 100644
index 00000000..29a815cd
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/sequence/searchable.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_SEARCHABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/concept/sequence/sequence.cpp b/src/boost/libs/hana/test/concept/sequence/sequence.cpp
new file mode 100644
index 00000000..2a096973
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/sequence/sequence.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_SEQUENCE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/concept/struct/any_of.cpp b/src/boost/libs/hana/test/concept/struct/any_of.cpp
new file mode 100644
index 00000000..8dd9082a
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/any_of.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/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not.hpp>
+
+#include "minimal_struct.hpp"
+namespace hana = boost::hana;
+
+
+template <int i = 0>
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ obj(),
+ undefined<>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ obj(undefined<0>{}),
+ hana::equal.to(hana::int_c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ obj(undefined<0>{}),
+ hana::equal.to(hana::int_c<1>)
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ obj(undefined<0>{}, undefined<1>{}),
+ hana::equal.to(hana::int_c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ obj(undefined<0>{}, undefined<1>{}),
+ hana::equal.to(hana::int_c<1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ obj(undefined<0>{}, undefined<1>{}),
+ hana::equal.to(hana::int_c<2>)
+ )));
+}
diff --git a/src/boost/libs/hana/test/concept/struct/at_key.cpp b/src/boost/libs/hana/test/concept/struct/at_key.cpp
new file mode 100644
index 00000000..2a9d757b
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/at_key.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/at_key.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/string.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (std::string, name),
+ (std::string, last_name),
+ (int, age)
+ );
+};
+
+int main() {
+ // non-const ref
+ {
+ Person john{"John", "Doe", 30};
+ std::string& name = hana::at_key(john, BOOST_HANA_STRING("name"));
+ std::string& last_name = hana::at_key(john, BOOST_HANA_STRING("last_name"));
+ int& age = hana::at_key(john, BOOST_HANA_STRING("age"));
+
+ name = "Bob";
+ last_name = "Foo";
+ age = 99;
+
+ BOOST_HANA_RUNTIME_CHECK(john.name == "Bob");
+ BOOST_HANA_RUNTIME_CHECK(john.last_name == "Foo");
+ BOOST_HANA_RUNTIME_CHECK(john.age == 99);
+ }
+
+ // const ref
+ {
+ Person john{"John", "Doe", 30};
+ Person const& const_john = john;
+ std::string const& name = hana::at_key(const_john, BOOST_HANA_STRING("name"));
+ std::string const& last_name = hana::at_key(const_john, BOOST_HANA_STRING("last_name"));
+ int const& age = hana::at_key(const_john, BOOST_HANA_STRING("age"));
+
+ john.name = "Bob";
+ john.last_name = "Foo";
+ john.age = 99;
+
+ BOOST_HANA_RUNTIME_CHECK(name == "Bob");
+ BOOST_HANA_RUNTIME_CHECK(last_name == "Foo");
+ BOOST_HANA_RUNTIME_CHECK(age == 99);
+ }
+}
diff --git a/src/boost/libs/hana/test/concept/struct/equal.cpp b/src/boost/libs/hana/test/concept/struct/equal.cpp
new file mode 100644
index 00000000..3bd91689
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/equal.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/concept/struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+
+#include "minimal_struct.hpp"
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ obj(),
+ obj()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ obj(ct_eq<0>{}),
+ obj(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ obj(ct_eq<0>{}),
+ obj(ct_eq<1>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ obj(ct_eq<0>{}, ct_eq<1>{}),
+ obj(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ obj(ct_eq<1>{}, ct_eq<0>{}),
+ obj(ct_eq<0>{}, ct_eq<1>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ obj(ct_eq<0>{}, ct_eq<99>{}),
+ obj(ct_eq<0>{}, ct_eq<1>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ obj(ct_eq<99>{}, ct_eq<1>{}),
+ obj(ct_eq<0>{}, ct_eq<1>{})
+ )));
+}
diff --git a/src/boost/libs/hana/test/concept/struct/find_if.cpp b/src/boost/libs/hana/test/concept/struct/find_if.cpp
new file mode 100644
index 00000000..3e249239
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/find_if.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 <boost/hana/concept/struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+
+#include "minimal_struct.hpp"
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+template <int i = 0>
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(obj(), undefined<>{}),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(obj(ct_eq<0>{}), hana::equal.to(hana::int_c<0>)),
+ hana::just(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(obj(undefined<1>{}), hana::equal.to(hana::int_c<1>)),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(obj(ct_eq<0>{}, ct_eq<1>{}), hana::equal.to(hana::int_c<0>)),
+ hana::just(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(obj(ct_eq<0>{}, ct_eq<1>{}), hana::equal.to(hana::int_c<1>)),
+ hana::just(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(obj(undefined<0>{}, undefined<1>{}), hana::equal.to(hana::int_c<2>)),
+ hana::nothing
+ ));
+}
diff --git a/src/boost/libs/hana/test/concept/struct/fold_left.cpp b/src/boost/libs/hana/test/concept/struct/fold_left.cpp
new file mode 100644
index 00000000..f7b63814
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/fold_left.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)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include "minimal_struct.hpp"
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+template <int i = 0>
+struct undefined { };
+
+struct MoveOnly {
+ MoveOnly() = default;
+ MoveOnly(MoveOnly&&) = default;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly&&) = default;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+};
+
+int main() {
+ constexpr auto pair = ::minimal_product;
+ ct_eq<999> s{};
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(obj(), s, undefined<>{}),
+ s
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(obj(ct_eq<0>{}), s, f),
+ f(s, pair(hana::int_c<0>, ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(obj(ct_eq<0>{}, ct_eq<1>{}), s, f),
+ f(f(s, pair(hana::int_c<0>, ct_eq<0>{})), pair(hana::int_c<1>, ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(obj(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), s, f),
+ f(f(f(s, pair(hana::int_c<0>, ct_eq<0>{})),
+ pair(hana::int_c<1>, ct_eq<1>{})),
+ pair(hana::int_c<2>, ct_eq<2>{}))
+ ));
+
+ // fold_left with move-only members
+ hana::fold_left(obj(MoveOnly{}), 0, [](int, auto) { return 0; });
+ hana::fold_left(obj(MoveOnly{}, MoveOnly{}), 0, [](int, auto) { return 0; });
+}
diff --git a/src/boost/libs/hana/test/concept/struct/fold_right.cpp b/src/boost/libs/hana/test/concept/struct/fold_right.cpp
new file mode 100644
index 00000000..3db67def
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/fold_right.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)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include "minimal_struct.hpp"
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+template <int i = 0>
+struct undefined { };
+
+struct MoveOnly {
+ MoveOnly() = default;
+ MoveOnly(MoveOnly&&) = default;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly&&) = default;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+};
+
+int main() {
+ constexpr auto pair = ::minimal_product;
+ ct_eq<999> s{};
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(obj(), s, undefined<>{}),
+ s
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(obj(ct_eq<0>{}), s, f),
+ f(pair(hana::int_c<0>, ct_eq<0>{}), s)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(obj(ct_eq<0>{}, ct_eq<1>{}), s, f),
+ f(pair(hana::int_c<0>, ct_eq<0>{}), f(pair(hana::int_c<1>, ct_eq<1>{}), s))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(obj(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), s, f),
+ f(pair(hana::int_c<0>, ct_eq<0>{}),
+ f(pair(hana::int_c<1>, ct_eq<1>{}),
+ f(pair(hana::int_c<2>, ct_eq<2>{}), s)))
+ ));
+
+ // fold_right with move-only members
+ hana::fold_right(obj(MoveOnly{}), 0, [](auto, int) { return 0; });
+ hana::fold_right(obj(MoveOnly{}, MoveOnly{}), 0, [](auto, int) { return 0; });
+}
diff --git a/src/boost/libs/hana/test/concept/struct/keys.cpp b/src/boost/libs/hana/test/concept/struct/keys.cpp
new file mode 100644
index 00000000..c07de9e1
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/keys.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/assert.hpp>
+#include <boost/hana/concept/struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/keys.hpp>
+
+#include "minimal_struct.hpp"
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+template <int i = 0>
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::keys(obj()),
+ ::seq()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::keys(obj(undefined<0>{})),
+ ::seq(hana::int_c<0>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::keys(obj(undefined<0>{}, undefined<1>{})),
+ ::seq(hana::int_c<0>, hana::int_c<1>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::keys(obj(undefined<0>{}, undefined<1>{}, undefined<2>{})),
+ ::seq(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::keys(obj(undefined<0>{}, undefined<1>{}, undefined<2>{}, undefined<3>{})),
+ ::seq(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>, hana::int_c<3>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/concept/struct/laws.cpp b/src/boost/libs/hana/test/concept/struct/laws.cpp
new file mode 100644
index 00000000..b10955db
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/laws.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/concept/struct.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include "minimal_struct.hpp"
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/searchable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto eq0 = hana::make_tuple(obj());
+ auto eq1 = hana::make_tuple(
+ obj(ct_eq<0>{}), obj(ct_eq<1>{}), obj(ct_eq<2>{})
+ );
+ auto eq2 = hana::make_tuple(
+ obj(ct_eq<0>{}, ct_eq<0>{}),
+ obj(ct_eq<0>{}, ct_eq<1>{}),
+ obj(ct_eq<1>{}, ct_eq<0>{}),
+ obj(ct_eq<1>{}, ct_eq<1>{}),
+ obj(ct_eq<0>{}, ct_eq<2>{}),
+ obj(ct_eq<2>{}, ct_eq<3>{})
+ );
+
+ hana::test::TestComparable<minimal_struct_tag<0>>{eq0};
+ hana::test::TestComparable<minimal_struct_tag<1>>{eq1};
+ hana::test::TestComparable<minimal_struct_tag<2>>{eq2};
+
+ hana::test::TestFoldable<minimal_struct_tag<0>>{eq0};
+ hana::test::TestFoldable<minimal_struct_tag<1>>{eq1};
+ hana::test::TestFoldable<minimal_struct_tag<2>>{eq2};
+
+ hana::test::TestSearchable<minimal_struct_tag<0>>{eq0, hana::make_tuple()};
+ hana::test::TestSearchable<minimal_struct_tag<1>>{eq1, hana::make_tuple(hana::int_c<0>)};
+ hana::test::TestSearchable<minimal_struct_tag<2>>{eq2, hana::make_tuple(hana::int_c<0>, hana::int_c<1>)};
+}
diff --git a/src/boost/libs/hana/test/concept/struct/macro.adapt_adt.cpp b/src/boost/libs/hana/test/concept/struct/macro.adapt_adt.cpp
new file mode 100644
index 00000000..dc759b42
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/macro.adapt_adt.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/adapt_adt.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/struct.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/string.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+namespace ns {
+ struct Data0 { };
+ struct Data1 {
+ ct_eq<1> get_member1() const { return {}; }
+ };
+ struct Data2 {
+ ct_eq<1> get_member1() const { return {}; }
+ ct_eq<2> get_member2() const { return {}; }
+ };
+ struct Data3 {
+ ct_eq<1> get_member1() const { return {}; }
+ ct_eq<2> get_member2() const { return {}; }
+ ct_eq<3> get_member3() const { return {}; }
+ };
+}
+
+// Note: We use commas in the lambdas to make sure the macro can handle it.
+BOOST_HANA_ADAPT_ADT(ns::Data0);
+BOOST_HANA_ADAPT_ADT(ns::Data1,
+ (member1, [](auto const& d) { return 0, d.get_member1(); })
+);
+BOOST_HANA_ADAPT_ADT(ns::Data2,
+ (member1, [](auto const& d) { return 0, d.get_member1(); }),
+ (member2, [](auto const& d) { return d.get_member2(); })
+);
+BOOST_HANA_ADAPT_ADT(ns::Data3,
+ (member1, [](auto const& d) { return 0, d.get_member1(); }),
+ (member2, [](auto const& d) { return d.get_member2(); }),
+ (member3, [](auto const& d) { return d.get_member3(); })
+);
+
+static_assert(hana::Struct<ns::Data0>::value, "");
+static_assert(hana::Struct<ns::Data1>::value, "");
+static_assert(hana::Struct<ns::Data2>::value, "");
+static_assert(hana::Struct<ns::Data3>::value, "");
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data1{}, BOOST_HANA_STRING("member1")));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data2{}, BOOST_HANA_STRING("member1")));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data2{}, BOOST_HANA_STRING("member2")));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member1")));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member2")));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member3")));
+}
diff --git a/src/boost/libs/hana/test/concept/struct/macro.adapt_struct.cpp b/src/boost/libs/hana/test/concept/struct/macro.adapt_struct.cpp
new file mode 100644
index 00000000..6aec33d5
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/macro.adapt_struct.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/adapt_struct.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/struct.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/string.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+namespace ns {
+ struct Data0 { };
+ struct Data1 {
+ ct_eq<1> member1;
+ };
+ struct Data2 {
+ ct_eq<1> member1;
+ ct_eq<2> member2;
+ };
+ struct Data3 {
+ ct_eq<1> member1;
+ ct_eq<2> member2;
+ ct_eq<3> member3;
+ };
+ struct MemberArray {
+ int array[10];
+ };
+}
+
+BOOST_HANA_ADAPT_STRUCT(ns::Data0);
+BOOST_HANA_ADAPT_STRUCT(ns::Data1, member1);
+BOOST_HANA_ADAPT_STRUCT(ns::Data2, member1, member2);
+BOOST_HANA_ADAPT_STRUCT(ns::Data3, member1, member2, member3);
+BOOST_HANA_ADAPT_STRUCT(ns::MemberArray, array);
+
+static_assert(hana::Struct<ns::Data0>::value, "");
+static_assert(hana::Struct<ns::Data1>::value, "");
+static_assert(hana::Struct<ns::Data2>::value, "");
+static_assert(hana::Struct<ns::Data3>::value, "");
+static_assert(hana::Struct<ns::MemberArray>::value, "");
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data1{}, BOOST_HANA_STRING("member1")));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data2{}, BOOST_HANA_STRING("member1")));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data2{}, BOOST_HANA_STRING("member2")));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member1")));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member2")));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member3")));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::MemberArray{}, BOOST_HANA_STRING("array")));
+}
diff --git a/src/boost/libs/hana/test/concept/struct/macro.define_struct.cpp b/src/boost/libs/hana/test/concept/struct/macro.define_struct.cpp
new file mode 100644
index 00000000..29ddbfdd
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/macro.define_struct.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/contains.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/string.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+// This allows us to make sure we can enter template types
+// containing commas in the macro.
+template <typename T, typename ...>
+using commas = T;
+
+struct Data0 {
+ BOOST_HANA_DEFINE_STRUCT(Data0);
+};
+struct Data1 {
+ BOOST_HANA_DEFINE_STRUCT(Data1,
+ (commas<ct_eq<1>, void>, member1)
+ );
+};
+struct Data2 {
+ BOOST_HANA_DEFINE_STRUCT(Data2,
+ (commas<ct_eq<1>, void, void>, member1),
+ (ct_eq<2>, member2)
+ );
+};
+struct Data3 {
+ BOOST_HANA_DEFINE_STRUCT(Data3,
+ (ct_eq<1>, member1),
+ (ct_eq<2>, member2),
+ (commas<ct_eq<3>, void, void, void>, member3)
+ );
+};
+
+static_assert(hana::Struct<Data0>::value, "");
+static_assert(hana::Struct<Data1>::value, "");
+static_assert(hana::Struct<Data2>::value, "");
+static_assert(hana::Struct<Data3>::value, "");
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(Data1{}, BOOST_HANA_STRING("member1")));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(Data2{}, BOOST_HANA_STRING("member1")));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(Data2{}, BOOST_HANA_STRING("member2")));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(Data3{}, BOOST_HANA_STRING("member1")));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(Data3{}, BOOST_HANA_STRING("member2")));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(Data3{}, BOOST_HANA_STRING("member3")));
+}
diff --git a/src/boost/libs/hana/test/concept/struct/member_function.cpp b/src/boost/libs/hana/test/concept/struct/member_function.cpp
new file mode 100644
index 00000000..1e3ab6ec
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/member_function.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/for_each.hpp>
+#include <boost/hana/fuse.hpp>
+#include <boost/hana/fwd/accessors.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+//
+// Unit test inspired by http://stackoverflow.com/q/32678647/627587
+//
+
+struct Foo {
+ std::string get_name() const { return "louis"; }
+};
+
+namespace boost { namespace hana {
+ template <>
+ struct accessors_impl<Foo> {
+ static auto apply() {
+ return hana::make_tuple(
+ hana::make_pair(BOOST_HANA_STRING("get_name"), [](auto const& foo) {
+ return foo.get_name();
+ })
+ );
+ }
+ };
+}}
+
+int main() {
+ Foo foo;
+ hana::for_each(foo, hana::fuse([](auto /*key*/, std::string const& name) {
+ BOOST_HANA_RUNTIME_CHECK(name == "louis");
+ }));
+}
diff --git a/src/boost/libs/hana/test/concept/struct/members.cpp b/src/boost/libs/hana/test/concept/struct/members.cpp
new file mode 100644
index 00000000..1734b519
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/members.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/assert.hpp>
+#include <boost/hana/concept/struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/members.hpp>
+
+#include "minimal_struct.hpp"
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct MoveOnly {
+ MoveOnly() = default;
+ MoveOnly(MoveOnly&&) = default;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly&&) = default;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+};
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::members(obj()),
+ ::seq()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::members(obj(ct_eq<0>{})),
+ ::seq(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::members(obj(ct_eq<0>{}, ct_eq<1>{})),
+ ::seq(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::members(obj(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
+ ::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ // make sure it works with move only types
+ auto z1 = hana::members(obj(MoveOnly{}));
+ auto z2 = hana::members(obj(MoveOnly{}, MoveOnly{}));
+ (void)z1;
+ (void)z2;
+}
diff --git a/src/boost/libs/hana/test/concept/struct/minimal_struct.hpp b/src/boost/libs/hana/test/concept/struct/minimal_struct.hpp
new file mode 100644
index 00000000..4eea80df
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/minimal_struct.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_STRUCT_MINIMAL_STRUCT_HPP
+#define BOOST_HANA_TEST_STRUCT_MINIMAL_STRUCT_HPP
+
+#include <boost/hana/at.hpp>
+#include <boost/hana/fwd/accessors.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+
+
+template <int N>
+struct minimal_struct_tag;
+
+template <typename ...Members>
+struct minimal_struct_t {
+ boost::hana::tuple<Members...> members;
+ using hana_tag = minimal_struct_tag<sizeof...(Members)>;
+};
+
+struct obj_t {
+ template <typename ...Members>
+ constexpr minimal_struct_t<Members...> operator()(Members ...members) const {
+ return {{static_cast<Members&&>(members)...}};
+ }
+};
+constexpr obj_t obj{};
+
+namespace boost { namespace hana {
+ template <int N>
+ struct accessors_impl<minimal_struct_tag<N>> {
+ template <typename K>
+ struct get_member {
+ template <typename Struct>
+ constexpr decltype(auto) operator()(Struct&& s) const {
+ return hana::at_c<K::value>(static_cast<Struct&&>(s).members);
+ }
+ };
+
+ static auto apply() {
+ return hana::unpack(hana::range_c<int, 0, N>, [](auto ...k) {
+ return hana::make_tuple(
+ hana::make_pair(k, get_member<decltype(k)>{})...
+ );
+ });
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_TEST_STRUCT_MINIMAL_STRUCT_HPP
diff --git a/src/boost/libs/hana/test/concept/struct/unpack.cpp b/src/boost/libs/hana/test/concept/struct/unpack.cpp
new file mode 100644
index 00000000..30b8982f
--- /dev/null
+++ b/src/boost/libs/hana/test/concept/struct/unpack.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/concept/struct.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include "minimal_struct.hpp"
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ constexpr auto pair = ::minimal_product;
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(obj(), f),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(obj(ct_eq<0>{}), f),
+ f(pair(hana::int_c<0>, ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(obj(ct_eq<0>{}, ct_eq<1>{}), f),
+ f(pair(hana::int_c<0>, ct_eq<0>{}),
+ pair(hana::int_c<1>, ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(obj(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), f),
+ f(pair(hana::int_c<0>, ct_eq<0>{}),
+ pair(hana::int_c<1>, ct_eq<1>{}),
+ pair(hana::int_c<2>, ct_eq<2>{}))
+ ));
+}
diff --git a/src/boost/libs/hana/test/core/common.cpp b/src/boost/libs/hana/test/core/common.cpp
new file mode 100644
index 00000000..c3b24f90
--- /dev/null
+++ b/src/boost/libs/hana/test/core/common.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/core/common.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename T>
+struct ImplicitConvertibleTo {
+ constexpr operator T() const { return {}; }
+};
+
+struct T { };
+struct invalid;
+
+static_assert(std::is_same<hana::common_t<T, T>, T>{}, "");
+static_assert(std::is_same<hana::common_t<invalid, invalid>, invalid>{}, "");
+static_assert(std::is_same<hana::common_t<void, void>, void>{}, "");
+
+static_assert(std::is_same<hana::common_t<ImplicitConvertibleTo<T>, T>, T>{}, "");
+static_assert(std::is_same<hana::common_t<T, ImplicitConvertibleTo<T>>, T>{}, "");
+
+static_assert(hana::has_common<T, T>{}, "");
+static_assert(!hana::has_common<void, T>{}, "");
+static_assert(!hana::has_common<T, void>{}, "");
+static_assert(!hana::has_common<invalid, T>{}, "");
+static_assert(!hana::has_common<T, invalid>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/core/default.cpp b/src/boost/libs/hana/test/core/default.cpp
new file mode 100644
index 00000000..9846c22b
--- /dev/null
+++ b/src/boost/libs/hana/test/core/default.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/core/default.hpp>
+namespace hana = boost::hana;
+
+
+template <typename T>
+struct method_impl : hana::default_ { };
+
+template <>
+struct method_impl<int> { };
+
+static_assert(hana::is_default<method_impl<void>>{}, "");
+static_assert(!hana::is_default<method_impl<int>>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/core/is_a.cpp b/src/boost/libs/hana/test/core/is_a.cpp
new file mode 100644
index 00000000..08d39003
--- /dev/null
+++ b/src/boost/libs/hana/test/core/is_a.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/core/is_a.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // This used to trigger a compilation error on Clang 3.5.
+ {
+ auto f = [](auto i) {
+ constexpr auto result = hana::is_an<int>(i);
+ (void)result;
+ };
+ f(1);
+ }
+}
diff --git a/src/boost/libs/hana/test/core/is_embedded.cpp b/src/boost/libs/hana/test/core/is_embedded.cpp
new file mode 100644
index 00000000..12a44090
--- /dev/null
+++ b/src/boost/libs/hana/test/core/is_embedded.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/core/to.hpp>
+#include <boost/hana/equal.hpp>
+
+#include <climits>
+namespace hana = boost::hana;
+
+
+// This test makes sure that fundamental types are properly embedded in
+// each other, when sensible.
+
+static_assert(hana::is_embedded<double, long double>{}, "");
+static_assert(hana::is_embedded<float, long double>{}, "");
+static_assert(hana::is_embedded<float, double>{}, "");
+
+static_assert(hana::is_embedded<signed long, signed long long>{}, "");
+static_assert(hana::is_embedded<signed int, signed long long>{}, "");
+static_assert(hana::is_embedded<signed short, signed long long>{}, "");
+static_assert(hana::is_embedded<signed char, signed long long>{}, "");
+static_assert(hana::is_embedded<signed int, signed long>{}, "");
+static_assert(hana::is_embedded<signed short, signed long>{}, "");
+static_assert(hana::is_embedded<signed char, signed long>{}, "");
+static_assert(hana::is_embedded<signed short, signed int>{}, "");
+static_assert(hana::is_embedded<signed char, signed int>{}, "");
+static_assert(hana::is_embedded<signed char, signed short>{}, "");
+
+static_assert(hana::is_embedded<unsigned long, unsigned long long>{}, "");
+static_assert(hana::is_embedded<unsigned int, unsigned long long>{}, "");
+static_assert(hana::is_embedded<unsigned short, unsigned long long>{}, "");
+static_assert(hana::is_embedded<unsigned char, unsigned long long>{}, "");
+static_assert(hana::is_embedded<unsigned int, unsigned long>{}, "");
+static_assert(hana::is_embedded<unsigned short, unsigned long>{}, "");
+static_assert(hana::is_embedded<unsigned char, unsigned long>{}, "");
+static_assert(hana::is_embedded<unsigned short, unsigned int>{}, "");
+static_assert(hana::is_embedded<unsigned char, unsigned int>{}, "");
+static_assert(hana::is_embedded<unsigned char, unsigned short>{}, "");
+
+#if CHAR_MIN < 0 // char is signed
+
+ static_assert(hana::is_embedded<char, signed long long>{}, "");
+ static_assert(hana::is_embedded<char, signed long>{}, "");
+ static_assert(hana::is_embedded<char, signed int>{}, "");
+ static_assert(hana::is_embedded<char, signed short>{}, "");
+
+ static_assert(hana::equal('a', static_cast<signed int>('a')), "");
+
+#else // char is unsigned
+
+ static_assert(hana::is_embedded<char, unsigned long long>{}, "");
+ static_assert(hana::is_embedded<char, unsigned long>{}, "");
+ static_assert(hana::is_embedded<char, unsigned int>{}, "");
+ static_assert(hana::is_embedded<char, unsigned short>{}, "");
+
+ static_assert(hana::equal('a', static_cast<unsigned int>('a')), "");
+
+#endif
+
+
+int main() { }
diff --git a/src/boost/libs/hana/test/core/make.cpp b/src/boost/libs/hana/test/core/make.cpp
new file mode 100644
index 00000000..01677f7b
--- /dev/null
+++ b/src/boost/libs/hana/test/core/make.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/make.hpp>
+namespace hana = boost::hana;
+
+
+struct udt {
+ int value;
+ constexpr explicit udt(int v) : value(v) { }
+};
+
+static_assert(hana::make<udt>(1).value == 1, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/core/tag_of.cpp b/src/boost/libs/hana/test/core/tag_of.cpp
new file mode 100644
index 00000000..99afe5c7
--- /dev/null
+++ b/src/boost/libs/hana/test/core/tag_of.cpp
@@ -0,0 +1,74 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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 <boost/hana/core/when.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename T, typename ExpectedDatatype>
+struct test {
+ static_assert(std::is_same<hana::tag_of_t<T>, ExpectedDatatype>::value, "");
+ static_assert(std::is_same<hana::tag_of_t<T const>, ExpectedDatatype>::value, "");
+ static_assert(std::is_same<hana::tag_of_t<T volatile>, ExpectedDatatype>::value, "");
+ static_assert(std::is_same<hana::tag_of_t<T const volatile>, ExpectedDatatype>::value, "");
+
+ static_assert(std::is_same<hana::tag_of_t<T&>, ExpectedDatatype>::value, "");
+ static_assert(std::is_same<hana::tag_of_t<T const&>, ExpectedDatatype>::value, "");
+ static_assert(std::is_same<hana::tag_of_t<T volatile&>, ExpectedDatatype>::value, "");
+ static_assert(std::is_same<hana::tag_of_t<T const volatile&>, ExpectedDatatype>::value, "");
+
+ static_assert(std::is_same<hana::tag_of_t<T&&>, ExpectedDatatype>::value, "");
+ static_assert(std::is_same<hana::tag_of_t<T const&&>, ExpectedDatatype>::value, "");
+ static_assert(std::is_same<hana::tag_of_t<T volatile&&>, ExpectedDatatype>::value, "");
+ static_assert(std::is_same<hana::tag_of_t<T const volatile&&>, ExpectedDatatype>::value, "");
+};
+
+struct NestedDatatype;
+struct Nested { struct hana_tag; };
+template struct test<Nested, Nested::hana_tag>;
+
+struct NoNestedDatatype { };
+template struct test<NoNestedDatatype, NoNestedDatatype>;
+
+struct NoNestedHana { };
+template struct test<NoNestedHana, NoNestedHana>;
+
+
+struct FullySpecializedDatatype;
+struct FullySpecialized;
+namespace boost { namespace hana {
+ template <>
+ struct tag_of<FullySpecialized> {
+ using type = FullySpecializedDatatype;
+ };
+}}
+template struct test<FullySpecialized, FullySpecializedDatatype>;
+
+
+struct PartiallySpecializedDatatype;
+template <typename> struct PartiallySpecialized;
+namespace boost { namespace hana {
+ template <typename T>
+ struct tag_of<PartiallySpecialized<T>> {
+ using type = PartiallySpecializedDatatype;
+ };
+}}
+template struct test<PartiallySpecialized<struct anything>, PartiallySpecializedDatatype>;
+
+
+struct PredicatedDatatype;
+struct Predicated { static constexpr bool predicate = true; };
+namespace boost { namespace hana {
+ template <typename T>
+ struct tag_of<T, hana::when<T::predicate>> {
+ using type = PredicatedDatatype;
+ };
+}}
+template struct test<Predicated, PredicatedDatatype>;
+
+
+int main() { }
diff --git a/src/boost/libs/hana/test/core/to.cpp b/src/boost/libs/hana/test/core/to.cpp
new file mode 100644
index 00000000..f4dd54ef
--- /dev/null
+++ b/src/boost/libs/hana/test/core/to.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/core/to.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/tag_of.hpp>
+
+#include <string>
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename X, typename Y>
+constexpr auto operator==(X x, Y y)
+{ return x.value == y.value; }
+
+struct Datatype {
+ int value;
+ using hana_tag = Datatype;
+};
+
+struct Other {
+ int value;
+ using hana_tag = Datatype;
+};
+
+struct SpecializedFrom;
+struct specialized_from {
+ int value;
+ using hana_tag = SpecializedFrom;
+};
+
+struct SpecializedTo;
+struct specialized_to {
+ int value;
+ using hana_tag = SpecializedTo;
+};
+
+namespace boost { namespace hana {
+ template <>
+ struct to_impl<SpecializedTo, SpecializedFrom> {
+ template <typename T>
+ static constexpr auto apply(T t)
+ { return specialized_to{t.value}; }
+ };
+}}
+
+template <typename F, typename T>
+void check_convert(F f, T t) {
+ using From = hana::tag_of_t<F>;
+ using To = hana::tag_of_t<T>;
+
+ // Check From -> To conversion
+ BOOST_HANA_RUNTIME_CHECK(hana::to<To>(f) == t);
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(hana::to<To>(f))>, To
+ >{}, "");
+
+ static_assert(hana::is_convertible<From, To>{}, "");
+
+
+ // Make sure From -> From and To -> To are the identity.
+ BOOST_HANA_RUNTIME_CHECK(hana::to<From>(f) == f);
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(hana::to<From>(f))>, From
+ >{}, "");
+
+ BOOST_HANA_RUNTIME_CHECK(hana::to<To>(t) == t);
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(hana::to<To>(t))>, To
+ >{}, "");
+
+ static_assert(hana::is_convertible<From, From>{}, "");
+ static_assert(hana::is_convertible<To, To>{}, "");
+
+ static_assert(hana::is_embedded<From, From>{}, "");
+ static_assert(hana::is_embedded<To, To>{}, "");
+}
+
+template <typename X>
+void check_variable_template_in_dependent_context(X x) {
+ hana::to<int>(x);
+}
+
+int main() {
+ // Clang used to assert in the code generation when we used variable
+ // templates inside a lambda; this is to catch this.
+ check_variable_template_in_dependent_context(3);
+
+ check_convert("abcdef", std::string{"abcdef"});
+ check_convert(int{1}, double{1});
+ check_convert(double{1}, int{1});
+ check_convert(std::true_type{}, int{1});
+ check_convert(std::false_type{}, int{0});
+ check_convert(Datatype{1}, Datatype{1});
+ check_convert(Other{1}, Other{1});
+ check_convert(specialized_from{1}, specialized_to{1});
+
+ static_assert(!hana::is_convertible<void, int>{}, "");
+ static_assert(!hana::is_embedded<void, int>{}, "");
+
+ static_assert(hana::is_convertible<int, void>{}, "");
+ static_assert(!hana::is_embedded<int, void>{}, "");
+}
diff --git a/src/boost/libs/hana/test/core/when.cpp b/src/boost/libs/hana/test/core/when.cpp
new file mode 100644
index 00000000..c8fead5e
--- /dev/null
+++ b/src/boost/libs/hana/test/core/when.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/core/when.hpp>
+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::first_type>> { };
+
+template <typename T>
+struct base_template<T, hana::when_valid<typename T::second_type>> { };
+
+struct First { struct first_type; };
+struct Second { struct second_type; };
+
+template struct base_template<First>;
+template struct base_template<Second>;
+
+int main() { }
diff --git a/src/boost/libs/hana/test/deploy/CMakeLists.txt b/src/boost/libs/hana/test/deploy/CMakeLists.txt
new file mode 100644
index 00000000..186d5def
--- /dev/null
+++ b/src/boost/libs/hana/test/deploy/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright Louis Dionne 2013-2017
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+cmake_minimum_required(VERSION 3.0)
+project(external CXX)
+find_package(Hana REQUIRED)
+
+add_executable(main main.cpp)
+target_link_libraries(main hana)
diff --git a/src/boost/libs/hana/test/deploy/main.cpp b/src/boost/libs/hana/test/deploy/main.cpp
new file mode 100644
index 00000000..e35e8135
--- /dev/null
+++ b/src/boost/libs/hana/test/deploy/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/test/detail/algorithm.cpp b/src/boost/libs/hana/test/detail/algorithm.cpp
new file mode 100644
index 00000000..af885cea
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/algorithm.cpp
@@ -0,0 +1,56 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/algorithm.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/mult.hpp>
+namespace hana = boost::hana;
+
+
+// The algorithms are taken from the suggested implementations on cppreference.
+// Hence, we assume them to be correct and we only make sure they compile, to
+// avoid stupid mistakes I could have made when copy/pasting and editing.
+//
+// Oh, and we also make sure they can be used in a constexpr context.
+constexpr bool constexpr_context() {
+ int x = 0, y = 1;
+ hana::detail::constexpr_swap(x, y);
+
+ int array[6] = {1, 2, 3, 4, 5, 6};
+ int* first = array;
+ int* last = array + 6;
+
+ hana::detail::reverse(first, last);
+
+ hana::detail::next_permutation(first, last, hana::less);
+ hana::detail::next_permutation(first, last);
+
+ hana::detail::lexicographical_compare(first, last, first, last, hana::less);
+ hana::detail::lexicographical_compare(first, last, first, last);
+
+ hana::detail::equal(first, last, first, last, hana::equal);
+ hana::detail::equal(first, last, first, last);
+
+ hana::detail::sort(first, last, hana::equal);
+ hana::detail::sort(first, last);
+
+ hana::detail::find(first, last, 3);
+ hana::detail::find_if(first, last, hana::equal.to(3));
+
+ hana::detail::iota(first, last, 0);
+
+ hana::detail::count(first, last, 2);
+
+ hana::detail::accumulate(first, last, 0);
+ hana::detail::accumulate(first, last, 1, hana::mult);
+
+ hana::detail::min_element(first, last);
+
+ return true;
+}
+
+static_assert(constexpr_context(), "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/detail/any_of.cpp b/src/boost/libs/hana/test/detail/any_of.cpp
new file mode 100644
index 00000000..3d71cc29
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/any_of.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/detail/any_of.hpp>
+#include <boost/hana/detail/wrong.hpp>
+#include <boost/hana/integral_constant.hpp>
+namespace hana = boost::hana;
+
+
+template <typename I>
+struct is_even {
+ static constexpr bool value = I::value % 2 == 0;
+};
+
+
+static_assert(!hana::detail::any_of<is_even>::value, "");
+static_assert(!hana::detail::any_of<is_even, hana::int_<1>>::value, "");
+static_assert(!hana::detail::any_of<is_even, hana::int_<1>, hana::int_<3>>::value, "");
+static_assert(!hana::detail::any_of<is_even, hana::int_<1>, hana::int_<3>, hana::int_<5>>::value, "");
+static_assert(!hana::detail::any_of<is_even, hana::int_<1>, hana::int_<3>, hana::int_<5>, hana::int_<7>>::value, "");
+
+static_assert(hana::detail::any_of<is_even, hana::int_<0>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<0>, hana::int_<2>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<0>, hana::int_<2>, hana::int_<4>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<0>, hana::int_<2>, hana::int_<4>, hana::int_<6>>::value, "");
+
+static_assert(hana::detail::any_of<is_even, hana::int_<0>, hana::int_<1>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<0>, hana::int_<1>, hana::int_<2>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<0>, hana::int_<1>, hana::int_<2>, hana::int_<3>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<0>, hana::int_<1>, hana::int_<2>, hana::int_<3>, hana::int_<4>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<1>, hana::int_<3>, hana::int_<5>, hana::int_<8>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<1>, hana::int_<8>, hana::int_<5>, hana::int_<7>>::value, "");
+
+// Make sure we short-circuit properly
+template <typename ...Dummy>
+struct fail {
+ static_assert(hana::detail::wrong<Dummy...>::value,
+ "this must never be instantiated");
+};
+static_assert(hana::detail::any_of<is_even, hana::int_<1>, hana::int_<2>, fail<>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<1>, hana::int_<2>, fail<>, hana::int_<3>>::value, "");
+static_assert(hana::detail::any_of<is_even, hana::int_<1>, hana::int_<2>, fail<>, hana::int_<4>>::value, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/detail/canonical_constant/laws.cpp b/src/boost/libs/hana/test/detail/canonical_constant/laws.cpp
new file mode 100644
index 00000000..9dffcb52
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/canonical_constant/laws.cpp
@@ -0,0 +1,56 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/canonical_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+#include <laws/constant.hpp>
+#include <laws/euclidean_ring.hpp>
+#include <laws/group.hpp>
+#include <laws/logical.hpp>
+#include <laws/monoid.hpp>
+#include <laws/orderable.hpp>
+#include <laws/ring.hpp>
+namespace hana = boost::hana;
+
+
+template <typename T, T v>
+struct canonical {
+ static constexpr T value = v;
+ using hana_tag = hana::detail::CanonicalConstant<T>;
+};
+
+int main() {
+ auto ints = hana::make_tuple(
+ canonical<int, -10>{}, canonical<int, -2>{}, canonical<int, 0>{},
+ canonical<int, 1>{}, canonical<int, 3>{}, canonical<int, 4>{}
+ );
+
+ auto bools = hana::make_tuple(canonical<bool, true>{}, canonical<bool, false>{});
+
+ // Constant
+ hana::test::TestConstant<hana::detail::CanonicalConstant<int>>{ints, hana::tuple_t<int, long, long long>};
+ hana::test::TestConstant<hana::detail::CanonicalConstant<bool>>{bools, hana::tuple_t<bool>};
+
+ // Monoid, Group, Ring, EuclideanRing
+ hana::test::TestMonoid<hana::detail::CanonicalConstant<int>>{ints};
+ hana::test::TestGroup<hana::detail::CanonicalConstant<int>>{ints};
+ hana::test::TestRing<hana::detail::CanonicalConstant<int>>{ints};
+ hana::test::TestEuclideanRing<hana::detail::CanonicalConstant<int>>{ints};
+
+ // Logical
+ {
+ auto ints = hana::make_tuple(
+ canonical<int, -2>{}, canonical<int, 0>{},
+ canonical<int, 1>{}, canonical<int, 3>{}
+ );
+ hana::test::TestLogical<hana::detail::CanonicalConstant<int>>{ints};
+ hana::test::TestLogical<hana::detail::CanonicalConstant<bool>>{bools};
+ }
+
+ // Comparable and Orderable
+ hana::test::TestComparable<hana::detail::CanonicalConstant<int>>{ints};
+ hana::test::TestOrderable<hana::detail::CanonicalConstant<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/detail/create.cpp b/src/boost/libs/hana/test/detail/create.cpp
new file mode 100644
index 00000000..e17002f1
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/create.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/config.hpp>
+#include <boost/hana/detail/create.hpp>
+
+#include <utility>
+#include <tuple>
+namespace hana = boost::hana;
+
+
+constexpr hana::detail::create<std::tuple> make_tuple{};
+constexpr hana::detail::create<std::pair> make_pair{};
+
+template <typename ...>
+struct empty { };
+
+template <typename T>
+struct single_holder { T x; };
+
+template <typename T>
+struct identity { using type = T; };
+
+template <typename ...T>
+using identity_t = typename identity<T...>::type;
+
+int main() {
+ static_assert(make_tuple(1, '2', 3.3) == std::make_tuple(1, '2', 3.3), "");
+ static_assert(make_pair(1, '2') == std::make_pair(1, '2'), "");
+
+ // should work
+ hana::detail::create<empty>{}();
+ hana::detail::create<single_holder>{}(1);
+ hana::detail::create<single_holder>{}([]{});
+ hana::detail::create<identity_t>{}(1);
+ hana::detail::create<identity_t>{}([]{});
+}
diff --git a/src/boost/libs/hana/test/detail/decay.cpp b/src/boost/libs/hana/test/detail/decay.cpp
new file mode 100644
index 00000000..bc1ec5b6
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/decay.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/detail/decay.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename T, typename Decayed>
+void check() {
+ static_assert(std::is_same<
+ typename hana::detail::decay<T>::type,
+ Decayed
+ >::value, "");
+}
+
+int main() {
+ // void is untouched
+ check<void, void>();
+
+ // normal types lose cv-qualifiers
+ check<int, int>();
+ check<int const, int>();
+ check<int const volatile, int>();
+
+ // [cv-qualified] references are stripped
+ check<int&, int>();
+ check<int const&, int>();
+ check<int&&, int>();
+ check<int const&&, int>();
+
+ // pointers are untouched
+ check<int*, int*>();
+ check<int const*, int const*>();
+ check<int volatile*, int volatile*>();
+ check<int const volatile*, int const volatile*>();
+
+ // arrays decay to pointers
+ check<int[], int*>();
+ check<int[10], int*>();
+ check<int const[10], int const*>();
+ check<int volatile[10], int volatile*>();
+ check<int const volatile[10], int const volatile*>();
+
+ // functions decay to function pointers
+ check<void(), void(*)()>();
+ check<void(...), void (*)(...)>();
+ check<void(int), void(*)(int)>();
+ check<void(int, ...), void(*)(int, ...)>();
+ check<void(int, float), void(*)(int, float)>();
+ check<void(int, float, ...), void(*)(int, float, ...)>();
+}
diff --git a/src/boost/libs/hana/test/detail/ebo.cpp b/src/boost/libs/hana/test/detail/ebo.cpp
new file mode 100644
index 00000000..6f174be4
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/ebo.cpp
@@ -0,0 +1,95 @@
+// Copyright Louis Dionne 2013-2016
+// Distributed under the 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/ebo.hpp>
+
+#include <boost/hana/assert.hpp>
+
+#include <string>
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+using hana::detail::ebo;
+
+
+template <int> struct empty { };
+template <int> struct idx;
+#ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
+template <typename ...Bases> struct __declspec(empty_bases) inherit : Bases... { };
+#else
+template <typename ...Bases> struct inherit : Bases... { };
+#endif
+
+static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>>), "");
+static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>, ebo<idx<1>, empty<1>>>), "");
+static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>, ebo<idx<1>, empty<1>>, ebo<idx<2>, empty<2>>>), "");
+
+
+int main() {
+ // Test default-construction
+ {
+ constexpr ebo<idx<0>, int> e;
+ static_assert(hana::detail::ebo_get<idx<0>>(e) == 0, "");
+ }
+
+ // Test construction of a non-empty object
+ {
+ ebo<idx<0>, std::string> e{"foobar"};
+ BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "foobar");
+ }
+
+ {
+ ebo<idx<0>, std::string> e{};
+ BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "");
+ }
+
+ // Test construction of a non default-constructible type
+ {
+ struct nodefault {
+ nodefault() = delete;
+ explicit nodefault(char const*) { }
+ };
+ ebo<idx<0>, nodefault> e{"foobar"};
+ }
+
+ // Get lvalue, const lvalue and rvalue with a non-empty type
+ {
+ ebo<idx<0>, std::string> e{"foobar"};
+ std::string& s = hana::detail::ebo_get<idx<0>>(e);
+ BOOST_HANA_RUNTIME_CHECK(s == "foobar");
+ s = "foobaz";
+ BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "foobaz");
+ }
+
+ {
+ ebo<idx<0>, std::string> const e{"foobar"};
+ std::string const& s = hana::detail::ebo_get<idx<0>>(e);
+ BOOST_HANA_RUNTIME_CHECK(s == "foobar");
+ }
+
+ {
+ ebo<idx<0>, std::string> e{"foobar"};
+ std::string&& s = hana::detail::ebo_get<idx<0>>(std::move(e));
+ BOOST_HANA_RUNTIME_CHECK(s == "foobar");
+ }
+
+ // Get lvalue, const lvalue and rvalue with an empty type
+ {
+ ebo<idx<0>, empty<0>> e{};
+ empty<0>& s = hana::detail::ebo_get<idx<0>>(e);
+ (void)s;
+ }
+
+ {
+ ebo<idx<0>, empty<0>> const e{};
+ empty<0> const& s = hana::detail::ebo_get<idx<0>>(e);
+ (void)s;
+ }
+
+ {
+ ebo<idx<0>, empty<0>> e{};
+ empty<0>&& s = hana::detail::ebo_get<idx<0>>(std::move(e));
+ (void)s;
+ }
+}
diff --git a/src/boost/libs/hana/test/detail/fast_and.cpp b/src/boost/libs/hana/test/detail/fast_and.cpp
new file mode 100644
index 00000000..fadb168f
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/fast_and.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/detail/fast_and.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::detail::fast_and<>::value, "");
+static_assert(hana::detail::fast_and<true>::value, "");
+static_assert(!hana::detail::fast_and<false>::value, "");
+
+static_assert(hana::detail::fast_and<true, true>::value, "");
+static_assert(!hana::detail::fast_and<true, false>::value, "");
+static_assert(!hana::detail::fast_and<false, true>::value, "");
+static_assert(!hana::detail::fast_and<false, false>::value, "");
+
+static_assert(hana::detail::fast_and<true, true, true>::value, "");
+static_assert(!hana::detail::fast_and<true, true, false>::value, "");
+static_assert(!hana::detail::fast_and<true, false, true>::value, "");
+static_assert(!hana::detail::fast_and<true, false, false>::value, "");
+static_assert(!hana::detail::fast_and<false, true, true>::value, "");
+static_assert(!hana::detail::fast_and<false, true, false>::value, "");
+static_assert(!hana::detail::fast_and<false, false, true>::value, "");
+static_assert(!hana::detail::fast_and<false, false, false>::value, "");
+
+static_assert(hana::detail::fast_and<true, true, true, true, true, true>::value, "");
+static_assert(!hana::detail::fast_and<true, true, true, false, true, true>::value, "");
+static_assert(!hana::detail::fast_and<true, true, true, true, true, false>::value, "");
+static_assert(!hana::detail::fast_and<false, true, true, true, true, true>::value, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/detail/first_unsatisfied_index.cpp b/src/boost/libs/hana/test/detail/first_unsatisfied_index.cpp
new file mode 100644
index 00000000..dd2eff55
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/first_unsatisfied_index.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/detail/first_unsatisfied_index.hpp>
+
+#include <boost/hana/not_equal.hpp>
+#include <laws/base.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct poison {
+ poison() = default;
+ poison(poison const&) = delete;
+};
+
+int main() {
+ auto predicate = [](auto x) {
+ static_assert(!std::is_same<poison, decltype(x)>::value, "");
+ return hana::not_equal(x, ct_eq<9>{});
+ };
+
+ using Find = hana::detail::first_unsatisfied_index<decltype(predicate)>;
+
+ static_assert(decltype(Find{}())::value == 0, "");
+
+ static_assert(decltype(Find{}(ct_eq<9>{}))::value == 0, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}))::value == 1, "");
+
+ static_assert(decltype(Find{}(ct_eq<9>{}, poison{}))::value == 0, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}, ct_eq<9>{}))::value == 1, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}, ct_eq<1>{}))::value == 2, "");
+
+ static_assert(decltype(Find{}(ct_eq<9>{}, poison{}, poison{}))::value == 0, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}, ct_eq<9>{}, poison{}))::value == 1, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}, ct_eq<1>{}, ct_eq<9>{}))::value == 2, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))::value == 3, "");
+
+ static_assert(decltype(Find{}(ct_eq<9>{}, poison{}, poison{}, poison{}))::value == 0, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}, ct_eq<9>{}, poison{}, poison{}))::value == 1, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}, ct_eq<1>{}, ct_eq<9>{}, poison{}))::value == 2, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<9>{}))::value == 3, "");
+ static_assert(decltype(Find{}(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}))::value == 4, "");
+}
diff --git a/src/boost/libs/hana/test/detail/has_duplicates.cpp b/src/boost/libs/hana/test/detail/has_duplicates.cpp
new file mode 100644
index 00000000..fab5d7df
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/has_duplicates.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/detail/has_duplicates.hpp>
+#include <boost/hana/integral_constant.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(!hana::detail::has_duplicates<>::value, "");
+
+static_assert(!hana::detail::has_duplicates<
+ hana::int_<0>
+>::value, "");
+
+static_assert(!hana::detail::has_duplicates<
+ hana::int_<0>, hana::int_<1>
+>::value, "");
+
+static_assert(!hana::detail::has_duplicates<
+ hana::int_<0>, hana::int_<1>, hana::int_<2>
+>::value, "");
+
+static_assert(hana::detail::has_duplicates<
+ hana::int_<0>, hana::int_<0>, hana::int_<2>
+>::value, "");
+
+static_assert(hana::detail::has_duplicates<
+ hana::int_<0>, hana::int_<1>, hana::int_<0>
+>::value, "");
+
+static_assert(hana::detail::has_duplicates<
+ hana::int_<0>, hana::int_<1>, hana::int_<2>, hana::int_<1>
+>::value, "");
+
+static_assert(hana::detail::has_duplicates<
+ hana::int_<0>, hana::int_<1>, hana::int_<2>, hana::int_<2>
+>::value, "");
+
+static_assert(hana::detail::has_duplicates<
+ hana::int_<0>, hana::int_<1>, hana::int_<2>, hana::int_<1>, hana::int_<1>
+>::value, "");
+
+static_assert(hana::detail::has_duplicates<
+ hana::int_<0>, hana::int_<1>, hana::int_<2>, hana::int_<1>, hana::int_<2>
+>::value, "");
+
+// Make sure it uses deep equality
+static_assert(hana::detail::has_duplicates<
+ hana::int_<0>, hana::long_<0>, hana::int_<2>, hana::int_<3>
+>::value, "");
+
+static_assert(hana::detail::has_duplicates<
+ hana::int_<0>, hana::int_<1>, hana::int_<2>, hana::long_<1>
+>::value, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/detail/preprocessor.cpp b/src/boost/libs/hana/test/detail/preprocessor.cpp
new file mode 100644
index 00000000..0ce69549
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/preprocessor.cpp
@@ -0,0 +1,65 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/detail/preprocessor.hpp>
+
+#include <string>
+#include <vector>
+
+
+//////////////////////////////////////////////////////////////////////////////
+// BOOST_HANA_PP_CONCAT
+//////////////////////////////////////////////////////////////////////////////
+static_assert(BOOST_HANA_PP_CONCAT(1, 2) == 12, "");
+
+//////////////////////////////////////////////////////////////////////////////
+// BOOST_HANA_PP_FRONT
+//////////////////////////////////////////////////////////////////////////////
+static_assert(BOOST_HANA_PP_FRONT(0) == 0, "");
+static_assert(BOOST_HANA_PP_FRONT(0, 1) == 0, "");
+static_assert(BOOST_HANA_PP_FRONT(0, 1, 2) == 0, "");
+static_assert(BOOST_HANA_PP_FRONT(0, 1, 2, 3) == 0, "");
+
+static_assert(BOOST_HANA_PP_FRONT(0, 1, 2, 3, 4, 5, 6, 6, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 16, 18) == 0, "");
+
+static_assert(BOOST_HANA_PP_FRONT(0, 1, 2, 3, 4, 5, 6, 6, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 16, 18, 19) == 0, "");
+
+
+int main() {
+ using Vector = std::vector<int>;
+
+ //////////////////////////////////////////////////////////////////////////
+ // BOOST_HANA_PP_STRINGIZE
+ //////////////////////////////////////////////////////////////////////////
+ {
+ constexpr char const* xyz = BOOST_HANA_PP_STRINGIZE(xyz);
+ BOOST_HANA_RUNTIME_CHECK(std::string{xyz} == "xyz");
+ }{
+ constexpr char const* xyz = BOOST_HANA_PP_STRINGIZE(foo{bar, baz});
+ BOOST_HANA_RUNTIME_CHECK(std::string{xyz} == "foo{bar, baz}");
+ }{
+ constexpr char const* xyz = BOOST_HANA_PP_STRINGIZE(foo, bar, baz);
+ BOOST_HANA_RUNTIME_CHECK(std::string{xyz} == "foo, bar, baz");
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // BOOST_HANA_PP_DROP_FRONT
+ //////////////////////////////////////////////////////////////////////////
+ {
+ Vector args = {BOOST_HANA_PP_DROP_FRONT(0, 1)};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{1});
+ }{
+ Vector args = {BOOST_HANA_PP_DROP_FRONT(0, 1, 2)};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{1, 2});
+ }{
+ Vector args = {BOOST_HANA_PP_DROP_FRONT(0, 1, 2, 3)};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{1, 2, 3});
+ }{
+ Vector args = {BOOST_HANA_PP_DROP_FRONT(0, 1, 2, 3, 4)};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{1, 2, 3, 4});
+ }
+}
diff --git a/src/boost/libs/hana/test/detail/struct_macros.cpp b/src/boost/libs/hana/test/detail/struct_macros.cpp
new file mode 100644
index 00000000..71904ac4
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/struct_macros.cpp
@@ -0,0 +1,108 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/detail/struct_macros.hpp>
+
+#include <string>
+#include <vector>
+
+
+//////////////////////////////////////////////////////////////////////////////
+// BOOST_HANA_PP_NARG
+//////////////////////////////////////////////////////////////////////////////
+static_assert(BOOST_HANA_PP_NARG(x) == 1, "");
+static_assert(BOOST_HANA_PP_NARG(x, x) == 2, "");
+static_assert(BOOST_HANA_PP_NARG(x, x, x) == 3, "");
+static_assert(BOOST_HANA_PP_NARG(x, x, x, x) == 4, "");
+static_assert(BOOST_HANA_PP_NARG(
+ x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x) == 38, "");
+static_assert(BOOST_HANA_PP_NARG(
+ x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x) == 39, "");
+static_assert(BOOST_HANA_PP_NARG(
+ x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x,
+ x, x, x, x, x, x, x, x, x, x) == 40, "");
+
+
+//////////////////////////////////////////////////////////////////////////////
+// BOOST_HANA_PP_BACK
+//////////////////////////////////////////////////////////////////////////////
+static_assert(BOOST_HANA_PP_BACK(1) == 1, "");
+static_assert(BOOST_HANA_PP_BACK(1, 2) == 2, "");
+static_assert(BOOST_HANA_PP_BACK(1, 2, 3) == 3, "");
+static_assert(BOOST_HANA_PP_BACK(1, 2, 3, 4) == 4, "");
+
+static_assert(BOOST_HANA_PP_BACK(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39) == 39, "");
+
+static_assert(BOOST_HANA_PP_BACK(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38) == 38, "");
+
+static_assert(BOOST_HANA_PP_BACK(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40) == 40, "");
+
+
+int main() {
+ using Vector = std::vector<int>;
+
+ //////////////////////////////////////////////////////////////////////////
+ // BOOST_HANA_PP_DROP_BACK
+ //////////////////////////////////////////////////////////////////////////
+ {
+ Vector args = {BOOST_HANA_PP_DROP_BACK(1)};
+ BOOST_HANA_RUNTIME_CHECK(args.empty());
+ }{
+ Vector args = {BOOST_HANA_PP_DROP_BACK(1, 2)};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{1});
+ }{
+ Vector args = {BOOST_HANA_PP_DROP_BACK(1, 2, 3)};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{1, 2});
+ }{
+ Vector args = {BOOST_HANA_PP_DROP_BACK(1, 2, 3, 4)};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{1, 2, 3});
+ }{
+ Vector args = {BOOST_HANA_PP_DROP_BACK(1, 2, 3, 4, 5)};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{1, 2, 3, 4});
+ }{
+ Vector args = {BOOST_HANA_PP_DROP_BACK(
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39
+ )};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38
+ });
+ }{
+ Vector args = {BOOST_HANA_PP_DROP_BACK(
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40
+ )};
+ BOOST_HANA_RUNTIME_CHECK(args == Vector{
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39
+ });
+ }
+}
diff --git a/src/boost/libs/hana/test/detail/type_at.cpp b/src/boost/libs/hana/test/detail/type_at.cpp
new file mode 100644
index 00000000..3297a55e
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/type_at.cpp
@@ -0,0 +1,102 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/type_at.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <int>
+struct x;
+
+static_assert(std::is_same<
+ hana::detail::type_at<0, x<0>>::type,
+ x<0>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<0, x<0>, x<1>>::type,
+ x<0>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<0, x<0>, x<1>, x<2>>::type,
+ x<0>
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_at<1, x<0>, x<1>>::type,
+ x<1>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<1, x<0>, x<1>, x<2>>::type,
+ x<1>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<1, x<0>, x<1>, x<2>, x<3>>::type,
+ x<1>
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_at<2, x<0>, x<1>, x<2>>::type,
+ x<2>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<2, x<0>, x<1>, x<2>, x<3>>::type,
+ x<2>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<2, x<0>, x<1>, x<2>, x<3>, x<4>>::type,
+ x<2>
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_at<3, x<0>, x<1>, x<2>, x<3>>::type,
+ x<3>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<3, x<0>, x<1>, x<2>, x<3>, x<4>>::type,
+ x<3>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<3, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>>::type,
+ x<3>
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_at<4, x<0>, x<1>, x<2>, x<3>, x<4>>::type,
+ x<4>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<4, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>>::type,
+ x<4>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<4, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>>::type,
+ x<4>
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_at<5, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>>::type,
+ x<5>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<5, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>>::type,
+ x<5>
+>{}, "");
+static_assert(std::is_same<
+ hana::detail::type_at<5, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>, x<7>>::type,
+ x<5>
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_at<6, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>>::type,
+ x<6>
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_at<7, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>, x<7>>::type,
+ x<7>
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/detail/type_foldl1.cpp b/src/boost/libs/hana/test/detail/type_foldl1.cpp
new file mode 100644
index 00000000..47c58572
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/type_foldl1.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/detail/type_foldl1.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename state, typename x>
+struct f {
+ struct type;
+};
+
+template <int>
+struct x;
+
+static_assert(std::is_same<
+ hana::detail::type_foldl1<f, x<0>>::type,
+ x<0>
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldl1<f, x<0>, x<1>>::type,
+ f<x<0>, x<1>>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldl1<f, x<0>, x<1>, x<2>>::type,
+ f<f<x<0>, x<1>>::type, x<2>>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldl1<f, x<0>, x<1>, x<2>, x<3>>::type,
+ f<f<f<x<0>, x<1>>::type, x<2>>::type, x<3>>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldl1<f, x<0>, x<1>, x<2>, x<3>, x<4>>::type,
+ f<f<f<f<x<0>, x<1>>::type, x<2>>::type, x<3>>::type, x<4>>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldl1<f, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>>::type,
+ f<f<f<f<f<x<0>, x<1>>::type, x<2>>::type, x<3>>::type, x<4>>::type, x<5>>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldl1<f, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>>::type,
+ f<f<f<f<f<f<x<0>, x<1>>::type, x<2>>::type, x<3>>::type, x<4>>::type, x<5>>::type, x<6>>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldl1<f, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>, x<7>>::type,
+ f<f<f<f<f<f<f<x<0>, x<1>>::type, x<2>>::type, x<3>>::type, x<4>>::type, x<5>>::type, x<6>>::type, x<7>>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldl1<f, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>, x<7>, x<8>>::type,
+ f<f<f<f<f<f<f<f<x<0>, x<1>>::type, x<2>>::type, x<3>>::type, x<4>>::type, x<5>>::type, x<6>>::type, x<7>>::type, x<8>>::type
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/detail/type_foldr1.cpp b/src/boost/libs/hana/test/detail/type_foldr1.cpp
new file mode 100644
index 00000000..eefa6a99
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/type_foldr1.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/detail/type_foldr1.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename x, typename state>
+struct f {
+ struct type;
+};
+
+template <int>
+struct x;
+
+static_assert(std::is_same<
+ hana::detail::type_foldr1<f, x<0>>::type,
+ x<0>
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldr1<f, x<0>, x<1>>::type,
+ f<x<0>, x<1>>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldr1<f, x<0>, x<1>, x<2>>::type,
+ f<x<0>, f<x<1>, x<2>>::type>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldr1<f, x<0>, x<1>, x<2>, x<3>>::type,
+ f<x<0>, f<x<1>, f<x<2>, x<3>>::type>::type>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldr1<f, x<0>, x<1>, x<2>, x<3>, x<4>>::type,
+ f<x<0>, f<x<1>, f<x<2>, f<x<3>, x<4>>::type>::type>::type>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldr1<f, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>>::type,
+ f<x<0>, f<x<1>, f<x<2>, f<x<3>, f<x<4>, x<5>>::type>::type>::type>::type>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldr1<f, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>>::type,
+ f<x<0>, f<x<1>, f<x<2>, f<x<3>, f<x<4>, f<x<5>, x<6>>::type>::type>::type>::type>::type>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldr1<f, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>, x<7>>::type,
+ f<x<0>, f<x<1>, f<x<2>, f<x<3>, f<x<4>, f<x<5>, f<x<6>, x<7>>::type>::type>::type>::type>::type>::type>::type
+>{}, "");
+
+static_assert(std::is_same<
+ hana::detail::type_foldr1<f, x<0>, x<1>, x<2>, x<3>, x<4>, x<5>, x<6>, x<7>, x<8>>::type,
+ f<x<0>, f<x<1>, f<x<2>, f<x<3>, f<x<4>, f<x<5>, f<x<6>, f<x<7>, x<8>>::type>::type>::type>::type>::type>::type>::type>::type
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/detail/unpack_flatten.cpp b/src/boost/libs/hana/test/detail/unpack_flatten.cpp
new file mode 100644
index 00000000..d6002c96
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/unpack_flatten.cpp
@@ -0,0 +1,114 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/detail/unpack_flatten.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ constexpr auto f = hana::test::_injection<0>{};
+
+ {
+ auto tuples = hana::make_tuple();
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f()
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple());
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f()
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple(), hana::make_tuple());
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f()
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple(),
+ hana::make_tuple(),
+ hana::make_tuple());
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f()
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple(ct_eq<0>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f(ct_eq<0>{})
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple(),
+ hana::make_tuple(ct_eq<0>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f(ct_eq<0>{})
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple(),
+ hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple(ct_eq<0>{}),
+ hana::make_tuple(ct_eq<1>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple(ct_eq<0>{}),
+ hana::make_tuple(ct_eq<1>{}),
+ hana::make_tuple(ct_eq<2>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ }
+
+ {
+ auto tuples = hana::make_tuple(hana::make_tuple(ct_eq<0>{}),
+ hana::make_tuple(ct_eq<1>{}),
+ hana::make_tuple(ct_eq<2>{}, ct_eq<3>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::detail::unpack_flatten(tuples, f),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/detail/variadic/at.cpp b/src/boost/libs/hana/test/detail/variadic/at.cpp
new file mode 100644
index 00000000..ddb4bddc
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/variadic/at.cpp
@@ -0,0 +1,93 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/variadic/at.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+namespace vd = hana::detail::variadic;
+using hana::test::ct_eq;
+
+
+struct non_pod { virtual ~non_pod() { } };
+
+template <int i> struct y { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<0>(ct_eq<0>{}),
+ ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<0>(ct_eq<0>{}, ct_eq<1>{}),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<1>(y<0>{}, ct_eq<1>{}),
+ ct_eq<1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<0>(ct_eq<0>{}, y<1>{}, y<2>{}),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<1>(y<0>{}, ct_eq<1>{}, y<2>{}),
+ ct_eq<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<2>(y<0>{}, y<1>{}, ct_eq<2>{}),
+ ct_eq<2>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<0>(ct_eq<0>{}, y<1>{}, y<2>{}, y<3>{}),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<1>(y<0>{}, ct_eq<1>{}, y<2>{}, y<3>{}),
+ ct_eq<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<2>(y<0>{}, y<1>{}, ct_eq<2>{}, y<3>{}),
+ ct_eq<2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<3>(y<0>{}, y<1>{}, y<2>{}, ct_eq<3>{}),
+ ct_eq<3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<0>(ct_eq<0>{}, y<1>{}, y<2>{}, y<3>{}, y<4>{}),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<1>(y<0>{}, ct_eq<1>{}, y<2>{}, y<3>{}, y<4>{}),
+ ct_eq<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<2>(y<0>{}, y<1>{}, ct_eq<2>{}, y<3>{}, y<4>{}),
+ ct_eq<2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<3>(y<0>{}, y<1>{}, y<2>{}, ct_eq<3>{}, y<4>{}),
+ ct_eq<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::at<4>(y<0>{}, y<1>{}, y<2>{}, y<3>{}, ct_eq<4>{}),
+ ct_eq<4>{}
+ ));
+
+ // make sure we can use non-pods on both side of the fetched object
+ vd::at<0>(ct_eq<0>{}, non_pod{});
+ vd::at<1>(non_pod{}, ct_eq<1>{});
+
+ // make sure it works with const objects
+ int const i = 1;
+ vd::at<0>(i);
+}
diff --git a/src/boost/libs/hana/test/detail/variadic/drop_into.cpp b/src/boost/libs/hana/test/detail/variadic/drop_into.cpp
new file mode 100644
index 00000000..8c4aecb5
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/variadic/drop_into.cpp
@@ -0,0 +1,78 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/variadic/drop_into.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+namespace vd = hana::detail::variadic;
+using hana::test::ct_eq;
+
+
+struct non_pod { virtual ~non_pod() { } };
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<0>(f)(),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<0>(f)(ct_eq<0>{}),
+ f(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<0>(f)(ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<0>(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<1>(f)(ct_eq<0>{}),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<1>(f)(ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<1>(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<1>(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<2>(f)(ct_eq<0>{}, ct_eq<1>{}),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<2>(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<2>(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::drop_into<2>(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ f(ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ ));
+
+ // make sure we can use non-pods
+ vd::drop_into<1>(f)(ct_eq<0>{}, non_pod{});
+ vd::drop_into<1>(f)(non_pod{}, ct_eq<1>{});
+}
diff --git a/src/boost/libs/hana/test/detail/variadic/foldl1.cpp b/src/boost/libs/hana/test/detail/variadic/foldl1.cpp
new file mode 100644
index 00000000..e0ded2c8
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/variadic/foldl1.cpp
@@ -0,0 +1,212 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/variadic/foldl1.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+struct undefined { };
+
+template <int i>
+using x = hana::test::ct_eq<i>;
+
+int main() {
+ using hana::detail::variadic::foldl1;
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(undefined{}, x<1>{}),
+ x<1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}),
+ f(x<1>{}, x<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}),
+ f(f(x<1>{}, x<2>{}), x<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}),
+ f(f(f(x<1>{}, x<2>{}), x<3>{}), x<4>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}),
+ f(f(f(f(x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}),
+ f(f(f(f(f(x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{}),
+ f(f(f(f(f(f(x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{}, x<8>{}),
+ f(f(f(f(f(f(f(x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}), x<8>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}
+ ),
+ f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{})
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}
+ ),
+ f(f(f(f(f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{}), x<10>{}), x<11>{}), x<12>{}), x<13>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{}
+ ),
+ f(f(f(f(f(f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{}), x<10>{}), x<11>{}), x<12>{}), x<13>{}), x<14>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}
+ ),
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{}), x<10>{}), x<11>{}), x<12>{}), x<13>{}), x<14>{}),
+ x<15>{})
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}
+ ),
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{}), x<10>{}), x<11>{}), x<12>{}), x<13>{}), x<14>{}),
+ x<15>{}), x<16>{}), x<17>{}), x<18>{}), x<19>{}), x<20>{}), x<21>{}),
+ x<22>{}), x<23>{}), x<24>{}), x<25>{}), x<26>{}), x<27>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{}
+ ),
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{}), x<10>{}), x<11>{}), x<12>{}), x<13>{}), x<14>{}),
+ x<15>{}), x<16>{}), x<17>{}), x<18>{}), x<19>{}), x<20>{}), x<21>{}),
+ x<22>{}), x<23>{}), x<24>{}), x<25>{}), x<26>{}), x<27>{}), x<28>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{},
+ x<29>{}
+ ),
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{}), x<10>{}), x<11>{}), x<12>{}), x<13>{}), x<14>{}),
+ x<15>{}), x<16>{}), x<17>{}), x<18>{}), x<19>{}), x<20>{}), x<21>{}),
+ x<22>{}), x<23>{}), x<24>{}), x<25>{}), x<26>{}), x<27>{}), x<28>{}),
+ x<29>{})
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{},
+ x<29>{}, x<30>{}, x<31>{}, x<32>{}, x<33>{}, x<34>{}, x<35>{},
+ x<36>{}, x<37>{}, x<38>{}, x<39>{}, x<40>{}, x<41>{}, x<42>{},
+ x<43>{}, x<44>{}, x<45>{}, x<46>{}, x<47>{}, x<48>{}, x<49>{},
+ x<50>{}, x<51>{}, x<52>{}, x<53>{}, x<54>{}, x<55>{}
+ ),
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{}), x<10>{}), x<11>{}), x<12>{}), x<13>{}), x<14>{}),
+ x<15>{}), x<16>{}), x<17>{}), x<18>{}), x<19>{}), x<20>{}), x<21>{}),
+ x<22>{}), x<23>{}), x<24>{}), x<25>{}), x<26>{}), x<27>{}), x<28>{}),
+ x<29>{}), x<30>{}), x<31>{}), x<32>{}), x<33>{}), x<34>{}), x<35>{}),
+ x<36>{}), x<37>{}), x<38>{}), x<39>{}), x<40>{}), x<41>{}), x<42>{}),
+ x<43>{}), x<44>{}), x<45>{}), x<46>{}), x<47>{}), x<48>{}), x<49>{}),
+ x<50>{}), x<51>{}), x<52>{}), x<53>{}), x<54>{}), x<55>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{},
+ x<29>{}, x<30>{}, x<31>{}, x<32>{}, x<33>{}, x<34>{}, x<35>{},
+ x<36>{}, x<37>{}, x<38>{}, x<39>{}, x<40>{}, x<41>{}, x<42>{},
+ x<43>{}, x<44>{}, x<45>{}, x<46>{}, x<47>{}, x<48>{}, x<49>{},
+ x<50>{}, x<51>{}, x<52>{}, x<53>{}, x<54>{}, x<55>{}, x<56>{}
+ ),
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{}), x<10>{}), x<11>{}), x<12>{}), x<13>{}), x<14>{}),
+ x<15>{}), x<16>{}), x<17>{}), x<18>{}), x<19>{}), x<20>{}), x<21>{}),
+ x<22>{}), x<23>{}), x<24>{}), x<25>{}), x<26>{}), x<27>{}), x<28>{}),
+ x<29>{}), x<30>{}), x<31>{}), x<32>{}), x<33>{}), x<34>{}), x<35>{}),
+ x<36>{}), x<37>{}), x<38>{}), x<39>{}), x<40>{}), x<41>{}), x<42>{}),
+ x<43>{}), x<44>{}), x<45>{}), x<46>{}), x<47>{}), x<48>{}), x<49>{}),
+ x<50>{}), x<51>{}), x<52>{}), x<53>{}), x<54>{}), x<55>{}), x<56>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldl1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{},
+ x<29>{}, x<30>{}, x<31>{}, x<32>{}, x<33>{}, x<34>{}, x<35>{},
+ x<36>{}, x<37>{}, x<38>{}, x<39>{}, x<40>{}, x<41>{}, x<42>{},
+ x<43>{}, x<44>{}, x<45>{}, x<46>{}, x<47>{}, x<48>{}, x<49>{},
+ x<50>{}, x<51>{}, x<52>{}, x<53>{}, x<54>{}, x<55>{}, x<56>{},
+ x<57>{}
+ ),
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
+ x<1>{}, x<2>{}), x<3>{}), x<4>{}), x<5>{}), x<6>{}), x<7>{}),
+ x<8>{}), x<9>{}), x<10>{}), x<11>{}), x<12>{}), x<13>{}), x<14>{}),
+ x<15>{}), x<16>{}), x<17>{}), x<18>{}), x<19>{}), x<20>{}), x<21>{}),
+ x<22>{}), x<23>{}), x<24>{}), x<25>{}), x<26>{}), x<27>{}), x<28>{}),
+ x<29>{}), x<30>{}), x<31>{}), x<32>{}), x<33>{}), x<34>{}), x<35>{}),
+ x<36>{}), x<37>{}), x<38>{}), x<39>{}), x<40>{}), x<41>{}), x<42>{}),
+ x<43>{}), x<44>{}), x<45>{}), x<46>{}), x<47>{}), x<48>{}), x<49>{}),
+ x<50>{}), x<51>{}), x<52>{}), x<53>{}), x<54>{}), x<55>{}), x<56>{}),
+ x<57>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/detail/variadic/foldr1.cpp b/src/boost/libs/hana/test/detail/variadic/foldr1.cpp
new file mode 100644
index 00000000..1d7d91ed
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/variadic/foldr1.cpp
@@ -0,0 +1,207 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/variadic/foldr1.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/value.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+struct undefined { };
+
+template <int i>
+using x = hana::test::ct_eq<i>;
+
+// We do not use test::_injection here because comparing the result would
+// blow away the template recursion limit.
+struct f_t {
+ template <typename X, typename Y>
+ constexpr auto operator()(X const&, Y const&) {
+ return x<hana::value<X>() - hana::value<Y>()>{};
+ }
+};
+
+int main() {
+ using hana::detail::variadic::foldr1;
+ f_t f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(undefined{}, x<0>{}),
+ x<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<0>{}, x<1>{}),
+ f(x<0>{}, x<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<0>{}, x<1>{}, x<2>{}),
+ f(x<0>{}, f(x<1>{}, x<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<0>{}, x<1>{}, x<2>{}, x<3>{}),
+ f(x<0>{}, f(x<1>{}, f(x<2>{}, x<3>{})))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<0>{}, x<1>{}, x<2>{}, x<3>{}, x<4>{}),
+ f(x<0>{}, f(x<1>{}, f(x<2>{}, f(x<3>{}, x<4>{}))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<0>{}, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}),
+ f(x<0>{}, f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, x<5>{})))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<0>{}, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}),
+ f(x<0>{}, f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, x<6>{}))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<0>{}, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{}),
+ f(x<0>{}, f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, x<7>{}
+ )))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<0>{}, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{}, x<8>{}),
+ f(x<0>{}, f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{}, x<8>{}
+ ))))))))
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{},
+ f(x<8>{}, f(x<9>{}, f(x<10>{}, f(x<11>{}, f(x<12>{}, x<13>{}
+ ))))))))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{}),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{},
+ f(x<8>{}, f(x<9>{}, f(x<10>{}, f(x<11>{}, f(x<12>{}, f(x<13>{}, x<14>{}
+ )))))))))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{},
+ f(x<8>{}, f(x<9>{}, f(x<10>{}, f(x<11>{}, f(x<12>{}, f(x<13>{}, f(x<14>{}, x<15>{}
+ ))))))))))))))
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{},
+ f(x<8>{}, f(x<9>{}, f(x<10>{}, f(x<11>{}, f(x<12>{}, f(x<13>{}, f(x<14>{},
+ f(x<15>{}, f(x<16>{}, f(x<17>{}, f(x<18>{}, f(x<19>{}, f(x<20>{}, f(x<21>{},
+ f(x<22>{}, f(x<23>{}, f(x<24>{}, f(x<25>{}, f(x<26>{}, x<27>{}
+ ))))))))))))))))))))))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{}),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{},
+ f(x<8>{}, f(x<9>{}, f(x<10>{}, f(x<11>{}, f(x<12>{}, f(x<13>{}, f(x<14>{},
+ f(x<15>{}, f(x<16>{}, f(x<17>{}, f(x<18>{}, f(x<19>{}, f(x<20>{}, f(x<21>{},
+ f(x<22>{}, f(x<23>{}, f(x<24>{}, f(x<25>{}, f(x<26>{}, f(x<27>{}, x<28>{}
+ )))))))))))))))))))))))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{},
+ x<29>{}),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{},
+ f(x<8>{}, f(x<9>{}, f(x<10>{}, f(x<11>{}, f(x<12>{}, f(x<13>{}, f(x<14>{},
+ f(x<15>{}, f(x<16>{}, f(x<17>{}, f(x<18>{}, f(x<19>{}, f(x<20>{}, f(x<21>{},
+ f(x<22>{}, f(x<23>{}, f(x<24>{}, f(x<25>{}, f(x<26>{}, f(x<27>{}, f(x<28>{},
+ x<29>{}
+ ))))))))))))))))))))))))))))
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{},
+ x<29>{}, x<30>{}, x<31>{}, x<32>{}, x<33>{}, x<34>{}, x<35>{},
+ x<36>{}, x<37>{}, x<38>{}, x<39>{}, x<40>{}, x<41>{}, x<42>{},
+ x<43>{}, x<44>{}, x<45>{}, x<46>{}, x<47>{}, x<48>{}, x<49>{},
+ x<50>{}, x<51>{}, x<52>{}, x<53>{}, x<54>{}, x<55>{}),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{},
+ f(x<8>{}, f(x<9>{}, f(x<10>{}, f(x<11>{}, f(x<12>{}, f(x<13>{}, f(x<14>{},
+ f(x<15>{}, f(x<16>{}, f(x<17>{}, f(x<18>{}, f(x<19>{}, f(x<20>{}, f(x<21>{},
+ f(x<22>{}, f(x<23>{}, f(x<24>{}, f(x<25>{}, f(x<26>{}, f(x<27>{}, f(x<28>{},
+ f(x<29>{}, f(x<30>{}, f(x<31>{}, f(x<32>{}, f(x<33>{}, f(x<34>{}, f(x<35>{},
+ f(x<36>{}, f(x<37>{}, f(x<38>{}, f(x<39>{}, f(x<40>{}, f(x<41>{}, f(x<42>{},
+ f(x<43>{}, f(x<44>{}, f(x<45>{}, f(x<46>{}, f(x<47>{}, f(x<48>{}, f(x<49>{},
+ f(x<50>{}, f(x<51>{}, f(x<52>{}, f(x<53>{}, f(x<54>{}, x<55>{}
+ ))))))))))))))))))))))))))))))))))))))))))))))))))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{},
+ x<29>{}, x<30>{}, x<31>{}, x<32>{}, x<33>{}, x<34>{}, x<35>{},
+ x<36>{}, x<37>{}, x<38>{}, x<39>{}, x<40>{}, x<41>{}, x<42>{},
+ x<43>{}, x<44>{}, x<45>{}, x<46>{}, x<47>{}, x<48>{}, x<49>{},
+ x<50>{}, x<51>{}, x<52>{}, x<53>{}, x<54>{}, x<55>{}, x<56>{}),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{},
+ f(x<8>{}, f(x<9>{}, f(x<10>{}, f(x<11>{}, f(x<12>{}, f(x<13>{}, f(x<14>{},
+ f(x<15>{}, f(x<16>{}, f(x<17>{}, f(x<18>{}, f(x<19>{}, f(x<20>{}, f(x<21>{},
+ f(x<22>{}, f(x<23>{}, f(x<24>{}, f(x<25>{}, f(x<26>{}, f(x<27>{}, f(x<28>{},
+ f(x<29>{}, f(x<30>{}, f(x<31>{}, f(x<32>{}, f(x<33>{}, f(x<34>{}, f(x<35>{},
+ f(x<36>{}, f(x<37>{}, f(x<38>{}, f(x<39>{}, f(x<40>{}, f(x<41>{}, f(x<42>{},
+ f(x<43>{}, f(x<44>{}, f(x<45>{}, f(x<46>{}, f(x<47>{}, f(x<48>{}, f(x<49>{},
+ f(x<50>{}, f(x<51>{}, f(x<52>{}, f(x<53>{}, f(x<54>{}, f(x<55>{}, x<56>{}
+ )))))))))))))))))))))))))))))))))))))))))))))))))))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ foldr1(f, x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}, x<6>{}, x<7>{},
+ x<8>{}, x<9>{}, x<10>{}, x<11>{}, x<12>{}, x<13>{}, x<14>{},
+ x<15>{}, x<16>{}, x<17>{}, x<18>{}, x<19>{}, x<20>{}, x<21>{},
+ x<22>{}, x<23>{}, x<24>{}, x<25>{}, x<26>{}, x<27>{}, x<28>{},
+ x<29>{}, x<30>{}, x<31>{}, x<32>{}, x<33>{}, x<34>{}, x<35>{},
+ x<36>{}, x<37>{}, x<38>{}, x<39>{}, x<40>{}, x<41>{}, x<42>{},
+ x<43>{}, x<44>{}, x<45>{}, x<46>{}, x<47>{}, x<48>{}, x<49>{},
+ x<50>{}, x<51>{}, x<52>{}, x<53>{}, x<54>{}, x<55>{}, x<56>{},
+ x<57>{}),
+ f(x<1>{}, f(x<2>{}, f(x<3>{}, f(x<4>{}, f(x<5>{}, f(x<6>{}, f(x<7>{},
+ f(x<8>{}, f(x<9>{}, f(x<10>{}, f(x<11>{}, f(x<12>{}, f(x<13>{}, f(x<14>{},
+ f(x<15>{}, f(x<16>{}, f(x<17>{}, f(x<18>{}, f(x<19>{}, f(x<20>{}, f(x<21>{},
+ f(x<22>{}, f(x<23>{}, f(x<24>{}, f(x<25>{}, f(x<26>{}, f(x<27>{}, f(x<28>{},
+ f(x<29>{}, f(x<30>{}, f(x<31>{}, f(x<32>{}, f(x<33>{}, f(x<34>{}, f(x<35>{},
+ f(x<36>{}, f(x<37>{}, f(x<38>{}, f(x<39>{}, f(x<40>{}, f(x<41>{}, f(x<42>{},
+ f(x<43>{}, f(x<44>{}, f(x<45>{}, f(x<46>{}, f(x<47>{}, f(x<48>{}, f(x<49>{},
+ f(x<50>{}, f(x<51>{}, f(x<52>{}, f(x<53>{}, f(x<54>{}, f(x<55>{}, f(x<56>{},
+ x<57>{}
+ ))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+ ));
+}
diff --git a/src/boost/libs/hana/test/detail/variadic/reverse_apply.cpp b/src/boost/libs/hana/test/detail/variadic/reverse_apply.cpp
new file mode 100644
index 00000000..60305f3a
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/variadic/reverse_apply.cpp
@@ -0,0 +1,70 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/variadic/reverse_apply.hpp>
+#include <boost/hana/detail/variadic/reverse_apply/flat.hpp>
+#include <boost/hana/detail/variadic/reverse_apply/unrolled.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+auto check = [](auto reverse_apply) {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f, ct_eq<0>{}),
+ f(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f, ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ f(ct_eq<4>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}),
+ f(ct_eq<5>{}, ct_eq<4>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}),
+ f(ct_eq<6>{}, ct_eq<5>{}, ct_eq<4>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}),
+ f(ct_eq<7>{}, ct_eq<6>{}, ct_eq<5>{}, ct_eq<4>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ reverse_apply(f, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}),
+ f(ct_eq<8>{}, ct_eq<7>{}, ct_eq<6>{}, ct_eq<5>{}, ct_eq<4>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{})
+ ));
+};
+
+int main() {
+ check(hana::detail::variadic::reverse_apply);
+ check([](auto f, auto ...x) {
+ return hana::detail::variadic::reverse_apply_flat(f, x...);
+ });
+ check([](auto f, auto ...x) {
+ return hana::detail::variadic::reverse_apply_unrolled(f, x...);
+ });
+}
diff --git a/src/boost/libs/hana/test/detail/variadic/split_at.cpp b/src/boost/libs/hana/test/detail/variadic/split_at.cpp
new file mode 100644
index 00000000..e33872a5
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/variadic/split_at.cpp
@@ -0,0 +1,168 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/variadic/split_at.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+namespace vd = hana::detail::variadic;
+using hana::test::ct_eq;
+
+
+auto check = [](auto split, auto xs, auto ys) {
+ auto result = split([](auto ...xs) {
+ return [=](auto ...ys) {
+ return hana::make_pair(hana::make_tuple(xs...), hana::make_tuple(ys...));
+ };
+ });
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(xs, hana::first(result)));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(ys, hana::second(result)));
+};
+
+int main() {
+ {
+ check(
+ vd::split_at<0>(),
+ hana::make_tuple(),
+ hana::make_tuple()
+ );
+
+ check(
+ vd::split_at<0>(ct_eq<1>{}),
+ hana::make_tuple(),
+ hana::make_tuple(ct_eq<1>{})
+ );
+
+ check(
+ vd::split_at<0>(ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_tuple(),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{})
+ );
+
+ check(
+ vd::split_at<0>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::make_tuple(),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ );
+ }
+ {
+ check(
+ vd::split_at<1>(ct_eq<1>{}),
+ hana::make_tuple(ct_eq<1>{}),
+ hana::make_tuple()
+ );
+
+ check(
+ vd::split_at<1>(ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_tuple(ct_eq<1>{}),
+ hana::make_tuple(ct_eq<2>{})
+ );
+
+ check(
+ vd::split_at<1>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::make_tuple(ct_eq<1>{}),
+ hana::make_tuple(ct_eq<2>{}, ct_eq<3>{})
+ );
+
+ check(
+ vd::split_at<1>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::make_tuple(ct_eq<1>{}),
+ hana::make_tuple(ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ );
+ }
+ {
+ check(
+ vd::split_at<2>(ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_tuple()
+ );
+
+ check(
+ vd::split_at<2>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_tuple(ct_eq<3>{})
+ );
+
+ check(
+ vd::split_at<2>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_tuple(ct_eq<3>{}, ct_eq<4>{})
+ );
+
+ check(
+ vd::split_at<2>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_tuple(ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})
+ );
+ }
+ {
+ check(
+ vd::split_at<7>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}),
+ hana::make_tuple()
+ );
+
+ check(
+ vd::split_at<7>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}),
+ hana::make_tuple(ct_eq<8>{})
+ );
+
+ check(
+ vd::split_at<7>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}),
+ hana::make_tuple(ct_eq<8>{}, ct_eq<9>{})
+ );
+
+ check(
+ vd::split_at<7>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}, ct_eq<10>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}),
+ hana::make_tuple(ct_eq<8>{}, ct_eq<9>{}, ct_eq<10>{})
+ );
+ }
+ {
+ check(
+ vd::split_at<8>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}),
+ hana::make_tuple()
+ );
+
+ check(
+ vd::split_at<8>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}),
+ hana::make_tuple(ct_eq<9>{})
+ );
+
+ check(
+ vd::split_at<8>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}, ct_eq<10>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}),
+ hana::make_tuple(ct_eq<9>{}, ct_eq<10>{})
+ );
+ }
+ {
+ check(
+ vd::split_at<9>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}),
+ hana::make_tuple()
+ );
+
+ check(
+ vd::split_at<9>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}, ct_eq<10>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}),
+ hana::make_tuple(ct_eq<10>{})
+ );
+
+ check(
+ vd::split_at<9>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}, ct_eq<10>{}, ct_eq<11>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}),
+ hana::make_tuple(ct_eq<10>{}, ct_eq<11>{})
+ );
+ }
+}
diff --git a/src/boost/libs/hana/test/detail/variadic/take.cpp b/src/boost/libs/hana/test/detail/variadic/take.cpp
new file mode 100644
index 00000000..031c6bae
--- /dev/null
+++ b/src/boost/libs/hana/test/detail/variadic/take.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/detail/variadic/take.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+namespace vd = hana::detail::variadic;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::take<0>()(f),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::take<0>(ct_eq<1>{})(f),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::take<0>(ct_eq<1>{}, ct_eq<2>{})(f),
+ f()
+ ));
+ }
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::take<1>(ct_eq<1>{})(f),
+ f(ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::take<1>(ct_eq<1>{}, ct_eq<2>{})(f),
+ f(ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::take<1>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})(f),
+ f(ct_eq<1>{})
+ ));
+ }
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::take<8>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{})(f),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ vd::take<8>(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{})(f),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{})
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/euclidean_ring.cpp b/src/boost/libs/hana/test/euclidean_ring.cpp
new file mode 100644
index 00000000..2653fe7e
--- /dev/null
+++ b/src/boost/libs/hana/test/euclidean_ring.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/div.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/euclidean_ring.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::TestEuclideanRing<int>{hana::make_tuple(0,1,2,3,4,5)};
+ hana::test::TestEuclideanRing<long>{hana::make_tuple(0l,1l,2l,3l,4l,5l)};
+
+ // div
+ {
+ static_assert(hana::div(6, 4) == 6 / 4, "");
+ static_assert(hana::div(7, -3) == 7 / -3, "");
+ }
+
+ // mod
+ {
+ static_assert(hana::mod(6, 4) == 6 % 4, "");
+ static_assert(hana::mod(7, -3) == 7 % -3, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/printable/map.cpp b/src/boost/libs/hana/test/experimental/printable/map.cpp
new file mode 100644
index 00000000..ad9bb575
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/printable/map.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/assert.hpp>
+#include <boost/hana/experimental/printable.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+
+#include <sstream>
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_map()
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "{}");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_map(hana::make_pair(hana::int_c<1>, 'x'))
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "{1 => x}");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_map(hana::make_pair(hana::int_c<1>, 'x'),
+ hana::make_pair(hana::int_c<2>, 'y'))
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "{1 => x, 2 => y}");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_map(hana::make_pair(hana::int_c<1>, 'x'),
+ hana::make_pair(hana::int_c<2>, 'y'),
+ hana::make_pair(hana::int_c<3>, 'z'))
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "{1 => x, 2 => y, 3 => z}");
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/printable/metafunction.cpp b/src/boost/libs/hana/test/experimental/printable/metafunction.cpp
new file mode 100644
index 00000000..5cfdb6a6
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/printable/metafunction.cpp
@@ -0,0 +1,45 @@
+// Copyright Jason Rice 2016
+// Distributed under the 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/experimental/printable.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/type.hpp>
+
+#include <regex>
+#include <sstream>
+namespace hana = boost::hana;
+
+namespace foo {
+ template <typename T> struct my_template { };
+ template <typename ...> struct my_mf { struct type; };
+ struct my_mf_class { template <typename ...> struct apply { struct type; }; };
+}
+
+int main() {
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::template_<foo::my_template>
+ );
+ BOOST_HANA_RUNTIME_CHECK(std::regex_match(ss.str(),
+ std::regex("template<(?:struct )?foo::my_template>")));
+ }
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::metafunction<foo::my_mf>
+ );
+ BOOST_HANA_RUNTIME_CHECK(std::regex_match(ss.str(),
+ std::regex("metafunction<(?:struct )?foo::my_mf>")));
+ }
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::metafunction_class<foo::my_mf_class>
+ );
+ BOOST_HANA_RUNTIME_CHECK(std::regex_match(ss.str(),
+ std::regex("metafunction_class<(?:struct )?foo::my_mf_class>")));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/printable/optional.cpp b/src/boost/libs/hana/test/experimental/printable/optional.cpp
new file mode 100644
index 00000000..c963204c
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/printable/optional.cpp
@@ -0,0 +1,29 @@
+// Copyright Jason Rice 2015
+// Distributed under the 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/experimental/printable.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <sstream>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::just(hana::int_c<5>)
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "just(5)");
+ }
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::nothing
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "nothing");
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/printable/pair.cpp b/src/boost/libs/hana/test/experimental/printable/pair.cpp
new file mode 100644
index 00000000..4d592fb3
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/printable/pair.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/experimental/printable.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/pair.hpp>
+
+#include <sstream>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_pair(1, hana::int_c<1>)
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "(1, 1)");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_pair(1, hana::int_c<2>)
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "(1, 2)");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_pair('x', hana::int_c<2>)
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "(x, 2)");
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/printable/set.cpp b/src/boost/libs/hana/test/experimental/printable/set.cpp
new file mode 100644
index 00000000..7a939944
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/printable/set.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 <boost/hana/experimental/printable.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/string.hpp>
+
+#include <sstream>
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_set()
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "{}");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_set(hana::int_c<1>)
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "{1}");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_set(hana::int_c<1>, BOOST_HANA_STRING("3456"))
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "{1, \"3456\"}");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ hana::make_set(hana::char_c<'x'>, BOOST_HANA_STRING("3456"))
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "{x, \"3456\"}");
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/printable/string.cpp b/src/boost/libs/hana/test/experimental/printable/string.cpp
new file mode 100644
index 00000000..419e06ad
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/printable/string.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/experimental/printable.hpp>
+#include <boost/hana/string.hpp>
+
+#include <sstream>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ BOOST_HANA_STRING("")
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "\"\"");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ BOOST_HANA_STRING("x")
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "\"x\"");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ BOOST_HANA_STRING("xy")
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "\"xy\"");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(
+ BOOST_HANA_STRING("xyz")
+ );
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "\"xyz\"");
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/printable/tuple.cpp b/src/boost/libs/hana/test/experimental/printable/tuple.cpp
new file mode 100644
index 00000000..db53626b
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/printable/tuple.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/assert.hpp>
+#include <boost/hana/experimental/printable.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <sstream>
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(hana::make_tuple());
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "()");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(hana::make_tuple(1));
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "(1)");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(hana::make_tuple(1, 2));
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "(1, 2)");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(hana::make_tuple(1, '2', "3456"));
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "(1, 2, 3456)");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(hana::make_tuple(1, '2', hana::make_tuple()));
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "(1, 2, ())");
+ }
+
+ {
+ std::ostringstream ss;
+ ss << hana::experimental::print(hana::make_tuple(1, '2', hana::make_tuple(3.3, '4')));
+ BOOST_HANA_RUNTIME_CHECK(ss.str() == "(1, 2, (3.3, 4))");
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/printable/type.cpp b/src/boost/libs/hana/test/experimental/printable/type.cpp
new file mode 100644
index 00000000..718cdc0c
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/printable/type.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/experimental/printable.hpp>
+#include <boost/hana/type.hpp>
+
+#include <iostream>
+namespace hana = boost::hana;
+
+
+template <typename ...T>
+struct Template { };
+
+int main() {
+ // Since demangling may not always be available, and since that's not
+ // our job to test this (but Boost.Core's job), we don't test the
+ // actual demangling of types. We merely print a type to make sure
+ // things don't blow up stupidly, but we can't really test more than
+ // that.
+
+ std::cout << hana::experimental::print(hana::type_c<void>) << std::endl;
+
+ std::cout << hana::experimental::print(hana::type_c<int>) << std::endl;
+
+ std::cout << hana::experimental::print(hana::type_c<int const>) << std::endl;
+
+ std::cout << hana::experimental::print(hana::type_c<int&>) << std::endl;
+
+ std::cout << hana::experimental::print(hana::type_c<int const&>) << std::endl;
+
+ std::cout << hana::experimental::print(hana::type_c<int(&)[]>) << std::endl;
+
+ std::cout << hana::experimental::print(hana::type_c<Template<void, char const*>>) << std::endl;
+}
diff --git a/src/boost/libs/hana/test/experimental/type_name.cpp b/src/boost/libs/hana/test/experimental/type_name.cpp
new file mode 100644
index 00000000..6144dc71
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/type_name.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/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/experimental/type_name.hpp>
+#include <boost/hana/string.hpp>
+
+#include <cstdlib>
+#include <iostream>
+#include <regex>
+#include <string>
+namespace hana = boost::hana;
+
+
+template <typename ...T>
+struct Template { };
+
+template <typename T>
+void check_matches(std::string const& re) {
+ std::string name = hana::to<char const*>(hana::experimental::type_name<T>());
+ std::regex regex{re};
+ if (!std::regex_match(name, regex)) {
+ std::cerr << "type name '" << name << "' does not match regex '" << re << "'" << std::endl;
+ std::abort();
+ }
+}
+
+int main() {
+ // Make sure this can be obtained at compile-time
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::experimental::type_name<void>(),
+ BOOST_HANA_STRING("void")
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::experimental::type_name<int>(),
+ BOOST_HANA_STRING("int")
+ ));
+
+ // Make sure we get something reasonable
+ check_matches<int const>("int const|const int");
+ check_matches<int&>(R"(int\s*&)");
+ check_matches<int const&>(R"(const\s+int\s*&|int\s+const\s*&)");
+ check_matches<int(&)[]>(R"(int\s*\(\s*&\s*\)\s*\[\s*\])");
+ check_matches<int(&)[10]>(R"(int\s*\(\s*&\s*\)\s*\[\s*10\s*\])");
+ check_matches<Template<void, char const*>>(R"(Template<\s*void\s*,\s*(char const|const char)\s*\*\s*>)");
+ check_matches<void(*)(int)>(R"(void\s*\(\s*\*\s*\)\s*\(\s*int\s*\))");
+}
diff --git a/src/boost/libs/hana/test/experimental/types/at.cpp b/src/boost/libs/hana/test/experimental/types/at.cpp
new file mode 100644
index 00000000..f5fe8f66
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/types/at.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)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/experimental/types.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct x;
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<0>(hana::experimental::types<x<0>>{}),
+ hana::type_c<x<0>>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<0>(hana::experimental::types<x<0>, x<1>>{}),
+ hana::type_c<x<0>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<1>(hana::experimental::types<x<0>, x<1>>{}),
+ hana::type_c<x<1>>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<0>(hana::experimental::types<x<0>, x<1>, x<2>>{}),
+ hana::type_c<x<0>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<1>(hana::experimental::types<x<0>, x<1>, x<2>>{}),
+ hana::type_c<x<1>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<2>(hana::experimental::types<x<0>, x<1>, x<2>>{}),
+ hana::type_c<x<2>>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<0>(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}),
+ hana::type_c<x<0>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<1>(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}),
+ hana::type_c<x<1>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<2>(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}),
+ hana::type_c<x<2>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<3>(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}),
+ hana::type_c<x<3>>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<0>(hana::experimental::types<x<0>, x<1>, x<2>, x<3>, x<4>>{}),
+ hana::type_c<x<0>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<1>(hana::experimental::types<x<0>, x<1>, x<2>, x<3>, x<4>>{}),
+ hana::type_c<x<1>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<2>(hana::experimental::types<x<0>, x<1>, x<2>, x<3>, x<4>>{}),
+ hana::type_c<x<2>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<3>(hana::experimental::types<x<0>, x<1>, x<2>, x<3>, x<4>>{}),
+ hana::type_c<x<3>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<4>(hana::experimental::types<x<0>, x<1>, x<2>, x<3>, x<4>>{}),
+ hana::type_c<x<4>>
+ ));
+}
diff --git a/src/boost/libs/hana/test/experimental/types/contains.cpp b/src/boost/libs/hana/test/experimental/types/contains.cpp
new file mode 100644
index 00000000..d9d5197d
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/types/contains.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/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/experimental/types.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct x;
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::experimental::types<>{},
+ undefined{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>>{},
+ hana::type_c<x<0>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::experimental::types<x<0>>{},
+ hana::type_c<x<999>>
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>, x<1>>{},
+ hana::type_c<x<0>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>, x<1>>{},
+ hana::type_c<x<1>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::experimental::types<x<0>, x<1>>{},
+ hana::type_c<x<999>>
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>, x<1>, x<2>>{},
+ hana::type_c<x<0>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>, x<1>, x<2>>{},
+ hana::type_c<x<1>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>, x<1>, x<2>>{},
+ hana::type_c<x<2>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::experimental::types<x<0>, x<1>, x<2>>{},
+ hana::type_c<x<999>>
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{},
+ hana::type_c<x<0>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{},
+ hana::type_c<x<1>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{},
+ hana::type_c<x<2>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{},
+ hana::type_c<x<3>>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{},
+ hana::type_c<x<999>>
+ )));
+}
diff --git a/src/boost/libs/hana/test/experimental/types/drop_front.cpp b/src/boost/libs/hana/test/experimental/types/drop_front.cpp
new file mode 100644
index 00000000..3277af40
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/types/drop_front.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/assert.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/experimental/types.hpp>
+#include <boost/hana/integral_constant.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct x;
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<>{}, hana::size_c<0>),
+ hana::experimental::types<>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<>{}, hana::size_c<1>),
+ hana::experimental::types<>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>>{}, hana::size_c<0>),
+ hana::experimental::types<x<0>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>>{}, hana::size_c<1>),
+ hana::experimental::types<>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>>{}, hana::size_c<2>),
+ hana::experimental::types<>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>>{}, hana::size_c<0>),
+ hana::experimental::types<x<0>, x<1>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>>{}, hana::size_c<1>),
+ hana::experimental::types<x<1>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>>{}, hana::size_c<2>),
+ hana::experimental::types<>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>>{}, hana::size_c<3>),
+ hana::experimental::types<>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>>{}, hana::size_c<0>),
+ hana::experimental::types<x<0>, x<1>, x<2>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>>{}, hana::size_c<1>),
+ hana::experimental::types<x<1>, x<2>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>>{}, hana::size_c<2>),
+ hana::experimental::types<x<2>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>>{}, hana::size_c<3>),
+ hana::experimental::types<>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>>{}, hana::size_c<4>),
+ hana::experimental::types<>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, hana::size_c<0>),
+ hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, hana::size_c<1>),
+ hana::experimental::types<x<1>, x<2>, x<3>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, hana::size_c<2>),
+ hana::experimental::types<x<2>, x<3>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, hana::size_c<3>),
+ hana::experimental::types<x<3>>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, hana::size_c<4>),
+ hana::experimental::types<>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, hana::size_c<5>),
+ hana::experimental::types<>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/experimental/types/equal.cpp b/src/boost/libs/hana/test/experimental/types/equal.cpp
new file mode 100644
index 00000000..a44b2dbf
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/types/equal.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)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/experimental/types.hpp>
+#include <boost/hana/not.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct x;
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::experimental::types<>{},
+ hana::experimental::types<>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::experimental::types<x<0>>{},
+ hana::experimental::types<x<0>>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::experimental::types<x<0>, x<1>, x<2>>{},
+ hana::experimental::types<x<0>, x<1>, x<2>>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::experimental::types<>{},
+ hana::experimental::types<x<0>>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::experimental::types<x<0>>{},
+ hana::experimental::types<>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::experimental::types<x<0>>{},
+ hana::experimental::types<x<1>>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::experimental::types<x<0>, x<1>, x<2>>{},
+ hana::experimental::types<x<0>, x<1>, x<3>>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::experimental::types<x<0>, x<1>, x<2>>{},
+ hana::experimental::types<x<0>, x<1>>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::experimental::types<x<0>, x<1>, x<2>>{},
+ hana::experimental::types<x<0>, x<9>, x<2>>{}
+ )));
+}
diff --git a/src/boost/libs/hana/test/experimental/types/is_empty.cpp b/src/boost/libs/hana/test/experimental/types/is_empty.cpp
new file mode 100644
index 00000000..f90c0154
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/types/is_empty.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/experimental/types.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct x;
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(
+ hana::experimental::types<>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ hana::experimental::types<x<0>>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ hana::experimental::types<x<0>, x<1>>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ hana::experimental::types<x<0>, x<1>, x<2>>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}
+ )));
+}
diff --git a/src/boost/libs/hana/test/experimental/types/transform.cpp b/src/boost/libs/hana/test/experimental/types/transform.cpp
new file mode 100644
index 00000000..0ed1b07c
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/types/transform.cpp
@@ -0,0 +1,74 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/types.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct mf { struct type; };
+
+template <int> struct x;
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::experimental::types<>{}, undefined{}),
+ hana::experimental::types<>{}
+ ));
+
+ // with a Metafunction
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::experimental::types<x<0>>{}, hana::metafunction<mf>),
+ hana::experimental::types<mf<x<0>>::type>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::experimental::types<x<0>, x<1>>{}, hana::metafunction<mf>),
+ hana::experimental::types<mf<x<0>>::type, mf<x<1>>::type>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::experimental::types<x<0>, x<1>, x<2>>{}, hana::metafunction<mf>),
+ hana::experimental::types<mf<x<0>>::type, mf<x<1>>::type, mf<x<2>>::type>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, hana::metafunction<mf>),
+ hana::experimental::types<mf<x<0>>::type, mf<x<1>>::type, mf<x<2>>::type, mf<x<3>>::type>{}
+ ));
+ }
+
+ // with a non-Metafunction
+ {
+ auto f = [](auto t) {
+ return hana::metafunction<mf>(t);
+ };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::experimental::types<x<0>>{}, f),
+ hana::experimental::types<mf<x<0>>::type>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::experimental::types<x<0>, x<1>>{}, f),
+ hana::experimental::types<mf<x<0>>::type, mf<x<1>>::type>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::experimental::types<x<0>, x<1>, x<2>>{}, f),
+ hana::experimental::types<mf<x<0>>::type, mf<x<1>>::type, mf<x<2>>::type>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, f),
+ hana::experimental::types<mf<x<0>>::type, mf<x<1>>::type, mf<x<2>>::type, mf<x<3>>::type>{}
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/types/unpack.cpp b/src/boost/libs/hana/test/experimental/types/unpack.cpp
new file mode 100644
index 00000000..96116b40
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/types/unpack.cpp
@@ -0,0 +1,83 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/types.hpp>
+#include <boost/hana/type.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct mf { struct type; };
+
+template <int> struct x;
+
+int main() {
+ // with a Metafunction
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<>{}, hana::metafunction<mf>),
+ hana::type_c<mf<>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<x<0>>{}, hana::metafunction<mf>),
+ hana::type_c<mf<x<0>>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<x<0>, x<1>>{}, hana::metafunction<mf>),
+ hana::type_c<mf<x<0>, x<1>>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<x<0>, x<1>, x<2>>{}, hana::metafunction<mf>),
+ hana::type_c<mf<x<0>, x<1>, x<2>>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, hana::metafunction<mf>),
+ hana::type_c<mf<x<0>, x<1>, x<2>, x<3>>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<x<0>, x<1>, x<2>, x<3>, x<4>>{}, hana::metafunction<mf>),
+ hana::type_c<mf<x<0>, x<1>, x<2>, x<3>, x<4>>::type>
+ ));
+ }
+
+ // with a non-Metafunction
+ {
+ auto f = hana::test::_injection<0>{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<>{}, f),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<x<0>>{}, f),
+ f(hana::type_c<x<0>>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<x<0>, x<1>>{}, f),
+ f(hana::type_c<x<0>>, hana::type_c<x<1>>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<x<0>, x<1>, x<2>>{}, f),
+ f(hana::type_c<x<0>>, hana::type_c<x<1>>, hana::type_c<x<2>>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::experimental::types<x<0>, x<1>, x<2>, x<3>>{}, f),
+ f(hana::type_c<x<0>>, hana::type_c<x<1>>, hana::type_c<x<2>>, hana::type_c<x<3>>)
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/empty/is_empty.cpp b/src/boost/libs/hana/test/experimental/view/empty/is_empty.cpp
new file mode 100644
index 00000000..c3efb7e2
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/empty/is_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/experimental/view.hpp>
+#include <boost/hana/is_empty.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ auto empty = hana::experimental::empty_view();
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(empty));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/empty/length.cpp b/src/boost/libs/hana/test/experimental/view/empty/length.cpp
new file mode 100644
index 00000000..3325ec9c
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/empty/length.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/experimental/view.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ auto empty = hana::experimental::empty_view();
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(empty),
+ hana::size_c<0>
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/empty/unpack.cpp b/src/boost/libs/hana/test/experimental/view/empty/unpack.cpp
new file mode 100644
index 00000000..6942e35a
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/empty/unpack.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/experimental/view.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto f = hana::test::_injection<0>{};
+
+ {
+ auto empty = hana::experimental::empty_view();
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(empty, f),
+ f()
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/joined/at.cpp b/src/boost/libs/hana/test/experimental/view/joined/at.cpp
new file mode 100644
index 00000000..ec4e0017
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/joined/at.cpp
@@ -0,0 +1,97 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/view.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto container = ::seq;
+
+ {
+ auto storage1 = container(ct_eq<0>{});
+ auto storage2 = container();
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ }{
+ auto storage1 = container();
+ auto storage2 = container(ct_eq<0>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ }
+
+ {
+ auto storage1 = container(ct_eq<0>{}, ct_eq<1>{});
+ auto storage2 = container();
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<1>),
+ ct_eq<1>{}
+ ));
+ }{
+ auto storage1 = container(ct_eq<0>{});
+ auto storage2 = container(ct_eq<1>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<1>),
+ ct_eq<1>{}
+ ));
+ }{
+ auto storage1 = container();
+ auto storage2 = container(ct_eq<0>{}, ct_eq<1>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<1>),
+ ct_eq<1>{}
+ ));
+ }
+
+ {
+ auto storage1 = container(ct_eq<0>{}, ct_eq<1>{});
+ auto storage2 = container(ct_eq<2>{}, ct_eq<3>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<1>),
+ ct_eq<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<2>),
+ ct_eq<2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(joined, hana::size_c<3>),
+ ct_eq<3>{}
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/joined/is_empty.cpp b/src/boost/libs/hana/test/experimental/view/joined/is_empty.cpp
new file mode 100644
index 00000000..b8a5e0ae
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/joined/is_empty.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/experimental/view.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct undefined { };
+
+int main() {
+ auto container = ::seq;
+
+ {
+ auto storage1 = container();
+ auto storage2 = container();
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(joined));
+ }
+ {
+ auto storage1 = container(undefined<0>{});
+ auto storage2 = container();
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(joined)));
+ }
+ {
+ auto storage1 = container(undefined<0>{});
+ auto storage2 = container(undefined<1>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(joined)));
+ }
+ {
+ auto storage1 = container();
+ auto storage2 = container(undefined<0>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(joined)));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/joined/length.cpp b/src/boost/libs/hana/test/experimental/view/joined/length.cpp
new file mode 100644
index 00000000..457d5f62
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/joined/length.cpp
@@ -0,0 +1,89 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/view.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct undefined { };
+
+int main() {
+ auto container = ::seq;
+
+ {
+ auto storage1 = container();
+ auto storage2 = container();
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(joined),
+ hana::size_c<0>
+ ));
+ }
+
+ {
+ auto storage1 = container(undefined<0>{});
+ auto storage2 = container();
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(joined),
+ hana::size_c<1>
+ ));
+ }
+
+ {
+ auto storage1 = container();
+ auto storage2 = container(undefined<0>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(joined),
+ hana::size_c<1>
+ ));
+ }
+
+ {
+ auto storage1 = container(undefined<0>{});
+ auto storage2 = container(undefined<1>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(joined),
+ hana::size_c<2>
+ ));
+ }
+
+ {
+ auto storage1 = container(undefined<0>{});
+ auto storage2 = container(undefined<1>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(joined),
+ hana::size_c<2>
+ ));
+ }
+
+ {
+ auto storage1 = container(undefined<0>{}, undefined<1>{});
+ auto storage2 = container(undefined<2>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(joined),
+ hana::size_c<3>
+ ));
+ }
+
+ {
+ auto storage1 = container(undefined<0>{}, undefined<1>{}, undefined<2>{});
+ auto storage2 = container(undefined<3>{}, undefined<4>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(joined),
+ hana::size_c<5>
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/joined/unpack.cpp b/src/boost/libs/hana/test/experimental/view/joined/unpack.cpp
new file mode 100644
index 00000000..cf0896d8
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/joined/unpack.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/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/experimental/view.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto container = ::seq;
+ auto f = hana::test::_injection<0>{};
+
+ {
+ auto storage1 = container();
+ auto storage2 = container();
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(joined, f),
+ f()
+ ));
+ }
+
+ {
+ auto storage1 = container(ct_eq<0>{});
+ auto storage2 = container();
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(joined, f),
+ f(ct_eq<0>{})
+ ));
+ }{
+ auto storage1 = container();
+ auto storage2 = container(ct_eq<0>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(joined, f),
+ f(ct_eq<0>{})
+ ));
+ }{
+ auto storage1 = container(ct_eq<0>{});
+ auto storage2 = container(ct_eq<1>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(joined, f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ }
+
+ {
+ auto storage1 = container(ct_eq<0>{}, ct_eq<1>{});
+ auto storage2 = container();
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(joined, f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ }{
+ auto storage1 = container();
+ auto storage2 = container(ct_eq<0>{}, ct_eq<1>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(joined, f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ }{
+ auto storage1 = container(ct_eq<0>{}, ct_eq<1>{});
+ auto storage2 = container(ct_eq<2>{}, ct_eq<3>{});
+ auto joined = hana::experimental::joined(storage1, storage2);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(joined, f),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/single/at.cpp b/src/boost/libs/hana/test/experimental/view/single/at.cpp
new file mode 100644
index 00000000..20d1490b
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/single/at.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/at.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/experimental/view.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ {
+ auto single = hana::experimental::single_view(ct_eq<0>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(single, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/single/is_empty.cpp b/src/boost/libs/hana/test/experimental/view/single/is_empty.cpp
new file mode 100644
index 00000000..4422b3e4
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/single/is_empty.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/experimental/view.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct undefined { };
+
+int main() {
+ {
+ auto single = hana::experimental::single_view(undefined<0>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(single)));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/single/length.cpp b/src/boost/libs/hana/test/experimental/view/single/length.cpp
new file mode 100644
index 00000000..8153f819
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/single/length.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/experimental/view.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct undefined { };
+
+int main() {
+ {
+ auto single = hana::experimental::single_view(undefined<0>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(single),
+ hana::size_c<1>
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/single/unpack.cpp b/src/boost/libs/hana/test/experimental/view/single/unpack.cpp
new file mode 100644
index 00000000..ca239841
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/single/unpack.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/experimental/view.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto f = hana::test::_injection<0>{};
+
+ {
+ auto single = hana::experimental::single_view(ct_eq<0>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(single, f),
+ f(ct_eq<0>{})
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/sliced/at.cpp b/src/boost/libs/hana/test/experimental/view/sliced/at.cpp
new file mode 100644
index 00000000..c8d201a5
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/sliced/at.cpp
@@ -0,0 +1,91 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/view.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto container = ::seq;
+
+ {
+ auto storage = container(ct_eq<0>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 1>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<0>),
+ ct_eq<1>{}
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0, 1>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<1>),
+ ct_eq<1>{}
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 1, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<0>),
+ ct_eq<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<1>),
+ ct_eq<0>{}
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<0>),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<1>),
+ ct_eq<0>{}
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 1, 3>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<0>),
+ ct_eq<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(sliced, hana::size_c<1>),
+ ct_eq<3>{}
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/sliced/is_empty.cpp b/src/boost/libs/hana/test/experimental/view/sliced/is_empty.cpp
new file mode 100644
index 00000000..d6f0d267
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/sliced/is_empty.cpp
@@ -0,0 +1,49 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/view.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct undefined { };
+
+int main() {
+ auto container = ::seq;
+
+ {
+ auto storage = container();
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(sliced));
+ }{
+ auto storage = container(undefined<0>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(sliced));
+ }{
+ auto storage = container(undefined<0>{}, undefined<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(sliced));
+ }
+
+ {
+ auto storage = container(undefined<0>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(sliced)));
+ }{
+ auto storage = container(undefined<0>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(sliced)));
+ }
+
+ {
+ auto storage = container(undefined<0>{}, undefined<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0, 1>);
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(sliced)));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/sliced/length.cpp b/src/boost/libs/hana/test/experimental/view/sliced/length.cpp
new file mode 100644
index 00000000..c975960a
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/sliced/length.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/equal.hpp>
+#include <boost/hana/experimental/view.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct undefined { };
+
+int main() {
+ auto container = ::seq;
+
+ {
+ auto storage = container();
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(sliced),
+ hana::size_c<0>
+ ));
+ }
+
+ {
+ auto storage = container(undefined<0>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(sliced),
+ hana::size_c<1>
+ ));
+ }{
+ auto storage = container(undefined<0>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(sliced),
+ hana::size_c<0>
+ ));
+ }
+
+ {
+ auto storage = container(undefined<0>{}, undefined<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(sliced),
+ hana::size_c<1>
+ ));
+ }{
+ auto storage = container(undefined<0>{}, undefined<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0, 1>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(sliced),
+ hana::size_c<2>
+ ));
+ }{
+ auto storage = container(undefined<0>{}, undefined<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(sliced),
+ hana::size_c<2>
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/sliced/unpack.cpp b/src/boost/libs/hana/test/experimental/view/sliced/unpack.cpp
new file mode 100644
index 00000000..710e8246
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/sliced/unpack.cpp
@@ -0,0 +1,135 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/view.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto container = ::seq;
+ auto f = hana::test::_injection<0>{};
+
+ {
+ auto storage = container();
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f()
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f()
+ ));
+ }{
+ auto storage = container(ct_eq<0>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<0>{})
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f()
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<0>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0, 1>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 1>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<1>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 1, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<1>{}, ct_eq<0>{})
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f()
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<0>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 1>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<1>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 2>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<2>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 0, 2>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<0>{}, ct_eq<2>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 1, 1>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<1>{}, ct_eq<1>{})
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{});
+ auto sliced = hana::experimental::sliced(storage, hana::tuple_c<int, 3, 1, 0, 2, 2>);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(sliced, f),
+ f(ct_eq<3>{}, ct_eq<1>{}, ct_eq<0>{}, ct_eq<2>{}, ct_eq<2>{})
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/ap.cpp b/src/boost/libs/hana/test/experimental/view/transformed/ap.cpp
new file mode 100644
index 00000000..b04d54fe
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/ap.cpp
@@ -0,0 +1,122 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/view.hpp>
+#include <boost/hana/functional/id.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::_injection;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto container = ::seq;
+ auto f = hana::test::_injection<99>{};
+
+ {
+ auto storage = container();
+ auto functions = container();
+ auto transformed_storage = hana::experimental::transformed(storage, f);
+ auto transformed_functions = hana::experimental::transformed(functions, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(transformed_functions, transformed_storage),
+ container()
+ ));
+ }{
+ auto storage = container(ct_eq<0>{});
+ auto functions = container();
+ auto transformed_storage = hana::experimental::transformed(storage, f);
+ auto transformed_functions = hana::experimental::transformed(functions, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(transformed_functions, transformed_storage),
+ container()
+ ));
+ }{
+ auto storage = container();
+ auto functions = container(ct_eq<0>{});
+ auto transformed_storage = hana::experimental::transformed(storage, f);
+ auto transformed_functions = hana::experimental::transformed(functions, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(transformed_functions, transformed_storage),
+ container()
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{});
+ auto functions = container(_injection<0>{});
+ auto transformed_storage = hana::experimental::transformed(storage, f);
+ auto transformed_functions = hana::experimental::transformed(functions, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(transformed_functions, transformed_storage),
+ container(_injection<0>{}(f(ct_eq<0>{})))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{});
+ auto functions = container(_injection<0>{}, _injection<1>{});
+ auto transformed_storage = hana::experimental::transformed(storage, f);
+ auto transformed_functions = hana::experimental::transformed(functions, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(transformed_functions, transformed_storage),
+ container(_injection<0>{}(f(ct_eq<0>{})),
+ _injection<1>{}(f(ct_eq<0>{})))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{});
+ auto functions = container(_injection<0>{}, _injection<1>{}, _injection<2>{});
+ auto transformed_storage = hana::experimental::transformed(storage, f);
+ auto transformed_functions = hana::experimental::transformed(functions, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(transformed_functions, transformed_storage),
+ container(_injection<0>{}(f(ct_eq<0>{})),
+ _injection<1>{}(f(ct_eq<0>{})),
+ _injection<2>{}(f(ct_eq<0>{})))
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto functions = container(_injection<0>{});
+ auto transformed_storage = hana::experimental::transformed(storage, f);
+ auto transformed_functions = hana::experimental::transformed(functions, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(transformed_functions, transformed_storage),
+ container(_injection<0>{}(f(ct_eq<0>{})),
+ _injection<0>{}(f(ct_eq<1>{})))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto functions = container(_injection<0>{});
+ auto transformed_storage = hana::experimental::transformed(storage, f);
+ auto transformed_functions = hana::experimental::transformed(functions, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(transformed_functions, transformed_storage),
+ container(_injection<0>{}(f(ct_eq<0>{})),
+ _injection<0>{}(f(ct_eq<1>{})),
+ _injection<0>{}(f(ct_eq<2>{})))
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto functions = container(_injection<0>{}, _injection<1>{});
+ auto transformed_storage = hana::experimental::transformed(storage, f);
+ auto transformed_functions = hana::experimental::transformed(functions, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(transformed_functions, transformed_storage),
+ container(_injection<0>{}(f(ct_eq<0>{})),
+ _injection<0>{}(f(ct_eq<1>{})),
+ _injection<0>{}(f(ct_eq<2>{})),
+
+ _injection<1>{}(f(ct_eq<0>{})),
+ _injection<1>{}(f(ct_eq<1>{})),
+ _injection<1>{}(f(ct_eq<2>{})))
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/at.cpp b/src/boost/libs/hana/test/experimental/view/transformed/at.cpp
new file mode 100644
index 00000000..2379f287
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/at.cpp
@@ -0,0 +1,73 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/view.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto container = ::seq;
+ auto f = hana::test::_injection<0>{};
+
+ {
+ auto storage = container(ct_eq<0>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<0>(transformed),
+ f(ct_eq<0>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<0>(transformed),
+ f(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<1>(transformed),
+ f(ct_eq<1>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<0>(transformed),
+ f(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<1>(transformed),
+ f(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<2>(transformed),
+ f(ct_eq<2>{})
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<0>(transformed),
+ f(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<1>(transformed),
+ f(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<2>(transformed),
+ f(ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_c<3>(transformed),
+ f(ct_eq<3>{})
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/drop_front.cpp b/src/boost/libs/hana/test/experimental/view/transformed/drop_front.cpp
new file mode 100644
index 00000000..0db64fd4
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/drop_front.cpp
@@ -0,0 +1,98 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/view.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto container = ::seq;
+ auto f = hana::test::_injection<0>{};
+
+ {
+ auto storage = container();
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<0>),
+ container()
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<0>),
+ container(f(ct_eq<0>{}))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<1>),
+ container()
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<0>),
+ container(f(ct_eq<0>{}), f(ct_eq<1>{}))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<1>),
+ container(f(ct_eq<1>{}))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<2>),
+ container()
+ ));
+ }
+
+ {
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<0>),
+ container(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<1>),
+ container(f(ct_eq<1>{}), f(ct_eq<2>{}))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<2>),
+ container(f(ct_eq<2>{}))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(transformed, hana::size_c<3>),
+ container()
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/equal.cpp b/src/boost/libs/hana/test/experimental/view/transformed/equal.cpp
new file mode 100644
index 00000000..f7723c0c
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/equal.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/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/experimental/view.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/not.hpp>
+
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto container = ::seq;
+
+ auto xs = container(0, '1', 2.2);
+ auto tr = hana::experimental::transformed(xs, hana::id);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ tr,
+ container()
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ tr,
+ container(0)
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ tr,
+ container(0, '1')
+ )));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ tr,
+ container(0, '1', 2.2)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ tr,
+ container(0, '1', 2.2, 345)
+ )));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::not_(hana::equal(
+ tr,
+ container('0', '1', '2')
+ )));
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/is_empty.cpp b/src/boost/libs/hana/test/experimental/view/transformed/is_empty.cpp
new file mode 100644
index 00000000..aafec8ab
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/is_empty.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/experimental/view.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+struct undefined { };
+
+int main() {
+ auto container = ::seq;
+
+ {
+ auto xs = container();
+ auto tr = hana::experimental::transformed(xs, undefined{});
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(tr));
+ }
+
+ {
+ auto xs = container(undefined{});
+ auto tr = hana::experimental::transformed(xs, undefined{});
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(tr)));
+ }
+
+ {
+ auto xs = container(undefined{}, undefined{});
+ auto tr = hana::experimental::transformed(xs, undefined{});
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(tr)));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/laziness.cpp b/src/boost/libs/hana/test/experimental/view/transformed/laziness.cpp
new file mode 100644
index 00000000..c1c9fc4c
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/laziness.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/experimental/view.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct undefined { };
+
+int main() {
+ // Make sure we do not evaluate the function unless required
+ auto storage = ::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto transformed = hana::experimental::transformed(storage, undefined{});
+ (void)transformed;
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/length.cpp b/src/boost/libs/hana/test/experimental/view/transformed/length.cpp
new file mode 100644
index 00000000..516df7da
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/length.cpp
@@ -0,0 +1,49 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/experimental/view.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+template <int> struct undefined { };
+
+int main() {
+ auto container = ::seq;
+
+ {
+ auto storage = container();
+ auto transformed = hana::experimental::transformed(storage, undefined<99>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(transformed),
+ hana::size_c<0>
+ ));
+ }{
+ auto storage = container(undefined<0>{});
+ auto transformed = hana::experimental::transformed(storage, undefined<99>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(transformed),
+ hana::size_c<1>
+ ));
+ }{
+ auto storage = container(undefined<0>{}, undefined<1>{});
+ auto transformed = hana::experimental::transformed(storage, undefined<99>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(transformed),
+ hana::size_c<2>
+ ));
+ }{
+ auto storage = container(undefined<0>{}, undefined<1>{}, undefined<2>{});
+ auto transformed = hana::experimental::transformed(storage, undefined<99>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(transformed),
+ hana::size_c<3>
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/less.cpp b/src/boost/libs/hana/test/experimental/view/transformed/less.cpp
new file mode 100644
index 00000000..562e0a46
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/less.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/experimental/view.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/not.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_ord;
+
+
+int main() {
+ auto container = ::seq;
+ auto f = hana::test::_injection<0>{};
+
+ {
+ auto storage = container();
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ transformed,
+ container()
+ )));
+ }{
+ auto storage = container(ct_ord<0>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ container(),
+ transformed
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ container(f(ct_ord<0>{})),
+ transformed
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ transformed,
+ container()
+ )));
+ }{
+ auto storage = container(ct_ord<0>{}, ct_ord<1>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ container(),
+ transformed
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ container(f(ct_ord<0>{})),
+ transformed
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ container(f(ct_ord<0>{}), f(ct_ord<0>{})),
+ transformed
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/transform.cpp b/src/boost/libs/hana/test/experimental/view/transformed/transform.cpp
new file mode 100644
index 00000000..6fbab678
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/transform.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/equal.hpp>
+#include <boost/hana/experimental/view.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto container = ::seq;
+ auto f = hana::test::_injection<0>{};
+ auto g = hana::test::_injection<1>{};
+
+ {
+ auto storage = container();
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(transformed, g),
+ container()
+ ));
+ }{
+ auto storage = container(ct_eq<0>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(transformed, g),
+ container(g(f(ct_eq<0>{})))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(transformed, g),
+ container(g(f(ct_eq<0>{})), g(f(ct_eq<1>{})))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(transformed, g),
+ container(g(f(ct_eq<0>{})), g(f(ct_eq<1>{})), g(f(ct_eq<2>{})))
+ ));
+ }{
+ auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{});
+ auto transformed = hana::experimental::transformed(storage, f);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(transformed, g),
+ container(g(f(ct_eq<0>{})), g(f(ct_eq<1>{})), g(f(ct_eq<2>{})), g(f(ct_eq<3>{})))
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/experimental/view/transformed/unpack.cpp b/src/boost/libs/hana/test/experimental/view/transformed/unpack.cpp
new file mode 100644
index 00000000..6ade5ed2
--- /dev/null
+++ b/src/boost/libs/hana/test/experimental/view/transformed/unpack.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/equal.hpp>
+#include <boost/hana/experimental/view.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto f = hana::test::_injection<0>{};
+ auto g = hana::test::_injection<1>{};
+ auto check = [=](auto ...x) {
+ auto storage = ::seq(x...);
+ auto transformed = hana::experimental::transformed(storage, f);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(transformed, g),
+ g(f(x)...)
+ ));
+ };
+
+ check();
+ check(ct_eq<0>{});
+ check(ct_eq<0>{}, ct_eq<1>{});
+ check(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ check(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{});
+}
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/_specs.hpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/_specs.hpp
new file mode 100644
index 00000000..6734967a
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/_specs.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_EXT_BOOST_FUSION_DEQUE_AUTO_SPECS_HPP
+#define BOOST_HANA_TEST_EXT_BOOST_FUSION_DEQUE_AUTO_SPECS_HPP
+
+#include <boost/hana/ext/boost/fusion/deque.hpp>
+
+#include <boost/fusion/container/deque.hpp>
+#include <boost/fusion/container/generation/make_deque.hpp>
+
+
+#define MAKE_TUPLE(...) ::boost::fusion::make_deque(__VA_ARGS__)
+#define TUPLE_TYPE(...) ::boost::fusion::deque<__VA_ARGS__>
+#define TUPLE_TAG ::boost::hana::ext::boost::fusion::deque_tag
+
+#endif // !BOOST_HANA_TEST_EXT_BOOST_FUSION_DEQUE_AUTO_SPECS_HPP
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/all_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/all_of.cpp
new file mode 100644
index 00000000..f3e974ff
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/all_of.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 "_specs.hpp"
+#include <auto/all_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/any_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/any_of.cpp
new file mode 100644
index 00000000..3065d017
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/any_of.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 "_specs.hpp"
+#include <auto/any_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/ap.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/ap.cpp
new file mode 100644
index 00000000..59c9cb75
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/ap.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 "_specs.hpp"
+#include <auto/ap.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/at.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/at.cpp
new file mode 100644
index 00000000..60526533
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/at.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 "_specs.hpp"
+#include <auto/at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/cartesian_product.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/cartesian_product.cpp
new file mode 100644
index 00000000..b0795e8d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/cartesian_product.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 "_specs.hpp"
+#include <auto/cartesian_product.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_back.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_back.cpp
new file mode 100644
index 00000000..b283844d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_back.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 "_specs.hpp"
+#include <auto/drop_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_front.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_front.cpp
new file mode 100644
index 00000000..a39d6f45
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_front.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 "_specs.hpp"
+#include <auto/drop_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_while.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_while.cpp
new file mode 100644
index 00000000..18907f03
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/drop_while.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 "_specs.hpp"
+#include <auto/drop_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/for_each.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/for_each.cpp
new file mode 100644
index 00000000..714fe03c
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/for_each.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 "_specs.hpp"
+#include <auto/for_each.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/group.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/group.cpp
new file mode 100644
index 00000000..0669b496
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/group.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 "_specs.hpp"
+#include <auto/group.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/index_if.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/index_if.cpp
new file mode 100644
index 00000000..ef37fe65
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/index_if.cpp
@@ -0,0 +1,9 @@
+// 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 "_specs.hpp"
+#include <auto/index_if.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/insert.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/insert.cpp
new file mode 100644
index 00000000..e8efc6dc
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/insert.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 "_specs.hpp"
+#include <auto/insert.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/insert_range.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/insert_range.cpp
new file mode 100644
index 00000000..05ac5774
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/insert_range.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 "_specs.hpp"
+#include <auto/insert_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/intersperse.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/intersperse.cpp
new file mode 100644
index 00000000..185c814a
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/intersperse.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 "_specs.hpp"
+#include <auto/intersperse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/is_empty.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/is_empty.cpp
new file mode 100644
index 00000000..f175f7dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/is_empty.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 "_specs.hpp"
+#include <auto/is_empty.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/length.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/length.cpp
new file mode 100644
index 00000000..55111dd6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/length.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 "_specs.hpp"
+#include <auto/length.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/lexicographical_compare.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/lexicographical_compare.cpp
new file mode 100644
index 00000000..4d2f3edf
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/lexicographical_compare.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 "_specs.hpp"
+#include <auto/lexicographical_compare.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/make.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/make.cpp
new file mode 100644
index 00000000..f90514f1
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/make.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 "_specs.hpp"
+#include <auto/make.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/none_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/none_of.cpp
new file mode 100644
index 00000000..b56a27b4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/none_of.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 "_specs.hpp"
+#include <auto/none_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/partition.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/partition.cpp
new file mode 100644
index 00000000..ba9621a6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/partition.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 "_specs.hpp"
+#include <auto/partition.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/permutations.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/permutations.cpp
new file mode 100644
index 00000000..3c1a6e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/permutations.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 "_specs.hpp"
+#include <auto/permutations.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/remove_at.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/remove_at.cpp
new file mode 100644
index 00000000..5b7c5af4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/remove_at.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 "_specs.hpp"
+#include <auto/remove_at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/remove_range.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/remove_range.cpp
new file mode 100644
index 00000000..6d7c6e09
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/remove_range.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 "_specs.hpp"
+#include <auto/remove_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/reverse.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/reverse.cpp
new file mode 100644
index 00000000..342278df
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/reverse.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 "_specs.hpp"
+#include <auto/reverse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/scans.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/scans.cpp
new file mode 100644
index 00000000..36dd3243
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/scans.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 "_specs.hpp"
+#include <auto/scans.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/sequence.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/sequence.cpp
new file mode 100644
index 00000000..4ed01e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/sequence.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 "_specs.hpp"
+#include <auto/sequence.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/slice.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/slice.cpp
new file mode 100644
index 00000000..3e20df95
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/slice.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 "_specs.hpp"
+#include <auto/slice.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/sort.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/sort.cpp
new file mode 100644
index 00000000..f639ddeb
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/sort.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 "_specs.hpp"
+#include <auto/sort.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/span.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/span.cpp
new file mode 100644
index 00000000..297b7f17
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/span.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 "_specs.hpp"
+#include <auto/span.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_back.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_back.cpp
new file mode 100644
index 00000000..2a91d7d4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_back.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 "_specs.hpp"
+#include <auto/take_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_front.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_front.cpp
new file mode 100644
index 00000000..9a48d2b8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_front.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 "_specs.hpp"
+#include <auto/take_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_while.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_while.cpp
new file mode 100644
index 00000000..e58c99ac
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/take_while.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 "_specs.hpp"
+#include <auto/take_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/transform.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/transform.cpp
new file mode 100644
index 00000000..306c1bc3
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/transform.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 "_specs.hpp"
+#include <auto/transform.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/unfolds.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/unfolds.cpp
new file mode 100644
index 00000000..f8bac9dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/unfolds.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 "_specs.hpp"
+#include <auto/unfolds.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/unique.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/unique.cpp
new file mode 100644
index 00000000..9c1dc715
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/unique.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 "_specs.hpp"
+#include <auto/unique.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/zips.cpp b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/zips.cpp
new file mode 100644
index 00000000..32ec5cc8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/deque/auto/zips.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 "_specs.hpp"
+#include <auto/zips.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/_specs.hpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/_specs.hpp
new file mode 100644
index 00000000..1bc300cf
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/_specs.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_EXT_BOOST_FUSION_LIST_AUTO_SPECS_HPP
+#define BOOST_HANA_TEST_EXT_BOOST_FUSION_LIST_AUTO_SPECS_HPP
+
+#include <boost/hana/ext/boost/fusion/list.hpp>
+
+#include <boost/fusion/container/generation/make_list.hpp>
+#include <boost/fusion/container/list.hpp>
+
+
+#define MAKE_TUPLE(...) ::boost::fusion::make_list(__VA_ARGS__)
+#define TUPLE_TYPE(...) ::boost::fusion::list<__VA_ARGS__>
+#define TUPLE_TAG ::boost::hana::ext::boost::fusion::list_tag
+
+#endif // !BOOST_HANA_TEST_EXT_BOOST_FUSION_LIST_AUTO_SPECS_HPP
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/all_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/all_of.cpp
new file mode 100644
index 00000000..f3e974ff
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/all_of.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 "_specs.hpp"
+#include <auto/all_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/any_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/any_of.cpp
new file mode 100644
index 00000000..3065d017
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/any_of.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 "_specs.hpp"
+#include <auto/any_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/ap.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/ap.cpp
new file mode 100644
index 00000000..59c9cb75
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/ap.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 "_specs.hpp"
+#include <auto/ap.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/at.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/at.cpp
new file mode 100644
index 00000000..60526533
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/at.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 "_specs.hpp"
+#include <auto/at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/cartesian_product.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/cartesian_product.cpp
new file mode 100644
index 00000000..b0795e8d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/cartesian_product.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 "_specs.hpp"
+#include <auto/cartesian_product.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_back.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_back.cpp
new file mode 100644
index 00000000..b283844d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_back.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 "_specs.hpp"
+#include <auto/drop_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_front.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_front.cpp
new file mode 100644
index 00000000..a39d6f45
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_front.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 "_specs.hpp"
+#include <auto/drop_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_while.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_while.cpp
new file mode 100644
index 00000000..18907f03
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/drop_while.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 "_specs.hpp"
+#include <auto/drop_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/for_each.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/for_each.cpp
new file mode 100644
index 00000000..714fe03c
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/for_each.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 "_specs.hpp"
+#include <auto/for_each.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/group.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/group.cpp
new file mode 100644
index 00000000..0669b496
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/group.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 "_specs.hpp"
+#include <auto/group.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/index_if.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/index_if.cpp
new file mode 100644
index 00000000..ef37fe65
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/index_if.cpp
@@ -0,0 +1,9 @@
+// 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 "_specs.hpp"
+#include <auto/index_if.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/insert.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/insert.cpp
new file mode 100644
index 00000000..e8efc6dc
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/insert.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 "_specs.hpp"
+#include <auto/insert.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/insert_range.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/insert_range.cpp
new file mode 100644
index 00000000..05ac5774
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/insert_range.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 "_specs.hpp"
+#include <auto/insert_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/intersperse.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/intersperse.cpp
new file mode 100644
index 00000000..185c814a
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/intersperse.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 "_specs.hpp"
+#include <auto/intersperse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/is_empty.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/is_empty.cpp
new file mode 100644
index 00000000..f175f7dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/is_empty.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 "_specs.hpp"
+#include <auto/is_empty.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/length.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/length.cpp
new file mode 100644
index 00000000..55111dd6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/length.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 "_specs.hpp"
+#include <auto/length.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/lexicographical_compare.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/lexicographical_compare.cpp
new file mode 100644
index 00000000..4d2f3edf
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/lexicographical_compare.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 "_specs.hpp"
+#include <auto/lexicographical_compare.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/make.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/make.cpp
new file mode 100644
index 00000000..f90514f1
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/make.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 "_specs.hpp"
+#include <auto/make.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/none_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/none_of.cpp
new file mode 100644
index 00000000..b56a27b4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/none_of.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 "_specs.hpp"
+#include <auto/none_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/partition.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/partition.cpp
new file mode 100644
index 00000000..ba9621a6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/partition.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 "_specs.hpp"
+#include <auto/partition.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/permutations.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/permutations.cpp
new file mode 100644
index 00000000..3c1a6e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/permutations.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 "_specs.hpp"
+#include <auto/permutations.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/remove_at.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/remove_at.cpp
new file mode 100644
index 00000000..5b7c5af4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/remove_at.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 "_specs.hpp"
+#include <auto/remove_at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/remove_range.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/remove_range.cpp
new file mode 100644
index 00000000..6d7c6e09
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/remove_range.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 "_specs.hpp"
+#include <auto/remove_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/reverse.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/reverse.cpp
new file mode 100644
index 00000000..342278df
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/reverse.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 "_specs.hpp"
+#include <auto/reverse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/scans.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/scans.cpp
new file mode 100644
index 00000000..36dd3243
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/scans.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 "_specs.hpp"
+#include <auto/scans.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/sequence.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/sequence.cpp
new file mode 100644
index 00000000..4ed01e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/sequence.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 "_specs.hpp"
+#include <auto/sequence.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/slice.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/slice.cpp
new file mode 100644
index 00000000..3e20df95
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/slice.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 "_specs.hpp"
+#include <auto/slice.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/sort.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/sort.cpp
new file mode 100644
index 00000000..f639ddeb
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/sort.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 "_specs.hpp"
+#include <auto/sort.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/span.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/span.cpp
new file mode 100644
index 00000000..297b7f17
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/span.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 "_specs.hpp"
+#include <auto/span.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_back.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_back.cpp
new file mode 100644
index 00000000..2a91d7d4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_back.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 "_specs.hpp"
+#include <auto/take_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_front.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_front.cpp
new file mode 100644
index 00000000..9a48d2b8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_front.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 "_specs.hpp"
+#include <auto/take_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_while.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_while.cpp
new file mode 100644
index 00000000..e58c99ac
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/take_while.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 "_specs.hpp"
+#include <auto/take_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/transform.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/transform.cpp
new file mode 100644
index 00000000..306c1bc3
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/transform.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 "_specs.hpp"
+#include <auto/transform.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/unfolds.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/unfolds.cpp
new file mode 100644
index 00000000..f8bac9dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/unfolds.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 "_specs.hpp"
+#include <auto/unfolds.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/unique.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/unique.cpp
new file mode 100644
index 00000000..9c1dc715
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/unique.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 "_specs.hpp"
+#include <auto/unique.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/list/auto/zips.cpp b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/zips.cpp
new file mode 100644
index 00000000..32ec5cc8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/list/auto/zips.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 "_specs.hpp"
+#include <auto/zips.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/_specs.hpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/_specs.hpp
new file mode 100644
index 00000000..5024efc4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/_specs.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_EXT_BOOST_FUSION_TUPLE_AUTO_SPECS_HPP
+#define BOOST_HANA_TEST_EXT_BOOST_FUSION_TUPLE_AUTO_SPECS_HPP
+
+#define FUSION_MAX_VECTOR_SIZE 50
+#include <boost/hana/ext/boost/fusion/tuple.hpp>
+
+#include <boost/fusion/tuple.hpp>
+
+
+#define MAKE_TUPLE(...) ::boost::fusion::make_tuple(__VA_ARGS__)
+#define TUPLE_TYPE(...) ::boost::fusion::tuple<__VA_ARGS__>
+#define TUPLE_TAG ::boost::hana::ext::boost::fusion::tuple_tag
+#define MAKE_TUPLE_NO_CONSTEXPR
+
+#endif // !BOOST_HANA_TEST_EXT_BOOST_FUSION_TUPLE_AUTO_SPECS_HPP
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/all_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/all_of.cpp
new file mode 100644
index 00000000..f3e974ff
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/all_of.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 "_specs.hpp"
+#include <auto/all_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/any_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/any_of.cpp
new file mode 100644
index 00000000..3065d017
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/any_of.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 "_specs.hpp"
+#include <auto/any_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/ap.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/ap.cpp
new file mode 100644
index 00000000..59c9cb75
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/ap.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 "_specs.hpp"
+#include <auto/ap.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/at.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/at.cpp
new file mode 100644
index 00000000..60526533
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/at.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 "_specs.hpp"
+#include <auto/at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/cartesian_product.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/cartesian_product.cpp
new file mode 100644
index 00000000..b0795e8d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/cartesian_product.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 "_specs.hpp"
+#include <auto/cartesian_product.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_back.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_back.cpp
new file mode 100644
index 00000000..b283844d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_back.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 "_specs.hpp"
+#include <auto/drop_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_front.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_front.cpp
new file mode 100644
index 00000000..a39d6f45
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_front.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 "_specs.hpp"
+#include <auto/drop_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_while.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_while.cpp
new file mode 100644
index 00000000..18907f03
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/drop_while.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 "_specs.hpp"
+#include <auto/drop_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/for_each.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/for_each.cpp
new file mode 100644
index 00000000..714fe03c
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/for_each.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 "_specs.hpp"
+#include <auto/for_each.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/group.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/group.cpp
new file mode 100644
index 00000000..0669b496
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/group.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 "_specs.hpp"
+#include <auto/group.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/index_if.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/index_if.cpp
new file mode 100644
index 00000000..ef37fe65
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/index_if.cpp
@@ -0,0 +1,9 @@
+// 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 "_specs.hpp"
+#include <auto/index_if.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/insert.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/insert.cpp
new file mode 100644
index 00000000..e8efc6dc
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/insert.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 "_specs.hpp"
+#include <auto/insert.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/insert_range.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/insert_range.cpp
new file mode 100644
index 00000000..05ac5774
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/insert_range.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 "_specs.hpp"
+#include <auto/insert_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/intersperse.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/intersperse.cpp
new file mode 100644
index 00000000..185c814a
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/intersperse.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 "_specs.hpp"
+#include <auto/intersperse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/is_empty.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/is_empty.cpp
new file mode 100644
index 00000000..f175f7dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/is_empty.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 "_specs.hpp"
+#include <auto/is_empty.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/length.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/length.cpp
new file mode 100644
index 00000000..55111dd6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/length.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 "_specs.hpp"
+#include <auto/length.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/lexicographical_compare.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/lexicographical_compare.cpp
new file mode 100644
index 00000000..4d2f3edf
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/lexicographical_compare.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 "_specs.hpp"
+#include <auto/lexicographical_compare.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/make.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/make.cpp
new file mode 100644
index 00000000..f90514f1
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/make.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 "_specs.hpp"
+#include <auto/make.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/none_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/none_of.cpp
new file mode 100644
index 00000000..b56a27b4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/none_of.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 "_specs.hpp"
+#include <auto/none_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/partition.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/partition.cpp
new file mode 100644
index 00000000..ba9621a6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/partition.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 "_specs.hpp"
+#include <auto/partition.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/permutations.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/permutations.cpp
new file mode 100644
index 00000000..3c1a6e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/permutations.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 "_specs.hpp"
+#include <auto/permutations.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/remove_at.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/remove_at.cpp
new file mode 100644
index 00000000..5b7c5af4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/remove_at.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 "_specs.hpp"
+#include <auto/remove_at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/remove_range.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/remove_range.cpp
new file mode 100644
index 00000000..6d7c6e09
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/remove_range.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 "_specs.hpp"
+#include <auto/remove_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/reverse.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/reverse.cpp
new file mode 100644
index 00000000..342278df
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/reverse.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 "_specs.hpp"
+#include <auto/reverse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/scans.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/scans.cpp
new file mode 100644
index 00000000..36dd3243
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/scans.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 "_specs.hpp"
+#include <auto/scans.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/sequence.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/sequence.cpp
new file mode 100644
index 00000000..4ed01e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/sequence.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 "_specs.hpp"
+#include <auto/sequence.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/slice.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/slice.cpp
new file mode 100644
index 00000000..3e20df95
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/slice.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 "_specs.hpp"
+#include <auto/slice.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/sort.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/sort.cpp
new file mode 100644
index 00000000..f639ddeb
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/sort.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 "_specs.hpp"
+#include <auto/sort.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/span.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/span.cpp
new file mode 100644
index 00000000..297b7f17
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/span.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 "_specs.hpp"
+#include <auto/span.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_back.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_back.cpp
new file mode 100644
index 00000000..2a91d7d4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_back.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 "_specs.hpp"
+#include <auto/take_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_front.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_front.cpp
new file mode 100644
index 00000000..9a48d2b8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_front.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 "_specs.hpp"
+#include <auto/take_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_while.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_while.cpp
new file mode 100644
index 00000000..e58c99ac
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/take_while.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 "_specs.hpp"
+#include <auto/take_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/transform.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/transform.cpp
new file mode 100644
index 00000000..306c1bc3
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/transform.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 "_specs.hpp"
+#include <auto/transform.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/unfolds.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/unfolds.cpp
new file mode 100644
index 00000000..f8bac9dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/unfolds.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 "_specs.hpp"
+#include <auto/unfolds.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/unique.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/unique.cpp
new file mode 100644
index 00000000..9c1dc715
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/unique.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 "_specs.hpp"
+#include <auto/unique.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/zips.cpp b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/zips.cpp
new file mode 100644
index 00000000..32ec5cc8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/tuple/auto/zips.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 "_specs.hpp"
+#include <auto/zips.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/_specs.hpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/_specs.hpp
new file mode 100644
index 00000000..3b87a1d8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/_specs.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_EXT_BOOST_FUSION_VECTOR_AUTO_SPECS_HPP
+#define BOOST_HANA_TEST_EXT_BOOST_FUSION_VECTOR_AUTO_SPECS_HPP
+
+#define FUSION_MAX_VECTOR_SIZE 50
+#include <boost/hana/ext/boost/fusion/vector.hpp>
+
+#include <boost/fusion/container/generation/make_vector.hpp>
+#include <boost/fusion/container/vector.hpp>
+
+#define MAKE_TUPLE(...) ::boost::fusion::make_vector(__VA_ARGS__)
+#define TUPLE_TYPE(...) ::boost::fusion::vector<__VA_ARGS__>
+#define TUPLE_TAG ::boost::hana::ext::boost::fusion::vector_tag
+#define MAKE_TUPLE_NO_CONSTEXPR
+
+#endif // !BOOST_HANA_TEST_EXT_BOOST_FUSION_VECTOR_AUTO_SPECS_HPP
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/all_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/all_of.cpp
new file mode 100644
index 00000000..f3e974ff
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/all_of.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 "_specs.hpp"
+#include <auto/all_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/any_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/any_of.cpp
new file mode 100644
index 00000000..3065d017
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/any_of.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 "_specs.hpp"
+#include <auto/any_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/ap.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/ap.cpp
new file mode 100644
index 00000000..59c9cb75
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/ap.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 "_specs.hpp"
+#include <auto/ap.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/at.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/at.cpp
new file mode 100644
index 00000000..60526533
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/at.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 "_specs.hpp"
+#include <auto/at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/cartesian_product.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/cartesian_product.cpp
new file mode 100644
index 00000000..b0795e8d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/cartesian_product.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 "_specs.hpp"
+#include <auto/cartesian_product.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_back.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_back.cpp
new file mode 100644
index 00000000..b283844d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_back.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 "_specs.hpp"
+#include <auto/drop_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_front.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_front.cpp
new file mode 100644
index 00000000..a39d6f45
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_front.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 "_specs.hpp"
+#include <auto/drop_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_while.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_while.cpp
new file mode 100644
index 00000000..18907f03
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/drop_while.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 "_specs.hpp"
+#include <auto/drop_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/for_each.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/for_each.cpp
new file mode 100644
index 00000000..714fe03c
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/for_each.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 "_specs.hpp"
+#include <auto/for_each.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/group.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/group.cpp
new file mode 100644
index 00000000..0669b496
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/group.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 "_specs.hpp"
+#include <auto/group.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/index_if.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/index_if.cpp
new file mode 100644
index 00000000..ef37fe65
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/index_if.cpp
@@ -0,0 +1,9 @@
+// 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 "_specs.hpp"
+#include <auto/index_if.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/insert.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/insert.cpp
new file mode 100644
index 00000000..e8efc6dc
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/insert.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 "_specs.hpp"
+#include <auto/insert.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/insert_range.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/insert_range.cpp
new file mode 100644
index 00000000..05ac5774
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/insert_range.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 "_specs.hpp"
+#include <auto/insert_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/intersperse.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/intersperse.cpp
new file mode 100644
index 00000000..185c814a
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/intersperse.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 "_specs.hpp"
+#include <auto/intersperse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/is_empty.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/is_empty.cpp
new file mode 100644
index 00000000..f175f7dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/is_empty.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 "_specs.hpp"
+#include <auto/is_empty.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/length.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/length.cpp
new file mode 100644
index 00000000..55111dd6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/length.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 "_specs.hpp"
+#include <auto/length.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/lexicographical_compare.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/lexicographical_compare.cpp
new file mode 100644
index 00000000..4d2f3edf
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/lexicographical_compare.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 "_specs.hpp"
+#include <auto/lexicographical_compare.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/make.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/make.cpp
new file mode 100644
index 00000000..f90514f1
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/make.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 "_specs.hpp"
+#include <auto/make.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/none_of.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/none_of.cpp
new file mode 100644
index 00000000..b56a27b4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/none_of.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 "_specs.hpp"
+#include <auto/none_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/partition.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/partition.cpp
new file mode 100644
index 00000000..ba9621a6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/partition.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 "_specs.hpp"
+#include <auto/partition.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/permutations.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/permutations.cpp
new file mode 100644
index 00000000..3c1a6e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/permutations.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 "_specs.hpp"
+#include <auto/permutations.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/remove_at.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/remove_at.cpp
new file mode 100644
index 00000000..5b7c5af4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/remove_at.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 "_specs.hpp"
+#include <auto/remove_at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/remove_range.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/remove_range.cpp
new file mode 100644
index 00000000..6d7c6e09
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/remove_range.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 "_specs.hpp"
+#include <auto/remove_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/reverse.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/reverse.cpp
new file mode 100644
index 00000000..342278df
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/reverse.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 "_specs.hpp"
+#include <auto/reverse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/scans.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/scans.cpp
new file mode 100644
index 00000000..36dd3243
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/scans.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 "_specs.hpp"
+#include <auto/scans.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/sequence.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/sequence.cpp
new file mode 100644
index 00000000..4ed01e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/sequence.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 "_specs.hpp"
+#include <auto/sequence.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/slice.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/slice.cpp
new file mode 100644
index 00000000..3e20df95
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/slice.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 "_specs.hpp"
+#include <auto/slice.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/sort.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/sort.cpp
new file mode 100644
index 00000000..f639ddeb
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/sort.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 "_specs.hpp"
+#include <auto/sort.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/span.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/span.cpp
new file mode 100644
index 00000000..297b7f17
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/span.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 "_specs.hpp"
+#include <auto/span.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_back.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_back.cpp
new file mode 100644
index 00000000..2a91d7d4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_back.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 "_specs.hpp"
+#include <auto/take_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_front.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_front.cpp
new file mode 100644
index 00000000..9a48d2b8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_front.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 "_specs.hpp"
+#include <auto/take_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_while.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_while.cpp
new file mode 100644
index 00000000..e58c99ac
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/take_while.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 "_specs.hpp"
+#include <auto/take_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/transform.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/transform.cpp
new file mode 100644
index 00000000..306c1bc3
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/transform.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 "_specs.hpp"
+#include <auto/transform.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/unfolds.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/unfolds.cpp
new file mode 100644
index 00000000..f8bac9dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/unfolds.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 "_specs.hpp"
+#include <auto/unfolds.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/unique.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/unique.cpp
new file mode 100644
index 00000000..9c1dc715
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/unique.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 "_specs.hpp"
+#include <auto/unique.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/zips.cpp b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/zips.cpp
new file mode 100644
index 00000000..32ec5cc8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/fusion/vector/auto/zips.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 "_specs.hpp"
+#include <auto/zips.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/integral_c/arithmetic.cpp b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/arithmetic.cpp
new file mode 100644
index 00000000..0dfef371
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/arithmetic.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/ext/boost/mpl/integral_c.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/euclidean_ring.hpp>
+#include <laws/group.hpp>
+#include <laws/monoid.hpp>
+#include <laws/ring.hpp>
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+int main() {
+ auto ints = hana::make_tuple(
+ mpl::int_<-10>{}, mpl::int_<-2>{}, mpl::integral_c<int, 0>{},
+ mpl::integral_c<int, 1>{}, mpl::integral_c<int, 3>{}
+ );
+
+ hana::test::TestMonoid<hana::ext::boost::mpl::integral_c_tag<int>>{ints};
+ hana::test::TestGroup<hana::ext::boost::mpl::integral_c_tag<int>>{ints};
+ hana::test::TestRing<hana::ext::boost::mpl::integral_c_tag<int>>{ints};
+ hana::test::TestEuclideanRing<hana::ext::boost::mpl::integral_c_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/integral_c/comparable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/comparable.cpp
new file mode 100644
index 00000000..60a0e5be
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/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/ext/boost/mpl/integral_c.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+#include <laws/hashable.hpp>
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+int main() {
+ auto ints = hana::make_tuple(
+ mpl::int_<-10>{}, mpl::int_<-2>{}, mpl::integral_c<int, 0>{},
+ mpl::integral_c<int, 1>{}, mpl::integral_c<int, 3>{}
+ );
+
+ hana::test::TestComparable<hana::ext::boost::mpl::integral_c_tag<int>>{ints};
+ hana::test::TestHashable<hana::ext::boost::mpl::integral_c_tag<void>>{ints};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/integral_c/constant.cpp b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/constant.cpp
new file mode 100644
index 00000000..6831d6cf
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/constant.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/ext/boost/mpl/integral_c.hpp>
+
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/value.hpp>
+
+#include <laws/constant.hpp>
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+int main() {
+ // value
+ static_assert(hana::value(mpl::integral_c<int, 0>{}) == 0, "");
+ static_assert(hana::value(mpl::integral_c<int, 1>{}) == 1, "");
+ static_assert(hana::value(mpl::integral_c<int, 3>{}) == 3, "");
+
+ // laws
+ hana::test::TestConstant<hana::ext::boost::mpl::integral_c_tag<int>>{
+ hana::make_tuple(
+ mpl::int_<-10>{}, mpl::int_<-2>{}, mpl::integral_c<int, 0>{},
+ mpl::integral_c<int, 1>{}, mpl::integral_c<int, 3>{}
+ ),
+ hana::tuple_t<int, long, long long>
+ };
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/integral_c/interop.cpp b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/interop.cpp
new file mode 100644
index 00000000..949e477d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/interop.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/boost/mpl/integral_c.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <boost/mpl/integral_c.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+int main() {
+ // Interoperation with hana::integral_constant
+ BOOST_HANA_CONSTANT_CHECK(mpl::integral_c<int, 1>{} == hana::int_c<1>);
+ BOOST_HANA_CONSTANT_CHECK(mpl::integral_c<int, 1>{} == hana::long_c<1>);
+
+ BOOST_HANA_CONSTANT_CHECK(mpl::integral_c<int, 2>{} != hana::int_c<3>);
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/integral_c/logical.cpp b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/logical.cpp
new file mode 100644
index 00000000..10c0e19a
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/logical.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/ext/boost/mpl/integral_c.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/logical.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+int main() {
+ // eval_if
+ {
+ auto t = hana::test::ct_eq<3>{};
+ auto e = hana::test::ct_eq<4>{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval_if(mpl::true_{}, hana::always(t), hana::always(e)),
+ t
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval_if(mpl::false_{}, hana::always(t), hana::always(e)),
+ e
+ ));
+ }
+
+ // not_
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::not_(mpl::true_{}),
+ mpl::false_{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::not_(mpl::false_{}),
+ mpl::true_{}
+ ));
+ }
+
+ // laws
+ hana::test::TestLogical<hana::ext::boost::mpl::integral_c_tag<int>>{
+ hana::make_tuple(
+ mpl::int_<-2>{}, mpl::integral_c<int, 0>{}, mpl::integral_c<int, 3>{}
+ )
+ };
+
+ hana::test::TestLogical<hana::ext::boost::mpl::integral_c_tag<bool>>{
+ hana::make_tuple(
+ mpl::true_{}, mpl::false_{},
+ mpl::integral_c<bool, true>{}, mpl::integral_c<bool, false>{}
+ )
+ };
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/integral_c/orderable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/orderable.cpp
new file mode 100644
index 00000000..24ee5b75
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/orderable.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/ext/boost/mpl/integral_c.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/orderable.hpp>
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+int main() {
+ auto ints = hana::make_tuple(
+ mpl::int_<-10>{}, mpl::int_<-2>{}, mpl::integral_c<int, 0>{},
+ mpl::integral_c<int, 1>{}, mpl::integral_c<int, 3>{}
+ );
+
+ hana::test::TestOrderable<hana::ext::boost::mpl::integral_c_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/integral_c/tag.cpp b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/tag.cpp
new file mode 100644
index 00000000..55b33a8c
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/integral_c/tag.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/ext/boost/mpl/integral_c.hpp>
+
+#include <boost/hana/core/tag_of.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/char.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+#include <boost/mpl/long.hpp>
+#include <boost/mpl/size_t.hpp>
+
+#include <cstddef>
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::bool_<true>>,
+ hana::ext::boost::mpl::integral_c_tag<bool>
+>::value, "");
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::int_<0>>,
+ hana::ext::boost::mpl::integral_c_tag<int>
+>::value, "");
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::long_<0>>,
+ hana::ext::boost::mpl::integral_c_tag<long>
+>::value, "");
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::size_t<0>>,
+ hana::ext::boost::mpl::integral_c_tag<std::size_t>
+>::value, "");
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::integral_c<int, 0>>,
+ hana::ext::boost::mpl::integral_c_tag<int>
+>::value, "");
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::char_<0>>,
+ hana::ext::boost::mpl::integral_c_tag<char>
+>::value, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/list/comparable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/list/comparable.cpp
new file mode 100644
index 00000000..fd13b530
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/list/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/ext/boost/mpl/list.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+
+#include <boost/mpl/list.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ auto lists = hana::make_tuple(
+ mpl::list<>{}
+ , mpl::list<t1>{}
+ , mpl::list<t1, t2>{}
+ , mpl::list<t1, t2, t3>{}
+ , mpl::list<t1, t2, t3, t4>{}
+ );
+
+ hana::test::TestComparable<hana::ext::boost::mpl::list_tag>{lists};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/list/foldable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/list/foldable.cpp
new file mode 100644
index 00000000..1c469777
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/list/foldable.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/ext/boost/mpl/list.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/unpack.hpp>
+#include <boost/hana/type.hpp>
+
+#include <laws/base.hpp>
+#include <laws/foldable.hpp>
+
+#include <boost/mpl/list.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ // unpack
+ {
+ hana::test::_injection<0> f{};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(mpl::list<>{}, f),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(mpl::list<t1>{}, f),
+ f(hana::type_c<t1>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(mpl::list<t1, t2>{}, f),
+ f(hana::type_c<t1>, hana::type_c<t2>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(mpl::list<t1, t2, t3>{}, f),
+ f(hana::type_c<t1>, hana::type_c<t2>, hana::type_c<t3>)
+ ));
+ }
+
+ // laws
+ auto lists = hana::make_tuple(
+ mpl::list<>{}
+ , mpl::list<t1>{}
+ , mpl::list<t1, t2>{}
+ , mpl::list<t1, t2, t3>{}
+ , mpl::list<t1, t2, t3, t4>{}
+ );
+
+ hana::test::TestFoldable<hana::ext::boost::mpl::list_tag>{lists};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/list/iterable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/list/iterable.cpp
new file mode 100644
index 00000000..68a900ee
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/list/iterable.cpp
@@ -0,0 +1,95 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/boost/mpl/list.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <laws/iterable.hpp>
+
+#include <boost/mpl/list.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ // front
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(mpl::list<t1>{}),
+ hana::type_c<t1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(mpl::list<t1, t2>{}),
+ hana::type_c<t1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(mpl::list<t1, t2, t3>{}),
+ hana::type_c<t1>
+ ));
+ }
+
+ // drop_front_exactly
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::list<t1>{}),
+ mpl::list<>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::list<t1, t2>{}),
+ mpl::list<t2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::list<t1, t2, t3>{}),
+ mpl::list<t2, t3>{}
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::list<t1, t2, t3>{}, hana::size_c<2>),
+ mpl::list<t3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::list<t1, t2, t3, t4>{}, hana::size_c<2>),
+ mpl::list<t3, t4>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::list<t1, t2, t3, t4>{}, hana::size_c<3>),
+ mpl::list<t4>{}
+ ));
+ }
+
+ // is_empty
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(mpl::list<>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(mpl::list0<>{}));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(mpl::list<t1>{})));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(mpl::list1<t1>{})));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(mpl::list<t1, t2>{})));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(mpl::list2<t1, t2>{})));
+ }
+
+ // laws
+ auto lists = hana::make_tuple(
+ mpl::list<>{}
+ , mpl::list<t1>{}
+ , mpl::list<t1, t2>{}
+ , mpl::list<t1, t2, t3>{}
+ , mpl::list<t1, t2, t3, t4>{}
+ );
+ hana::test::TestIterable<hana::ext::boost::mpl::list_tag>{lists};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/list/searchable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/list/searchable.cpp
new file mode 100644
index 00000000..50b3a15e
--- /dev/null
+++ b/src/boost/libs/hana/test/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/ext/boost/mpl/list.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/searchable.hpp>
+
+#include <boost/mpl/list.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ auto lists = hana::make_tuple(
+ mpl::list<>{}
+ , mpl::list<t1>{}
+ , mpl::list<t1, t2>{}
+ , mpl::list<t1, t2, t3>{}
+ , mpl::list<t1, t2, t3, t4>{}
+ );
+
+ auto keys = hana::tuple_t<t1, t2, void>;
+
+ hana::test::TestSearchable<hana::ext::boost::mpl::list_tag>{lists, keys};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/list/tag.cpp b/src/boost/libs/hana/test/ext/boost/mpl/list/tag.cpp
new file mode 100644
index 00000000..3cfc26ae
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/list/tag.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/ext/boost/mpl/list.hpp>
+
+#include <boost/hana/core/tag_of.hpp>
+
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/quote.hpp>
+#include <boost/mpl/transform.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+using mpl_id = mpl::quote1<mpl::identity>;
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::list<>>,
+ hana::ext::boost::mpl::list_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::list<>::type>,
+ hana::ext::boost::mpl::list_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::transform<mpl::list<>, mpl_id>::type>,
+ hana::ext::boost::mpl::list_tag
+>{}, "");
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::list<t1>>,
+ hana::ext::boost::mpl::list_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::list<t1>::type>,
+ hana::ext::boost::mpl::list_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::transform<mpl::list<t1>, mpl_id>::type>,
+ hana::ext::boost::mpl::list_tag
+>{}, "");
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::list<t1, t2>>,
+ hana::ext::boost::mpl::list_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::list<t1, t2>::type>,
+ hana::ext::boost::mpl::list_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::transform<mpl::list<t1, t2>, mpl_id>::type>,
+ hana::ext::boost::mpl::list_tag
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/list/to.cpp b/src/boost/libs/hana/test/ext/boost/mpl/list/to.cpp
new file mode 100644
index 00000000..bd8808af
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/list/to.cpp
@@ -0,0 +1,49 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/boost/mpl/list.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/type.hpp>
+
+#include <support/seq.hpp>
+
+#include <boost/mpl/list.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ // Conversion from any `Foldable` containing `type`s
+ auto foldable = ::seq;
+ auto to_list = hana::to<hana::ext::boost::mpl::list_tag>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_list(foldable()),
+ mpl::list<>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_list(foldable(hana::type_c<t1>)),
+ mpl::list<t1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_list(foldable(hana::type_c<t1>, hana::type_c<t2>)),
+ mpl::list<t1, t2>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_list(foldable(hana::type_c<t1>, hana::type_c<t2>, hana::type_c<t3>)),
+ mpl::list<t1, t2, t3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_list(foldable(hana::type_c<t1>, hana::type_c<t2>, hana::type_c<t3>, hana::type_c<t4>)),
+ mpl::list<t1, t2, t3, t4>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/vector/comparable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/vector/comparable.cpp
new file mode 100644
index 00000000..55557f31
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/vector/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/ext/boost/mpl/vector.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+
+#include <boost/mpl/vector.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ auto vectors = hana::make_tuple(
+ mpl::vector<>{}
+ , mpl::vector<t1>{}
+ , mpl::vector<t1, t2>{}
+ , mpl::vector<t1, t2, t3>{}
+ , mpl::vector<t1, t2, t3, t4>{}
+ );
+
+ hana::test::TestComparable<hana::ext::boost::mpl::vector_tag>{vectors};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/vector/foldable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/vector/foldable.cpp
new file mode 100644
index 00000000..4143cd58
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/vector/foldable.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/ext/boost/mpl/vector.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/unpack.hpp>
+#include <boost/hana/type.hpp>
+
+#include <laws/base.hpp>
+#include <laws/foldable.hpp>
+
+#include <boost/mpl/vector.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ // unpack
+ {
+ hana::test::_injection<0> f{};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(mpl::vector<>{}, f),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(mpl::vector<t1>{}, f),
+ f(hana::type_c<t1>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(mpl::vector<t1, t2>{}, f),
+ f(hana::type_c<t1>, hana::type_c<t2>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(mpl::vector<t1, t2, t3>{}, f),
+ f(hana::type_c<t1>, hana::type_c<t2>, hana::type_c<t3>)
+ ));
+ }
+
+ // laws
+ auto vectors = hana::make_tuple(
+ mpl::vector<>{}
+ , mpl::vector<t1>{}
+ , mpl::vector<t1, t2>{}
+ , mpl::vector<t1, t2, t3>{}
+ , mpl::vector<t1, t2, t3, t4>{}
+ );
+
+ hana::test::TestFoldable<hana::ext::boost::mpl::vector_tag>{vectors};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/vector/iterable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/vector/iterable.cpp
new file mode 100644
index 00000000..08090af7
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/vector/iterable.cpp
@@ -0,0 +1,95 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/boost/mpl/vector.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <laws/iterable.hpp>
+
+#include <boost/mpl/vector.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ // front
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(mpl::vector<t1>{}),
+ hana::type_c<t1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(mpl::vector<t1, t2>{}),
+ hana::type_c<t1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(mpl::vector<t1, t2, t3>{}),
+ hana::type_c<t1>
+ ));
+ }
+
+ // drop_front_exactly
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::vector<t1>{}),
+ mpl::vector<>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::vector<t1, t2>{}),
+ mpl::vector<t2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::vector<t1, t2, t3>{}),
+ mpl::vector<t2, t3>{}
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::vector<t1, t2, t3>{}, hana::size_c<2>),
+ mpl::vector<t3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::vector<t1, t2, t3, t4>{}, hana::size_c<2>),
+ mpl::vector<t3, t4>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(mpl::vector<t1, t2, t3, t4>{}, hana::size_c<3>),
+ mpl::vector<t4>{}
+ ));
+ }
+
+ // is_empty
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(mpl::vector<>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(mpl::vector0<>{}));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(mpl::vector<t1>{})));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(mpl::vector1<t1>{})));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(mpl::vector<t1, t2>{})));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(mpl::vector2<t1, t2>{})));
+ }
+
+ // laws
+ auto vectors = hana::make_tuple(
+ mpl::vector<>{}
+ , mpl::vector<t1>{}
+ , mpl::vector<t1, t2>{}
+ , mpl::vector<t1, t2, t3>{}
+ , mpl::vector<t1, t2, t3, t4>{}
+ );
+ hana::test::TestIterable<hana::ext::boost::mpl::vector_tag>{vectors};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/vector/searchable.cpp b/src/boost/libs/hana/test/ext/boost/mpl/vector/searchable.cpp
new file mode 100644
index 00000000..58a0dd06
--- /dev/null
+++ b/src/boost/libs/hana/test/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/ext/boost/mpl/vector.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/searchable.hpp>
+
+#include <boost/mpl/vector.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ auto vectors = hana::make_tuple(
+ mpl::vector<>{}
+ , mpl::vector<t1>{}
+ , mpl::vector<t1, t2>{}
+ , mpl::vector<t1, t2, t3>{}
+ , mpl::vector<t1, t2, t3, t4>{}
+ );
+
+ auto keys = hana::tuple_t<t1, t2, void>;
+
+ hana::test::TestSearchable<hana::ext::boost::mpl::vector_tag>{vectors, keys};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/vector/tag.cpp b/src/boost/libs/hana/test/ext/boost/mpl/vector/tag.cpp
new file mode 100644
index 00000000..892f119b
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/vector/tag.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/ext/boost/mpl/vector.hpp>
+
+#include <boost/hana/core/tag_of.hpp>
+
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/quote.hpp>
+#include <boost/mpl/transform.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+using mpl_id = mpl::quote1<mpl::identity>;
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::vector<>>,
+ hana::ext::boost::mpl::vector_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::vector<>::type>,
+ hana::ext::boost::mpl::vector_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::transform<mpl::vector<>, mpl_id>::type>,
+ hana::ext::boost::mpl::vector_tag
+>{}, "");
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::vector<t1>>,
+ hana::ext::boost::mpl::vector_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::vector<t1>::type>,
+ hana::ext::boost::mpl::vector_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::transform<mpl::vector<t1>, mpl_id>::type>,
+ hana::ext::boost::mpl::vector_tag
+>{}, "");
+
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::vector<t1, t2>>,
+ hana::ext::boost::mpl::vector_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::vector<t1, t2>::type>,
+ hana::ext::boost::mpl::vector_tag
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<mpl::transform<mpl::vector<t1, t2>, mpl_id>::type>,
+ hana::ext::boost::mpl::vector_tag
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/mpl/vector/to.cpp b/src/boost/libs/hana/test/ext/boost/mpl/vector/to.cpp
new file mode 100644
index 00000000..0ebb6d47
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/mpl/vector/to.cpp
@@ -0,0 +1,49 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/boost/mpl/vector.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/type.hpp>
+
+#include <support/seq.hpp>
+
+#include <boost/mpl/vector.hpp>
+namespace hana = boost::hana;
+namespace mpl = boost::mpl;
+
+
+struct t1; struct t2; struct t3; struct t4;
+
+int main() {
+ // Conversion from any `Foldable` containing `type`s
+ auto foldable = ::seq;
+ auto to_vector = hana::to<hana::ext::boost::mpl::vector_tag>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_vector(foldable()),
+ mpl::vector<>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_vector(foldable(hana::type_c<t1>)),
+ mpl::vector<t1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_vector(foldable(hana::type_c<t1>, hana::type_c<t2>)),
+ mpl::vector<t1, t2>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_vector(foldable(hana::type_c<t1>, hana::type_c<t2>, hana::type_c<t3>)),
+ mpl::vector<t1, t2, t3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ to_vector(foldable(hana::type_c<t1>, hana::type_c<t2>, hana::type_c<t3>, hana::type_c<t4>)),
+ mpl::vector<t1, t2, t3, t4>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/_specs.hpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/_specs.hpp
new file mode 100644
index 00000000..3d1ff41a
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/_specs.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_EXT_BOOST_TUPLE_AUTO_SPECS_HPP
+#define BOOST_HANA_TEST_EXT_BOOST_TUPLE_AUTO_SPECS_HPP
+
+#include <boost/hana/ext/boost/tuple.hpp>
+
+#include <boost/tuple/tuple.hpp>
+
+
+#define MAKE_TUPLE(...) ::boost::make_tuple(__VA_ARGS__)
+#define TUPLE_TYPE(...) ::boost::tuple<__VA_ARGS__>
+#define TUPLE_TAG ::boost::hana::ext::boost::tuple_tag
+#define MAKE_TUPLE_NO_CONSTEXPR
+
+#endif // !BOOST_HANA_TEST_EXT_BOOST_TUPLE_AUTO_SPECS_HPP
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/all_of.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/all_of.cpp
new file mode 100644
index 00000000..f3e974ff
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/all_of.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 "_specs.hpp"
+#include <auto/all_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/any_of.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/any_of.cpp
new file mode 100644
index 00000000..3065d017
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/any_of.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 "_specs.hpp"
+#include <auto/any_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/ap.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/ap.cpp
new file mode 100644
index 00000000..59c9cb75
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/ap.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 "_specs.hpp"
+#include <auto/ap.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/at.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/at.cpp
new file mode 100644
index 00000000..60526533
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/at.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 "_specs.hpp"
+#include <auto/at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/cartesian_product.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/cartesian_product.cpp
new file mode 100644
index 00000000..b0795e8d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/cartesian_product.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 "_specs.hpp"
+#include <auto/cartesian_product.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/drop_back.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/drop_back.cpp
new file mode 100644
index 00000000..b283844d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/drop_back.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 "_specs.hpp"
+#include <auto/drop_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/drop_front.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/drop_front.cpp
new file mode 100644
index 00000000..a39d6f45
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/drop_front.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 "_specs.hpp"
+#include <auto/drop_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/drop_while.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/drop_while.cpp
new file mode 100644
index 00000000..18907f03
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/drop_while.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 "_specs.hpp"
+#include <auto/drop_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/for_each.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/for_each.cpp
new file mode 100644
index 00000000..714fe03c
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/for_each.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 "_specs.hpp"
+#include <auto/for_each.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/group.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/group.cpp
new file mode 100644
index 00000000..0669b496
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/group.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 "_specs.hpp"
+#include <auto/group.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/index_if.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/index_if.cpp
new file mode 100644
index 00000000..ef37fe65
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/index_if.cpp
@@ -0,0 +1,9 @@
+// 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 "_specs.hpp"
+#include <auto/index_if.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/insert.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/insert.cpp
new file mode 100644
index 00000000..e8efc6dc
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/insert.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 "_specs.hpp"
+#include <auto/insert.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/insert_range.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/insert_range.cpp
new file mode 100644
index 00000000..05ac5774
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/insert_range.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 "_specs.hpp"
+#include <auto/insert_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/intersperse.broken.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/intersperse.broken.cpp
new file mode 100644
index 00000000..88d5d356
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/intersperse.broken.cpp
@@ -0,0 +1,10 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#if 0
+#include "_specs.hpp"
+#include <auto/intersperse.hpp>
+#endif
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/is_empty.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/is_empty.cpp
new file mode 100644
index 00000000..f175f7dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/is_empty.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 "_specs.hpp"
+#include <auto/is_empty.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/length.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/length.cpp
new file mode 100644
index 00000000..55111dd6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/length.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 "_specs.hpp"
+#include <auto/length.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/lexicographical_compare.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/lexicographical_compare.cpp
new file mode 100644
index 00000000..4d2f3edf
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/lexicographical_compare.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 "_specs.hpp"
+#include <auto/lexicographical_compare.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/make.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/make.cpp
new file mode 100644
index 00000000..f90514f1
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/make.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 "_specs.hpp"
+#include <auto/make.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/none_of.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/none_of.cpp
new file mode 100644
index 00000000..b56a27b4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/none_of.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 "_specs.hpp"
+#include <auto/none_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/partition.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/partition.cpp
new file mode 100644
index 00000000..ba9621a6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/partition.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 "_specs.hpp"
+#include <auto/partition.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/permutations.broken.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/permutations.broken.cpp
new file mode 100644
index 00000000..0b505bf3
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/permutations.broken.cpp
@@ -0,0 +1,10 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#if 0
+#include "_specs.hpp"
+#include <auto/permutations.hpp>
+#endif
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/remove_at.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/remove_at.cpp
new file mode 100644
index 00000000..5b7c5af4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/remove_at.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 "_specs.hpp"
+#include <auto/remove_at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/remove_range.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/remove_range.cpp
new file mode 100644
index 00000000..6d7c6e09
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/remove_range.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 "_specs.hpp"
+#include <auto/remove_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/reverse.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/reverse.cpp
new file mode 100644
index 00000000..342278df
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/reverse.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 "_specs.hpp"
+#include <auto/reverse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/scans.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/scans.cpp
new file mode 100644
index 00000000..36dd3243
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/scans.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 "_specs.hpp"
+#include <auto/scans.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/sequence.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/sequence.cpp
new file mode 100644
index 00000000..4ed01e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/sequence.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 "_specs.hpp"
+#include <auto/sequence.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/slice.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/slice.cpp
new file mode 100644
index 00000000..3e20df95
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/slice.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 "_specs.hpp"
+#include <auto/slice.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/sort.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/sort.cpp
new file mode 100644
index 00000000..f639ddeb
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/sort.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 "_specs.hpp"
+#include <auto/sort.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/span.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/span.cpp
new file mode 100644
index 00000000..297b7f17
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/span.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 "_specs.hpp"
+#include <auto/span.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/take_back.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/take_back.cpp
new file mode 100644
index 00000000..2a91d7d4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/take_back.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 "_specs.hpp"
+#include <auto/take_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/take_front.broken.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/take_front.broken.cpp
new file mode 100644
index 00000000..f155b386
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/take_front.broken.cpp
@@ -0,0 +1,10 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#if 0
+#include "_specs.hpp"
+#include <auto/take_front.hpp>
+#endif
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/take_while.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/take_while.cpp
new file mode 100644
index 00000000..e58c99ac
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/take_while.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 "_specs.hpp"
+#include <auto/take_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/transform.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/transform.cpp
new file mode 100644
index 00000000..306c1bc3
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/transform.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 "_specs.hpp"
+#include <auto/transform.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/unfolds.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/unfolds.cpp
new file mode 100644
index 00000000..f8bac9dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/unfolds.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 "_specs.hpp"
+#include <auto/unfolds.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/unique.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/unique.cpp
new file mode 100644
index 00000000..9c1dc715
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/unique.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 "_specs.hpp"
+#include <auto/unique.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/auto/zips.cpp b/src/boost/libs/hana/test/ext/boost/tuple/auto/zips.cpp
new file mode 100644
index 00000000..32ec5cc8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/auto/zips.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 "_specs.hpp"
+#include <auto/zips.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/iterable.cpp b/src/boost/libs/hana/test/ext/boost/tuple/iterable.cpp
new file mode 100644
index 00000000..d74a355d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/iterable.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/ext/boost/tuple.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/foldable.hpp>
+#include <laws/iterable.hpp>
+
+#include <boost/tuple/tuple.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+using eq = hana::test::ct_eq<i>;
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // Setup for the laws below
+ //////////////////////////////////////////////////////////////////////////
+ auto eq_tuples = hana::make_tuple(
+ ::boost::make_tuple()
+ , ::boost::make_tuple(eq<0>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{}, eq<2>{})
+ );
+
+ //////////////////////////////////////////////////////////////////////////
+ // Foldable, Iterable
+ //////////////////////////////////////////////////////////////////////////
+ hana::test::TestFoldable<hana::ext::boost::tuple_tag>{eq_tuples};
+ hana::test::TestIterable<hana::ext::boost::tuple_tag>{eq_tuples};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/monad.cpp b/src/boost/libs/hana/test/ext/boost/tuple/monad.cpp
new file mode 100644
index 00000000..b7af3913
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/monad.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/ext/boost/tuple.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/applicative.hpp>
+#include <laws/base.hpp>
+#include <laws/functor.hpp>
+#include <laws/monad.hpp>
+
+#include <boost/tuple/tuple.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+using eq = hana::test::ct_eq<i>;
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // Setup for the laws below
+ //////////////////////////////////////////////////////////////////////////
+ auto eq_tuples = hana::make_tuple(
+ ::boost::make_tuple()
+ , ::boost::make_tuple(eq<0>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{})
+ );
+
+ auto eq_values = hana::make_tuple(eq<0>{}, eq<2>{});
+
+ auto eq_tuples_tuples = hana::make_tuple(
+ ::boost::make_tuple()
+ , ::boost::make_tuple(
+ ::boost::make_tuple(eq<0>{}))
+ , ::boost::make_tuple(
+ ::boost::make_tuple(eq<0>{}),
+ ::boost::make_tuple(eq<1>{}, eq<2>{}))
+ , ::boost::make_tuple(
+ ::boost::make_tuple(eq<0>{}),
+ ::boost::make_tuple(eq<1>{}, eq<2>{}),
+ ::boost::make_tuple(eq<3>{}, eq<4>{}))
+ );
+
+ //////////////////////////////////////////////////////////////////////////
+ // Functor up to Monad
+ //////////////////////////////////////////////////////////////////////////
+ hana::test::TestFunctor<hana::ext::boost::tuple_tag>{eq_tuples, eq_values};
+ hana::test::TestApplicative<hana::ext::boost::tuple_tag>{eq_tuples};
+ hana::test::TestMonad<hana::ext::boost::tuple_tag>{eq_tuples, eq_tuples_tuples};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/monad_plus.cpp b/src/boost/libs/hana/test/ext/boost/tuple/monad_plus.cpp
new file mode 100644
index 00000000..ca6b5158
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/monad_plus.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/ext/boost/tuple.hpp>
+
+#include <boost/hana/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/monad_plus.hpp>
+
+#include <boost/tuple/tuple.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+using eq = hana::test::ct_eq<i>;
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // Setup for the laws below
+ //////////////////////////////////////////////////////////////////////////
+ auto eq_tuples = hana::make_tuple(
+ ::boost::make_tuple(eq<0>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{}, eq<2>{})
+ );
+
+ auto eq_values = hana::make_tuple(eq<0>{}, eq<1>{}, eq<2>{});
+ auto predicates = hana::make_tuple(
+ hana::equal.to(eq<0>{}), hana::equal.to(eq<1>{}), hana::equal.to(eq<2>{}),
+ hana::always(hana::false_c), hana::always(hana::true_c)
+ );
+
+ //////////////////////////////////////////////////////////////////////////
+ // MonadPlus
+ //////////////////////////////////////////////////////////////////////////
+ hana::test::TestMonadPlus<hana::ext::boost::tuple_tag>{eq_tuples, predicates, eq_values};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/orderable.cpp b/src/boost/libs/hana/test/ext/boost/tuple/orderable.cpp
new file mode 100644
index 00000000..661fad13
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/orderable.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/ext/boost/tuple.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+#include <laws/orderable.hpp>
+
+#include <boost/tuple/tuple.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+using eq = hana::test::ct_eq<i>;
+
+template <int i>
+using ord = hana::test::ct_ord<i>;
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // Setup for the laws below
+ //////////////////////////////////////////////////////////////////////////
+ auto eq_tuples = hana::make_tuple(
+ ::boost::make_tuple()
+ , ::boost::make_tuple(eq<0>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{}, eq<2>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}, eq<4>{})
+ );
+
+ auto ord_tuples = hana::make_tuple(
+ ::boost::make_tuple()
+ , ::boost::make_tuple(ord<0>{})
+ , ::boost::make_tuple(ord<0>{}, ord<1>{})
+ , ::boost::make_tuple(ord<0>{}, ord<1>{}, ord<2>{})
+ , ::boost::make_tuple(ord<0>{}, ord<1>{}, ord<2>{}, ord<3>{}, ord<4>{})
+ );
+
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable and Orderable
+ //////////////////////////////////////////////////////////////////////////
+ hana::test::TestComparable<hana::ext::boost::tuple_tag>{eq_tuples};
+ hana::test::TestOrderable<hana::ext::boost::tuple_tag>{ord_tuples};
+}
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/searchable.cpp b/src/boost/libs/hana/test/ext/boost/tuple/searchable.cpp
new file mode 100644
index 00000000..08b4b78d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/searchable.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/ext/boost/tuple.hpp>
+
+#include <boost/hana/bool.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/searchable.hpp>
+
+#include <boost/tuple/tuple.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+using eq = hana::test::ct_eq<i>;
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // Setup for the laws below
+ //////////////////////////////////////////////////////////////////////////
+ auto eq_tuples = hana::make_tuple(
+ ::boost::make_tuple()
+ , ::boost::make_tuple(eq<0>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{})
+ , ::boost::make_tuple(eq<0>{}, eq<1>{}, eq<2>{})
+ );
+
+ auto eq_tuple_keys = hana::make_tuple(
+ eq<3>{}, eq<5>{}, eq<7>{}
+ );
+
+ //////////////////////////////////////////////////////////////////////////
+ // Searchable
+ //////////////////////////////////////////////////////////////////////////
+ {
+ hana::test::TestSearchable<hana::ext::boost::tuple_tag>{eq_tuples, eq_tuple_keys};
+
+ auto bools = hana::make_tuple(
+ ::boost::make_tuple(hana::true_c)
+ , ::boost::make_tuple(hana::false_c)
+ , ::boost::make_tuple(hana::true_c, hana::true_c)
+ , ::boost::make_tuple(hana::true_c, hana::false_c)
+ , ::boost::make_tuple(hana::false_c, hana::true_c)
+ , ::boost::make_tuple(hana::false_c, hana::false_c)
+ );
+ hana::test::TestSearchable<hana::ext::boost::tuple_tag>{
+ bools,
+ hana::make_tuple(hana::true_c, hana::false_c)
+ };
+ }
+}
diff --git a/src/boost/libs/hana/test/ext/boost/tuple/tag_of.cpp b/src/boost/libs/hana/test/ext/boost/tuple/tag_of.cpp
new file mode 100644
index 00000000..831bb8a7
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/boost/tuple/tag_of.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/core/tag_of.hpp>
+#include <boost/hana/ext/boost/tuple.hpp>
+
+#include <boost/tuple/tuple.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // make sure the tag is correct
+ //////////////////////////////////////////////////////////////////////////
+ {
+ auto make_cons = [](auto x, auto xs) {
+ return boost::tuples::cons<decltype(x), decltype(xs)>{x, xs};
+ };
+
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(boost::make_tuple())>,
+ hana::ext::boost::tuple_tag
+ >::value, "");
+
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(boost::make_tuple(1))>,
+ hana::ext::boost::tuple_tag
+ >::value, "");
+
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(boost::make_tuple(1, '2'))>,
+ hana::ext::boost::tuple_tag
+ >::value, "");
+
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(boost::make_tuple(1, '2', 3.3))>,
+ hana::ext::boost::tuple_tag
+ >::value, "");
+
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(make_cons(1, boost::tuples::null_type{}))>,
+ hana::ext::boost::tuple_tag
+ >::value, "");
+
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(make_cons(1, make_cons('2', boost::tuples::null_type{})))>,
+ hana::ext::boost::tuple_tag
+ >::value, "");
+
+ static_assert(std::is_same<
+ hana::tag_of_t<decltype(make_cons(1, boost::make_tuple('2', 3.3)))>,
+ hana::ext::boost::tuple_tag
+ >::value, "");
+
+ static_assert(std::is_same<
+ hana::tag_of_t<boost::tuples::null_type>,
+ hana::ext::boost::tuple_tag
+ >::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/ext/std/array/at.cpp b/src/boost/libs/hana/test/ext/std/array/at.cpp
new file mode 100644
index 00000000..90ed1f5b
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/array/at.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/ext/std/array.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+
+#include <laws/base.hpp> // for move_only
+
+#include <array>
+namespace hana = boost::hana;
+
+
+int main() {
+ // Check non-const lvalue reference
+ {
+ std::array<int, 2> arr = {{999, 888}};
+ int& i = hana::at_c<0>(arr);
+ BOOST_HANA_RUNTIME_CHECK(i == 999);
+ arr[0] = 333;
+ BOOST_HANA_RUNTIME_CHECK(i == 333);
+ i = 444;
+ BOOST_HANA_RUNTIME_CHECK(arr[0] == 444);
+ }
+
+ // Check const lvalue reference
+ {
+ std::array<int, 2> arr = {{999, 888}};
+ int const& i = hana::at_c<0>(static_cast<std::array<int, 2> const&>(arr));
+ BOOST_HANA_RUNTIME_CHECK(i == 999);
+ arr[0] = 333;
+ BOOST_HANA_RUNTIME_CHECK(i == 333);
+ }
+
+ // Check move-only types
+ {
+ std::array<hana::test::move_only, 2> arr{};
+ hana::test::move_only m = hana::at_c<0>(std::move(arr));
+ (void)m;
+ }
+}
diff --git a/src/boost/libs/hana/test/ext/std/array/comparable.cpp b/src/boost/libs/hana/test/ext/std/array/comparable.cpp
new file mode 100644
index 00000000..d0596fa6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/array/comparable.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/ext/std/array.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+
+#include <array>
+namespace hana = boost::hana;
+
+
+template <int ...i>
+constexpr auto array() { return std::array<int, sizeof...(i)>{{i...}}; }
+
+int main() {
+ auto int_arrays = hana::make_tuple(
+ array<>()
+ , array<0>()
+ , array<0, 1>()
+ , array<0, 1, 2>()
+ , array<0, 1, 2, 3>()
+ , array<0, 1, 2, 3, 4>()
+ );
+
+ hana::test::TestComparable<hana::ext::std::array_tag>{int_arrays};
+}
diff --git a/src/boost/libs/hana/test/ext/std/array/foldable.cpp b/src/boost/libs/hana/test/ext/std/array/foldable.cpp
new file mode 100644
index 00000000..b36e9521
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/array/foldable.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/ext/std/array.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/foldable.hpp>
+
+#include <array>
+namespace hana = boost::hana;
+
+
+template <int ...i>
+constexpr auto array() { return std::array<int, sizeof...(i)>{{i...}}; }
+
+int main() {
+ auto int_arrays = hana::make_tuple(
+ array<>()
+ , array<0>()
+ , array<0, 1>()
+ , array<0, 1, 2>()
+ , array<0, 1, 2, 3>()
+ , array<0, 1, 2, 3, 4>()
+ );
+
+ hana::test::TestFoldable<hana::ext::std::array_tag>{int_arrays};
+}
diff --git a/src/boost/libs/hana/test/ext/std/array/issue_304.cpp b/src/boost/libs/hana/test/ext/std/array/issue_304.cpp
new file mode 100644
index 00000000..321f18f2
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/array/issue_304.cpp
@@ -0,0 +1,21 @@
+// Copyright Jason Rice 2016
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+// modified from https://github.com/boostorg/hana/issues/304
+
+#include <boost/hana/ext/std/array.hpp>
+#include <boost/hana/tuple.hpp>
+
+namespace hana = boost::hana;
+
+struct Foo
+{
+ Foo() = default;
+ Foo(Foo const&) = delete;
+ Foo(Foo &&) = default;
+};
+
+using bar = decltype(hana::to_tuple(std::array<Foo, 2>()));
+
+int main()
+{ }
diff --git a/src/boost/libs/hana/test/ext/std/array/iterable.cpp b/src/boost/libs/hana/test/ext/std/array/iterable.cpp
new file mode 100644
index 00000000..38bd7731
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/array/iterable.cpp
@@ -0,0 +1,83 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/assert.hpp>
+#include <boost/hana/drop_front_exactly.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/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/iterable.hpp>
+
+#include <array>
+namespace hana = boost::hana;
+
+
+template <int ...i>
+constexpr auto array() { return std::array<int, sizeof...(i)>{{i...}}; }
+
+int main() {
+ // is_empty
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(array<>()));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(array<0>())));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(array<0, 1>())));
+ }
+
+ // front
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::front(array<0>()) == 0);
+ BOOST_HANA_CONSTEXPR_CHECK(hana::front(array<0, 1>()) == 0);
+ BOOST_HANA_CONSTEXPR_CHECK(hana::front(array<0, 1, 2>()) == 0);
+ }
+
+ // drop_front_exactly
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(array<0>()),
+ array<>()
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::drop_front_exactly(array<0, 1>()),
+ array<1>()
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::drop_front_exactly(array<0, 1, 2>()),
+ array<1, 2>()
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::drop_front_exactly(array<0, 1, 2, 3>()),
+ array<1, 2, 3>()
+ ));
+
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::drop_front_exactly(array<0, 1, 2, 3>(), hana::size_c<2>),
+ array<2, 3>()
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::drop_front_exactly(array<0, 1, 2, 3>(), hana::size_c<3>),
+ array<3>()
+ ));
+ }
+
+ // laws
+ auto int_arrays = hana::make_tuple(
+ array<>()
+ , array<0>()
+ , array<0, 1>()
+ , array<0, 1, 2>()
+ , array<0, 1, 2, 3>()
+ , array<0, 1, 2, 3, 4>()
+ );
+
+ hana::test::TestIterable<hana::ext::std::array_tag>{int_arrays};
+}
diff --git a/src/boost/libs/hana/test/ext/std/array/orderable.cpp b/src/boost/libs/hana/test/ext/std/array/orderable.cpp
new file mode 100644
index 00000000..ced9ab6b
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/array/orderable.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/ext/std/array.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/orderable.hpp>
+
+#include <array>
+namespace hana = boost::hana;
+
+
+template <int ...i>
+constexpr auto array() { return std::array<int, sizeof...(i)>{{i...}}; }
+
+int main() {
+ auto int_arrays = hana::make_tuple(
+ array<>()
+ , array<0>()
+ , array<0, 1>()
+ , array<0, 1, 2>()
+ , array<0, 1, 2, 3>()
+ , array<0, 1, 2, 3, 4>()
+ );
+
+ hana::test::TestOrderable<hana::ext::std::array_tag>{int_arrays};
+}
diff --git a/src/boost/libs/hana/test/ext/std/array/searchable.cpp b/src/boost/libs/hana/test/ext/std/array/searchable.cpp
new file mode 100644
index 00000000..1ba584fd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/array/searchable.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/ext/std/array.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/searchable.hpp>
+
+#include <array>
+namespace hana = boost::hana;
+
+
+template <int ...i>
+constexpr auto array() { return std::array<int, sizeof...(i)>{{i...}}; }
+
+int main() {
+ auto eq_arrays = hana::make_tuple(
+ std::array<hana::test::ct_eq<0>, 0>{}
+ , std::array<hana::test::ct_eq<0>, 1>{}
+ , std::array<hana::test::ct_eq<0>, 2>{}
+ , std::array<hana::test::ct_eq<0>, 3>{}
+ , std::array<hana::test::ct_eq<0>, 4>{}
+ );
+
+ auto eq_keys = hana::make_tuple(hana::test::ct_eq<0>{});
+
+ hana::test::TestSearchable<hana::ext::std::array_tag>{eq_arrays, eq_keys};
+}
diff --git a/src/boost/libs/hana/test/ext/std/bugs/libcxx_19616.cpp b/src/boost/libs/hana/test/ext/std/bugs/libcxx_19616.cpp
new file mode 100644
index 00000000..2b91f88a
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/bugs/libcxx_19616.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/ext/std/tuple.hpp>
+#include <boost/hana/lift.hpp>
+
+#include <tuple>
+namespace hana = boost::hana;
+
+
+int main() {
+ // Make sure we workaround the bug at:
+ // http://llvm.org/bugs/show_bug.cgi?id=19616
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::lift<hana::ext::std::tuple_tag>(std::make_tuple(1)),
+ std::make_tuple(std::make_tuple(1))
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/bugs/libcxx_22806.cpp b/src/boost/libs/hana/test/ext/std/bugs/libcxx_22806.cpp
new file mode 100644
index 00000000..28148108
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/bugs/libcxx_22806.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/chain.hpp>
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/lift.hpp>
+
+#include <laws/base.hpp>
+
+#include <tuple>
+namespace hana = boost::hana;
+
+
+int main() {
+ using M = hana::ext::std::tuple_tag;
+ auto m = std::make_tuple(hana::test::ct_eq<0>{});
+ auto f = hana::compose(hana::lift<M>, hana::test::_injection<0>{});
+ hana::chain(m, hana::compose(hana::lift<M>, f));
+}
diff --git a/src/boost/libs/hana/test/ext/std/integer_sequence/drop_front_exactly.cpp b/src/boost/libs/hana/test/ext/std/integer_sequence/drop_front_exactly.cpp
new file mode 100644
index 00000000..a9556ccb
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integer_sequence/drop_front_exactly.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/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(std::index_sequence<0>{}),
+ std::index_sequence<>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(std::index_sequence<0, 1>{}),
+ std::index_sequence<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(std::index_sequence<0, 1, 2>{}),
+ std::index_sequence<1, 2>{}
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(std::index_sequence<0, 1, 2>{}, hana::size_c<2>),
+ std::index_sequence<2>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(std::index_sequence<0, 1, 2, 3>{}, hana::size_c<2>),
+ std::index_sequence<2, 3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(std::index_sequence<0, 1, 2, 3>{}, hana::size_c<3>),
+ std::index_sequence<3>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/integer_sequence/equal.cpp b/src/boost/libs/hana/test/ext/std/integer_sequence/equal.cpp
new file mode 100644
index 00000000..7249d234
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integer_sequence/equal.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/integer_sequence.hpp>
+#include <boost/hana/not.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+using T = int;
+using U = long long;
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ std::integer_sequence<T>{},
+ std::integer_sequence<U>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ std::integer_sequence<T, 0>{},
+ std::integer_sequence<U>{}
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ std::integer_sequence<T>{},
+ std::integer_sequence<U, 0>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ std::integer_sequence<T, 0>{},
+ std::integer_sequence<U, 0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ std::integer_sequence<T, 0>{},
+ std::integer_sequence<U, 0, 1>{}
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ std::integer_sequence<T, 0, 2>{},
+ std::integer_sequence<U, 0, 1>{}
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ std::integer_sequence<T, 0, 1, 2, 3>{},
+ std::integer_sequence<U, 0, 1, 2, 3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ std::integer_sequence<T, 0, 1, 2, 3, 5>{},
+ std::integer_sequence<U, 0, 1, 2, 3>{}
+ )));
+}
diff --git a/src/boost/libs/hana/test/ext/std/integer_sequence/find_if.cpp b/src/boost/libs/hana/test/ext/std/integer_sequence/find_if.cpp
new file mode 100644
index 00000000..4c904ed6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integer_sequence/find_if.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/equal.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <cstddef>
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct undefined { };
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<>{},
+ hana::equal.to(undefined{})),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0>{},
+ hana::equal.to(std::integral_constant<std::size_t, 0>{})),
+ hana::just(std::integral_constant<std::size_t, 0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0>{},
+ hana::equal.to(std::integral_constant<std::size_t, 1>{})),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1>{},
+ hana::equal.to(std::integral_constant<std::size_t, 0>{})),
+ hana::just(std::integral_constant<std::size_t, 0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1>{},
+ hana::equal.to(std::integral_constant<std::size_t, 1>{})),
+ hana::just(std::integral_constant<std::size_t, 1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1>{},
+ hana::equal.to(std::integral_constant<std::size_t, 2>{})),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1, 2>{},
+ hana::equal.to(std::integral_constant<std::size_t, 0>{})),
+ hana::just(std::integral_constant<std::size_t, 0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1, 2>{},
+ hana::equal.to(std::integral_constant<std::size_t, 1>{})),
+ hana::just(std::integral_constant<std::size_t, 1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1, 2>{},
+ hana::equal.to(std::integral_constant<std::size_t, 2>{})),
+ hana::just(std::integral_constant<std::size_t, 2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1, 2>{},
+ hana::equal.to(std::integral_constant<std::size_t, 3>{})),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1, 2, 3>{},
+ hana::equal.to(std::integral_constant<std::size_t, 0>{})),
+ hana::just(std::integral_constant<std::size_t, 0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1, 2, 3>{},
+ hana::equal.to(std::integral_constant<std::size_t, 1>{})),
+ hana::just(std::integral_constant<std::size_t, 1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1, 2, 3>{},
+ hana::equal.to(std::integral_constant<std::size_t, 2>{})),
+ hana::just(std::integral_constant<std::size_t, 2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1, 2, 3>{},
+ hana::equal.to(std::integral_constant<std::size_t, 3>{})),
+ hana::just(std::integral_constant<std::size_t, 3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(std::index_sequence<0, 1, 2, 3>{},
+ hana::equal.to(std::integral_constant<std::size_t, 4>{})),
+ hana::nothing
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/integer_sequence/front.cpp b/src/boost/libs/hana/test/ext/std/integer_sequence/front.cpp
new file mode 100644
index 00000000..69372c99
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integer_sequence/front.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/std/integer_sequence.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/front.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(std::index_sequence<0>{}),
+ std::integral_constant<std::size_t, 0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(std::index_sequence<0, 1>{}),
+ std::integral_constant<std::size_t, 0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(std::integer_sequence<int, -3, 1, 2, 3, 4>{}),
+ std::integral_constant<int, -3>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/integer_sequence/is_empty.cpp b/src/boost/libs/hana/test/ext/std/integer_sequence/is_empty.cpp
new file mode 100644
index 00000000..b6c79c75
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integer_sequence/is_empty.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/integer_sequence.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(std::index_sequence<>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(std::index_sequence<0>{})));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(std::index_sequence<1>{})));
+}
diff --git a/src/boost/libs/hana/test/ext/std/integer_sequence/laws.cpp b/src/boost/libs/hana/test/ext/std/integer_sequence/laws.cpp
new file mode 100644
index 00000000..8cc7fcc4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integer_sequence/laws.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/ext/std/integer_sequence.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/iterable.hpp>
+#include <laws/searchable.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+auto sequences = hana::make_tuple(
+ std::integer_sequence<int>{},
+ std::integer_sequence<int, 2>{},
+ std::integer_sequence<int, 3>{},
+ std::integer_sequence<int, 3, 4>{},
+ std::integer_sequence<int, 3, 4, 5>{}
+);
+
+auto keys = hana::make_tuple(
+ std::integral_constant<int, 3>{}, std::integral_constant<long long, 4>{}
+);
+
+int main() {
+ hana::test::TestComparable<hana::ext::std::integer_sequence_tag>{sequences};
+ hana::test::TestFoldable<hana::ext::std::integer_sequence_tag>{sequences};
+ hana::test::TestIterable<hana::ext::std::integer_sequence_tag>{sequences};
+ hana::test::TestSearchable<hana::ext::std::integer_sequence_tag>{sequences, keys};
+}
diff --git a/src/boost/libs/hana/test/ext/std/integer_sequence/unpack.cpp b/src/boost/libs/hana/test/ext/std/integer_sequence/unpack.cpp
new file mode 100644
index 00000000..5ef9320c
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integer_sequence/unpack.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/ext/std/integer_sequence.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(std::integer_sequence<int>{}, f),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(std::integer_sequence<int, 0>{}, f),
+ f(std::integral_constant<int, 0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(std::integer_sequence<int, 0, 1>{}, f),
+ f(std::integral_constant<int, 0>{}, std::integral_constant<int, 1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(std::integer_sequence<int, 0, 1, 2>{}, f),
+ f(std::integral_constant<int, 0>{}, std::integral_constant<int, 1>{},
+ std::integral_constant<int, 2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(std::integer_sequence<int, 0, 1, 2, 3>{}, f),
+ f(std::integral_constant<int, 0>{}, std::integral_constant<int, 1>{},
+ std::integral_constant<int, 2>{}, std::integral_constant<int, 3>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/integral_constant/arithmetic.cpp b/src/boost/libs/hana/test/ext/std/integral_constant/arithmetic.cpp
new file mode 100644
index 00000000..25372ddd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integral_constant/arithmetic.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/ext/std/integral_constant.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/euclidean_ring.hpp>
+#include <laws/group.hpp>
+#include <laws/monoid.hpp>
+#include <laws/ring.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto ints = hana::make_tuple(
+ std::integral_constant<int, -10>{},
+ std::integral_constant<int, -2>{},
+ std::integral_constant<int, 0>{},
+ std::integral_constant<int, 1>{},
+ std::integral_constant<int, 3>{}
+ );
+
+ hana::test::TestMonoid<hana::ext::std::integral_constant_tag<int>>{ints};
+ hana::test::TestGroup<hana::ext::std::integral_constant_tag<int>>{ints};
+ hana::test::TestRing<hana::ext::std::integral_constant_tag<int>>{ints};
+ hana::test::TestEuclideanRing<hana::ext::std::integral_constant_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/ext/std/integral_constant/comparable.cpp b/src/boost/libs/hana/test/ext/std/integral_constant/comparable.cpp
new file mode 100644
index 00000000..d17b6d81
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integral_constant/comparable.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/ext/std/integral_constant.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+#include <laws/hashable.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto ints = hana::make_tuple(
+ std::integral_constant<int, -10>{},
+ std::integral_constant<int, -2>{},
+ std::integral_constant<int, 0>{},
+ std::integral_constant<int, 1>{},
+ std::integral_constant<int, 3>{}
+ );
+
+ hana::test::TestComparable<hana::ext::std::integral_constant_tag<int>>{ints};
+ hana::test::TestHashable<hana::ext::std::integral_constant_tag<void>>{ints};
+}
diff --git a/src/boost/libs/hana/test/ext/std/integral_constant/constant.cpp b/src/boost/libs/hana/test/ext/std/integral_constant/constant.cpp
new file mode 100644
index 00000000..f15fb8e8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integral_constant/constant.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/ext/std/integral_constant.hpp>
+
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/value.hpp>
+
+#include <laws/constant.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ // value
+ static_assert(hana::value(std::integral_constant<int, 0>{}) == 0, "");
+ static_assert(hana::value(std::integral_constant<int, 1>{}) == 1, "");
+ static_assert(hana::value(std::integral_constant<int, 3>{}) == 3, "");
+
+ // laws
+ hana::test::TestConstant<hana::ext::std::integral_constant_tag<int>>{
+ hana::make_tuple(
+ std::integral_constant<int, -10>{},
+ std::integral_constant<int, -2>{},
+ std::integral_constant<int, 0>{},
+ std::integral_constant<int, 1>{},
+ std::integral_constant<int, 3>{}
+ ),
+ hana::tuple_t<int, long, long long>
+ };
+}
diff --git a/src/boost/libs/hana/test/ext/std/integral_constant/interop.cpp b/src/boost/libs/hana/test/ext/std/integral_constant/interop.cpp
new file mode 100644
index 00000000..9b445f01
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integral_constant/interop.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/ext/std/integral_constant.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ // Interoperation with hana::integral_constant
+ BOOST_HANA_CONSTANT_CHECK(std::integral_constant<int, 1>{} == hana::int_c<1>);
+ BOOST_HANA_CONSTANT_CHECK(std::integral_constant<int, 1>{} == hana::long_c<1>);
+
+ BOOST_HANA_CONSTANT_CHECK(std::integral_constant<int, 2>{} != hana::int_c<3>);
+}
diff --git a/src/boost/libs/hana/test/ext/std/integral_constant/logical.cpp b/src/boost/libs/hana/test/ext/std/integral_constant/logical.cpp
new file mode 100644
index 00000000..38d8091c
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integral_constant/logical.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/ext/std/integral_constant.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/logical.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ // eval_if
+ {
+ auto t = hana::test::ct_eq<3>{};
+ auto e = hana::test::ct_eq<4>{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval_if(std::true_type{}, hana::always(t), hana::always(e)),
+ t
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval_if(std::false_type{}, hana::always(t), hana::always(e)),
+ e
+ ));
+ }
+
+ // not_
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::not_(std::true_type{}),
+ std::false_type{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::not_(std::false_type{}),
+ std::true_type{}
+ ));
+ }
+
+ auto ints = hana::make_tuple(
+ std::integral_constant<int, -2>{},
+ std::integral_constant<int, 0>{},
+ std::integral_constant<int, 1>{},
+ std::integral_constant<int, 3>{}
+ );
+
+ auto bools = hana::make_tuple(std::true_type{}, std::false_type{});
+
+ // laws
+ hana::test::TestLogical<hana::ext::std::integral_constant_tag<int>>{ints};
+ hana::test::TestLogical<hana::ext::std::integral_constant_tag<bool>>{bools};
+}
diff --git a/src/boost/libs/hana/test/ext/std/integral_constant/orderable.cpp b/src/boost/libs/hana/test/ext/std/integral_constant/orderable.cpp
new file mode 100644
index 00000000..6a14ad14
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integral_constant/orderable.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/ext/std/integral_constant.hpp>
+
+#include <boost/hana/tuple.hpp>
+
+#include <laws/orderable.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto ints = hana::make_tuple(
+ std::integral_constant<int, -10>{},
+ std::integral_constant<int, -2>{},
+ std::integral_constant<int, 0>{},
+ std::integral_constant<int, 1>{},
+ std::integral_constant<int, 3>{}
+ );
+
+ hana::test::TestOrderable<hana::ext::std::integral_constant_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/ext/std/integral_constant/tag.cpp b/src/boost/libs/hana/test/ext/std/integral_constant/tag.cpp
new file mode 100644
index 00000000..8a747e44
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/integral_constant/tag.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/ext/std/integral_constant.hpp>
+
+#include <boost/hana/core/tag_of.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct inherit_simple : std::integral_constant<int, 3> { };
+struct inherit_no_default : std::integral_constant<int, 3> {
+ inherit_no_default() = delete;
+};
+
+struct incomplete;
+struct empty_type { };
+struct non_pod { virtual ~non_pod() { } };
+
+
+static_assert(std::is_same<
+ hana::tag_of_t<inherit_simple>,
+ hana::ext::std::integral_constant_tag<int>
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<inherit_no_default>,
+ hana::ext::std::integral_constant_tag<int>
+>{}, "");
+static_assert(std::is_same<
+ hana::tag_of_t<std::is_pointer<int*>>,
+ hana::ext::std::integral_constant_tag<bool>
+>{}, "");
+
+static_assert(!std::is_same<
+ hana::tag_of_t<incomplete>,
+ hana::ext::std::integral_constant_tag<int>
+>{}, "");
+static_assert(!std::is_same<
+ hana::tag_of_t<empty_type>,
+ hana::ext::std::integral_constant_tag<int>
+>{}, "");
+static_assert(!std::is_same<
+ hana::tag_of_t<non_pod>,
+ hana::ext::std::integral_constant_tag<int>
+>{}, "");
+static_assert(!std::is_same<
+ hana::tag_of_t<void>,
+ hana::ext::std::integral_constant_tag<int>
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/pair/first_second.cpp b/src/boost/libs/hana/test/ext/std/pair/first_second.cpp
new file mode 100644
index 00000000..a44ed1cc
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/pair/first_second.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/std/pair.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/second.hpp>
+
+#include <laws/base.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ // first
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::first(std::make_pair(ct_eq<0>{}, ct_eq<1>{})),
+ ct_eq<0>{}
+ ));
+
+ // second
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::second(std::make_pair(ct_eq<0>{}, ct_eq<1>{})),
+ ct_eq<1>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/pair/issue_90.cpp b/src/boost/libs/hana/test/ext/std/pair/issue_90.cpp
new file mode 100644
index 00000000..d8f70c56
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/pair/issue_90.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/ext/std/pair.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/second.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <typename T>
+T const& cref(T& t) { return t; }
+
+// a non-movable, non-copyable type
+template <int i>
+struct RefOnly {
+ RefOnly() = default;
+ RefOnly(RefOnly const&) = delete;
+ RefOnly(RefOnly&&) = delete;
+};
+
+int main() {
+ // This test makes sure that we return the proper reference types from
+ // `first` and `second`.
+ std::pair<RefOnly<0>, RefOnly<1>> p;
+
+ {
+ RefOnly<0>&& r1 = hana::first(std::move(p));
+ RefOnly<0>& r2 = hana::first(p);
+ RefOnly<0> const& r3 = hana::first(cref(p));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ {
+ RefOnly<1>&& r1 = hana::second(std::move(p));
+ RefOnly<1>& r2 = hana::second(p);
+ RefOnly<1> const& r3 = hana::second(cref(p));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+}
diff --git a/src/boost/libs/hana/test/ext/std/pair/laws.cpp b/src/boost/libs/hana/test/ext/std/pair/laws.cpp
new file mode 100644
index 00000000..869001ab
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/pair/laws.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/ext/std/pair.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/orderable.hpp>
+#include <laws/product.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+using hana::test::ct_ord;
+
+
+int main() {
+ auto eq_elems = hana::make_tuple(ct_eq<3>{}, ct_eq<4>{});
+
+ auto eqs = hana::make_tuple(
+ std::make_pair(ct_eq<3>{}, ct_eq<3>{})
+ , std::make_pair(ct_eq<3>{}, ct_eq<4>{})
+ , std::make_pair(ct_eq<4>{}, ct_eq<3>{})
+ , std::make_pair(ct_eq<4>{}, ct_eq<4>{})
+ );
+
+ auto ords = hana::make_tuple(
+ std::make_pair(ct_ord<3>{}, ct_ord<3>{})
+ , std::make_pair(ct_ord<3>{}, ct_ord<4>{})
+ , std::make_pair(ct_ord<4>{}, ct_ord<3>{})
+ , std::make_pair(ct_ord<4>{}, ct_ord<4>{})
+ );
+
+ hana::test::TestComparable<hana::ext::std::pair_tag>{eqs};
+ hana::test::TestOrderable<hana::ext::std::pair_tag>{ords};
+ hana::test::TestFoldable<hana::ext::std::pair_tag>{eqs};
+ hana::test::TestProduct<hana::ext::std::pair_tag>{eq_elems};
+}
diff --git a/src/boost/libs/hana/test/ext/std/pair/make.cpp b/src/boost/libs/hana/test/ext/std/pair/make.cpp
new file mode 100644
index 00000000..f0cb9d29
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/pair/make.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/ext/std/pair.hpp>
+
+#include <laws/base.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::ext::std::pair_tag>(ct_eq<0>{}, ct_eq<1>{}),
+ std::make_pair(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::ext::std::pair_tag>(ct_eq<3>{}, ct_eq<4>{}),
+ std::make_pair(ct_eq<3>{}, ct_eq<4>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/div.cpp b/src/boost/libs/hana/test/ext/std/ratio/div.cpp
new file mode 100644
index 00000000..327717fc
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/div.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/div.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/ratio.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::div(std::ratio<6>{}, std::ratio<4>{}),
+ std::ratio<6, 4>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::div(std::ratio<3, 4>{}, std::ratio<5, 10>{}),
+ std::ratio<3*10, 4*5>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/equal.cpp b/src/boost/libs/hana/test/ext/std/ratio/equal.cpp
new file mode 100644
index 00000000..f72ec898
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/equal.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/equal.hpp>
+#include <boost/hana/ext/std/ratio.hpp>
+#include <boost/hana/not.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ std::ratio<0>{},
+ std::ratio<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ std::ratio<3>{},
+ std::ratio<3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ std::ratio<3, 5>{},
+ std::ratio<6, 10>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ std::ratio<4, 5>{},
+ std::ratio<6, 10>{}
+ )));
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/laws.cpp b/src/boost/libs/hana/test/ext/std/ratio/laws.cpp
new file mode 100644
index 00000000..460fe3c8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/laws.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/ext/std/ratio.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+#include <laws/euclidean_ring.hpp>
+#include <laws/group.hpp>
+#include <laws/monoid.hpp>
+#include <laws/orderable.hpp>
+#include <laws/ring.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto ratios = hana::make_tuple(
+ std::ratio<0>{}
+ , std::ratio<1, 3>{}
+ , std::ratio<1, 2>{}
+ , std::ratio<2, 6>{}
+ , std::ratio<3, 1>{}
+ , std::ratio<7, 8>{}
+ , std::ratio<3, 5>{}
+ , std::ratio<2, 1>{}
+ );
+
+ hana::test::TestComparable<hana::ext::std::ratio_tag>{ratios};
+ hana::test::TestOrderable<hana::ext::std::ratio_tag>{ratios};
+ hana::test::TestMonoid<hana::ext::std::ratio_tag>{ratios};
+ hana::test::TestGroup<hana::ext::std::ratio_tag>{ratios};
+ hana::test::TestRing<hana::ext::std::ratio_tag>{ratios};
+ hana::test::TestEuclideanRing<hana::ext::std::ratio_tag>{ratios};
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/less.cpp b/src/boost/libs/hana/test/ext/std/ratio/less.cpp
new file mode 100644
index 00000000..79e8dbc4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/less.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/ext/std/ratio.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/not.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ std::ratio<1>{},
+ std::ratio<3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ std::ratio<4, 10>{},
+ std::ratio<3, 5>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ std::ratio<3, 5>{},
+ std::ratio<4, 10>{}
+ )));
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/minus.cpp b/src/boost/libs/hana/test/ext/std/ratio/minus.cpp
new file mode 100644
index 00000000..9a6bc419
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/minus.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/ext/std/ratio.hpp>
+#include <boost/hana/minus.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::minus(std::ratio<3, 4>{}, std::ratio<5, 10>{}),
+ std::ratio<3*10 - 5*4, 4*10>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/mod.cpp b/src/boost/libs/hana/test/ext/std/ratio/mod.cpp
new file mode 100644
index 00000000..24c748eb
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/mod.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/ratio.hpp>
+#include <boost/hana/mod.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::mod(std::ratio<6>{}, std::ratio<4>{}),
+ std::ratio<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::mod(std::ratio<3, 4>{}, std::ratio<5, 10>{}),
+ std::ratio<0>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/mult.cpp b/src/boost/libs/hana/test/ext/std/ratio/mult.cpp
new file mode 100644
index 00000000..5f345bf2
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/mult.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/ext/std/ratio.hpp>
+#include <boost/hana/mult.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::mult(std::ratio<3, 4>{}, std::ratio<5, 10>{}),
+ std::ratio<3*5, 4*10>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/one.cpp b/src/boost/libs/hana/test/ext/std/ratio/one.cpp
new file mode 100644
index 00000000..a05ac1be
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/one.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/ratio.hpp>
+#include <boost/hana/one.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::one<hana::ext::std::ratio_tag>(),
+ std::ratio<1, 1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::one<hana::ext::std::ratio_tag>(),
+ std::ratio<2, 2>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/plus.cpp b/src/boost/libs/hana/test/ext/std/ratio/plus.cpp
new file mode 100644
index 00000000..33a47bd9
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/plus.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/ext/std/ratio.hpp>
+#include <boost/hana/plus.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::plus(std::ratio<3, 4>{}, std::ratio<5, 10>{}),
+ std::ratio<3*10 + 5*4, 4*10>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/to.cpp b/src/boost/libs/hana/test/ext/std/ratio/to.cpp
new file mode 100644
index 00000000..2795c990
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/to.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/equal.hpp>
+#include <boost/hana/ext/std/ratio.hpp>
+
+#include <laws/base.hpp>
+#include <support/cnumeric.hpp>
+
+#include <ratio>
+#include <utility>
+namespace hana = boost::hana;
+
+
+int main() {
+ // Conversion from a Constant to a std::ratio
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::ext::std::ratio_tag>(cnumeric<int, 0>),
+ std::ratio<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::ext::std::ratio_tag>(cnumeric<int, 1>),
+ std::ratio<1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::ext::std::ratio_tag>(cnumeric<int, 3>),
+ std::ratio<3>{}
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/ext/std/ratio/zero.cpp b/src/boost/libs/hana/test/ext/std/ratio/zero.cpp
new file mode 100644
index 00000000..af0fa171
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/ratio/zero.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/ratio.hpp>
+#include <boost/hana/zero.hpp>
+
+#include <ratio>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zero<hana::ext::std::ratio_tag>(),
+ std::ratio<0, 1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zero<hana::ext::std::ratio_tag>(),
+ std::ratio<0, 2>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/_specs.hpp b/src/boost/libs/hana/test/ext/std/tuple/auto/_specs.hpp
new file mode 100644
index 00000000..c165d421
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/_specs.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_EXT_STD_TUPLE_AUTO_SPECS_HPP
+#define BOOST_HANA_TEST_EXT_STD_TUPLE_AUTO_SPECS_HPP
+
+#include <boost/hana/ext/std/tuple.hpp>
+
+#include <tuple>
+
+
+#define MAKE_TUPLE(...) ::std::make_tuple(__VA_ARGS__)
+#define TUPLE_TYPE(...) ::std::tuple<__VA_ARGS__>
+#define TUPLE_TAG ::boost::hana::ext::std::tuple_tag
+
+#endif // !BOOST_HANA_TEST_EXT_STD_TUPLE_AUTO_SPECS_HPP
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/all_of.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/all_of.cpp
new file mode 100644
index 00000000..f3e974ff
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/all_of.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 "_specs.hpp"
+#include <auto/all_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/any_of.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/any_of.cpp
new file mode 100644
index 00000000..3065d017
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/any_of.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 "_specs.hpp"
+#include <auto/any_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/ap.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/ap.cpp
new file mode 100644
index 00000000..59c9cb75
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/ap.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 "_specs.hpp"
+#include <auto/ap.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/at.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/at.cpp
new file mode 100644
index 00000000..60526533
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/at.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 "_specs.hpp"
+#include <auto/at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/cartesian_product.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/cartesian_product.cpp
new file mode 100644
index 00000000..b0795e8d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/cartesian_product.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 "_specs.hpp"
+#include <auto/cartesian_product.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/drop_back.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/drop_back.cpp
new file mode 100644
index 00000000..b283844d
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/drop_back.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 "_specs.hpp"
+#include <auto/drop_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/drop_front.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/drop_front.cpp
new file mode 100644
index 00000000..a39d6f45
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/drop_front.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 "_specs.hpp"
+#include <auto/drop_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/drop_while.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/drop_while.cpp
new file mode 100644
index 00000000..18907f03
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/drop_while.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 "_specs.hpp"
+#include <auto/drop_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/for_each.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/for_each.cpp
new file mode 100644
index 00000000..714fe03c
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/for_each.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 "_specs.hpp"
+#include <auto/for_each.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/group.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/group.cpp
new file mode 100644
index 00000000..0669b496
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/group.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 "_specs.hpp"
+#include <auto/group.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/index_if.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/index_if.cpp
new file mode 100644
index 00000000..ef37fe65
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/index_if.cpp
@@ -0,0 +1,9 @@
+// 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 "_specs.hpp"
+#include <auto/index_if.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/insert.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/insert.cpp
new file mode 100644
index 00000000..e8efc6dc
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/insert.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 "_specs.hpp"
+#include <auto/insert.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/insert_range.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/insert_range.cpp
new file mode 100644
index 00000000..05ac5774
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/insert_range.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 "_specs.hpp"
+#include <auto/insert_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/intersperse.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/intersperse.cpp
new file mode 100644
index 00000000..185c814a
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/intersperse.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 "_specs.hpp"
+#include <auto/intersperse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/is_empty.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/is_empty.cpp
new file mode 100644
index 00000000..f175f7dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/is_empty.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 "_specs.hpp"
+#include <auto/is_empty.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/length.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/length.cpp
new file mode 100644
index 00000000..55111dd6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/length.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 "_specs.hpp"
+#include <auto/length.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/lexicographical_compare.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/lexicographical_compare.cpp
new file mode 100644
index 00000000..4d2f3edf
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/lexicographical_compare.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 "_specs.hpp"
+#include <auto/lexicographical_compare.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/make.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/make.cpp
new file mode 100644
index 00000000..f90514f1
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/make.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 "_specs.hpp"
+#include <auto/make.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/none_of.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/none_of.cpp
new file mode 100644
index 00000000..b56a27b4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/none_of.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 "_specs.hpp"
+#include <auto/none_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/partition.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/partition.cpp
new file mode 100644
index 00000000..ba9621a6
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/partition.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 "_specs.hpp"
+#include <auto/partition.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/permutations.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/permutations.cpp
new file mode 100644
index 00000000..3c1a6e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/permutations.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 "_specs.hpp"
+#include <auto/permutations.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/remove_at.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/remove_at.cpp
new file mode 100644
index 00000000..5b7c5af4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/remove_at.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 "_specs.hpp"
+#include <auto/remove_at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/remove_range.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/remove_range.cpp
new file mode 100644
index 00000000..6d7c6e09
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/remove_range.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 "_specs.hpp"
+#include <auto/remove_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/reverse.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/reverse.cpp
new file mode 100644
index 00000000..342278df
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/reverse.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 "_specs.hpp"
+#include <auto/reverse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/scans.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/scans.cpp
new file mode 100644
index 00000000..36dd3243
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/scans.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 "_specs.hpp"
+#include <auto/scans.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/sequence.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/sequence.cpp
new file mode 100644
index 00000000..4ed01e85
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/sequence.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 "_specs.hpp"
+#include <auto/sequence.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/slice.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/slice.cpp
new file mode 100644
index 00000000..3e20df95
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/slice.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 "_specs.hpp"
+#include <auto/slice.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/sort.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/sort.cpp
new file mode 100644
index 00000000..f639ddeb
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/sort.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 "_specs.hpp"
+#include <auto/sort.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/span.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/span.cpp
new file mode 100644
index 00000000..297b7f17
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/span.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 "_specs.hpp"
+#include <auto/span.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/take_back.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/take_back.cpp
new file mode 100644
index 00000000..2a91d7d4
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/take_back.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 "_specs.hpp"
+#include <auto/take_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/take_front.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/take_front.cpp
new file mode 100644
index 00000000..9a48d2b8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/take_front.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 "_specs.hpp"
+#include <auto/take_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/take_while.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/take_while.cpp
new file mode 100644
index 00000000..e58c99ac
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/take_while.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 "_specs.hpp"
+#include <auto/take_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/transform.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/transform.cpp
new file mode 100644
index 00000000..306c1bc3
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/transform.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 "_specs.hpp"
+#include <auto/transform.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/unfolds.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/unfolds.cpp
new file mode 100644
index 00000000..f8bac9dd
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/unfolds.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 "_specs.hpp"
+#include <auto/unfolds.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/unique.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/unique.cpp
new file mode 100644
index 00000000..9c1dc715
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/unique.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 "_specs.hpp"
+#include <auto/unique.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/auto/zips.cpp b/src/boost/libs/hana/test/ext/std/tuple/auto/zips.cpp
new file mode 100644
index 00000000..32ec5cc8
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/auto/zips.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 "_specs.hpp"
+#include <auto/zips.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/ext/std/tuple/issue_90.cpp b/src/boost/libs/hana/test/ext/std/tuple/issue_90.cpp
new file mode 100644
index 00000000..dfbb4a7f
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/issue_90.cpp
@@ -0,0 +1,73 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/at_key.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <tuple>
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <typename T>
+T const& cref(T& t) { return t; }
+
+// a non-movable, non-copyable type
+struct RefOnly {
+ RefOnly() = default;
+ RefOnly(RefOnly const&) = delete;
+ RefOnly(RefOnly&&) = delete;
+};
+
+template <int i>
+struct RefOnly_i : hana::int_<i> {
+ RefOnly_i() = default;
+ RefOnly_i(RefOnly_i const&) = delete;
+ RefOnly_i(RefOnly_i&&) = delete;
+};
+
+int main() {
+ std::tuple<RefOnly> t;
+
+ // Make sure that we return the proper reference types from `at`.
+ {
+ RefOnly&& r1 = hana::at_c<0>(std::move(t));
+ RefOnly& r2 = hana::at_c<0>(t);
+ RefOnly const& r3 = hana::at_c<0>(cref(t));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ // Make sure we return the proper reference types from `front`.
+ {
+ RefOnly&& r1 = hana::front(std::move(t));
+ RefOnly& r2 = hana::front(t);
+ RefOnly const& r3 = hana::front(cref(t));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ // Make sure we return the proper reference types from `back`.
+ {
+ RefOnly&& r1 = hana::back(std::move(t));
+ RefOnly& r2 = hana::back(t);
+ RefOnly const& r3 = hana::back(cref(t));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ // Make sure we return the proper reference types from `at_key`.
+ {
+ std::tuple<RefOnly_i<3>> t{};
+ RefOnly_i<3>& r1 = hana::at_key(t, RefOnly_i<3>{});
+ RefOnly_i<3> const& r2 = hana::at_key(cref(t), RefOnly_i<3>{});
+ RefOnly_i<3>&& r3 = hana::at_key(std::move(t), RefOnly_i<3>{});
+
+ (void)r1; (void)r2; (void)r3;
+ }
+}
diff --git a/src/boost/libs/hana/test/ext/std/tuple/laws.cpp b/src/boost/libs/hana/test/ext/std/tuple/laws.cpp
new file mode 100644
index 00000000..4c56bc8e
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/laws.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/ext/std/tuple.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/iterable.hpp>
+#include <laws/orderable.hpp>
+#include <laws/sequence.hpp>
+
+#include <tuple>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+using hana::test::ct_ord;
+
+
+int main() {
+ auto eq_tuples = hana::make_tuple(
+ std::make_tuple()
+ , std::make_tuple(ct_eq<0>{})
+ , std::make_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , std::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , std::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ );
+
+ auto ord_tuples = hana::make_tuple(
+ std::make_tuple()
+ , std::make_tuple(ct_ord<0>{})
+ , std::make_tuple(ct_ord<0>{}, ct_ord<1>{})
+ , std::make_tuple(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{})
+ , std::make_tuple(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, ct_ord<3>{}, ct_ord<4>{})
+ );
+
+ hana::test::TestComparable<hana::ext::std::tuple_tag>{eq_tuples};
+ hana::test::TestOrderable<hana::ext::std::tuple_tag>{ord_tuples};
+ hana::test::TestFoldable<hana::ext::std::tuple_tag>{eq_tuples};
+ hana::test::TestIterable<hana::ext::std::tuple_tag>{eq_tuples};
+ hana::test::TestSequence<hana::ext::std::tuple_tag>{};
+}
diff --git a/src/boost/libs/hana/test/ext/std/tuple/laws.functor.cpp b/src/boost/libs/hana/test/ext/std/tuple/laws.functor.cpp
new file mode 100644
index 00000000..874d01f9
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/laws.functor.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/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/applicative.hpp>
+#include <laws/base.hpp>
+#include <laws/functor.hpp>
+#include <laws/monad.hpp>
+#include <laws/monad_plus.hpp>
+
+#include <tuple>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto tuples = hana::make_tuple(
+ std::make_tuple()
+ , std::make_tuple(ct_eq<0>{})
+ , std::make_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , std::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , std::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ );
+
+ auto values = hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+
+ auto nested_tuples = hana::make_tuple(
+ std::make_tuple()
+ , std::make_tuple(
+ std::make_tuple(ct_eq<0>{}))
+ , std::make_tuple(
+ std::make_tuple(ct_eq<0>{}),
+ std::make_tuple(ct_eq<1>{}, ct_eq<2>{}))
+ , std::make_tuple(
+ std::make_tuple(ct_eq<0>{}),
+ std::make_tuple(ct_eq<1>{}, ct_eq<2>{}),
+ std::make_tuple(ct_eq<3>{}, ct_eq<4>{}))
+ );
+
+ auto predicates = hana::make_tuple(
+ hana::equal.to(ct_eq<0>{}), hana::equal.to(ct_eq<1>{}), hana::equal.to(ct_eq<2>{}),
+ hana::always(hana::false_c), hana::always(hana::true_c)
+ );
+
+ hana::test::TestFunctor<hana::ext::std::tuple_tag>{tuples, values};
+ hana::test::TestApplicative<hana::ext::std::tuple_tag>{tuples};
+ hana::test::TestMonad<hana::ext::std::tuple_tag>{tuples, nested_tuples};
+ hana::test::TestMonadPlus<hana::ext::std::tuple_tag>{tuples, predicates, values};
+}
diff --git a/src/boost/libs/hana/test/ext/std/tuple/laws.searchable.cpp b/src/boost/libs/hana/test/ext/std/tuple/laws.searchable.cpp
new file mode 100644
index 00000000..7eb6b42b
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/tuple/laws.searchable.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/bool.hpp>
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/searchable.hpp>
+
+#include <tuple>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto tuples = hana::make_tuple(
+ std::make_tuple()
+ , std::make_tuple(ct_eq<0>{})
+ , std::make_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , std::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ );
+ auto keys = hana::make_tuple(ct_eq<3>{}, ct_eq<5>{}, ct_eq<7>{});
+
+ auto bool_tuples = hana::make_tuple(
+ std::make_tuple(hana::true_c)
+ , std::make_tuple(hana::false_c)
+ , std::make_tuple(hana::true_c, hana::true_c)
+ , std::make_tuple(hana::true_c, hana::false_c)
+ , std::make_tuple(hana::false_c, hana::true_c)
+ , std::make_tuple(hana::false_c, hana::false_c)
+ );
+ auto bool_keys = hana::make_tuple(hana::true_c, hana::false_c);
+
+ hana::test::TestSearchable<hana::ext::std::tuple_tag>{tuples, keys};
+ hana::test::TestSearchable<hana::ext::std::tuple_tag>{bool_tuples, bool_keys};
+}
diff --git a/src/boost/libs/hana/test/ext/std/vector.cpp b/src/boost/libs/hana/test/ext/std/vector.cpp
new file mode 100644
index 00000000..1e9e7cde
--- /dev/null
+++ b/src/boost/libs/hana/test/ext/std/vector.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/ext/std/vector.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+// #include <laws/functor.hpp>
+#include <laws/orderable.hpp>
+
+#include <vector>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto eqs = hana::make_tuple(
+ std::vector<hana::test::eq<0>>{0}
+ , std::vector<hana::test::eq<0>>{1}
+ , std::vector<hana::test::eq<0>>{2}
+ , std::vector<hana::test::eq<0>>{3}
+ , std::vector<hana::test::eq<0>>{4}
+ );
+
+ // auto eq_values = hana::make_tuple(hana::test::eq<0>{}, hana::test::eq<2>{});
+
+ auto ords = hana::make_tuple(
+ std::vector<hana::test::ord<0>>{0}
+ , std::vector<hana::test::ord<0>>{1}
+ , std::vector<hana::test::ord<0>>{2}
+ , std::vector<hana::test::ord<0>>{3}
+ , std::vector<hana::test::ord<0>>{4}
+ );
+
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable, Orderable, Functor
+ //////////////////////////////////////////////////////////////////////////
+ hana::test::TestComparable<hana::ext::std::vector_tag>{eqs};
+ hana::test::TestOrderable<hana::ext::std::vector_tag>{ords};
+ // hana::test::TestFunctor<hana::ext::std::vector_tag>{eqs, eq_values};
+}
diff --git a/src/boost/libs/hana/test/fold_left/ref.cpp b/src/boost/libs/hana/test/fold_left/ref.cpp
new file mode 100644
index 00000000..a2b34ad6
--- /dev/null
+++ b/src/boost/libs/hana/test/fold_left/ref.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/at.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+//
+// Make sure that we can fold_left and take arguments by reference.
+//
+
+int main() {
+ // with state
+ {
+ auto xs = hana::make_tuple(1, 2, 3);
+ int state = 99;
+
+ int& three = hana::fold_left(xs, state, [](int&, int& i) -> int& {
+ return i;
+ });
+ BOOST_HANA_RUNTIME_CHECK(three == 3);
+ three = 10;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(xs) == 10);
+ }
+
+ // without state
+ {
+ auto xs = hana::make_tuple(1, 2, 3);
+
+ int& three = hana::fold_left(xs, [](int&, int& i) -> int& {
+ return i;
+ });
+ BOOST_HANA_RUNTIME_CHECK(three == 3);
+ three = 10;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(xs) == 10);
+ }
+}
diff --git a/src/boost/libs/hana/test/fold_right/ref.cpp b/src/boost/libs/hana/test/fold_right/ref.cpp
new file mode 100644
index 00000000..e23cd521
--- /dev/null
+++ b/src/boost/libs/hana/test/fold_right/ref.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/at.hpp>
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+//
+// Make sure that we can fold_right and take arguments by reference.
+//
+
+int main() {
+ // with state
+ {
+ auto xs = hana::make_tuple(1, 2, 3);
+ int state = 99;
+
+ int& one = hana::fold_right(xs, state, [](int& i, int&) -> int& {
+ return i;
+ });
+ BOOST_HANA_RUNTIME_CHECK(one == 1);
+ one = 10;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(xs) == 10);
+ }
+
+ // without state
+ {
+ auto xs = hana::make_tuple(1, 2, 3);
+ int& one = hana::fold_right(xs, [](int& i, int&) -> int& {
+ return i;
+ });
+ BOOST_HANA_RUNTIME_CHECK(one == 1);
+ one = 10;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(xs) == 10);
+ }
+}
diff --git a/src/boost/libs/hana/test/foldable/fold_left_mcd/iterable.cpp b/src/boost/libs/hana/test/foldable/fold_left_mcd/iterable.cpp
new file mode 100644
index 00000000..683d895f
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/fold_left_mcd/iterable.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+#define BOOST_HANA_TEST_ITERABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/fold_left_mcd/monad.cpp b/src/boost/libs/hana/test/foldable/fold_left_mcd/monad.cpp
new file mode 100644
index 00000000..fb3a0b5e
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/fold_left_mcd/monad.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+#define BOOST_HANA_TEST_MONAD
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/fold_left_mcd/monad_plus.cpp b/src/boost/libs/hana/test/foldable/fold_left_mcd/monad_plus.cpp
new file mode 100644
index 00000000..3d2a963d
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/fold_left_mcd/monad_plus.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+#define BOOST_HANA_TEST_MONAD_PLUS
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/fold_left_mcd/orderable.cpp b/src/boost/libs/hana/test/foldable/fold_left_mcd/orderable.cpp
new file mode 100644
index 00000000..ee459465
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/fold_left_mcd/orderable.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+#define BOOST_HANA_TEST_ORDERABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/fold_left_mcd/searchable.cpp b/src/boost/libs/hana/test/foldable/fold_left_mcd/searchable.cpp
new file mode 100644
index 00000000..2569ab05
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/fold_left_mcd/searchable.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+#define BOOST_HANA_TEST_SEARCHABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/fold_left_mcd/sequence.cpp b/src/boost/libs/hana/test/foldable/fold_left_mcd/sequence.cpp
new file mode 100644
index 00000000..c8eeddd6
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/fold_left_mcd/sequence.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+#define BOOST_HANA_TEST_SEQUENCE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/iterable_mcd/iterable.cpp b/src/boost/libs/hana/test/foldable/iterable_mcd/iterable.cpp
new file mode 100644
index 00000000..ecb05112
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/iterable_mcd/iterable.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD
+#define BOOST_HANA_TEST_ITERABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/iterable_mcd/monad.cpp b/src/boost/libs/hana/test/foldable/iterable_mcd/monad.cpp
new file mode 100644
index 00000000..6197c369
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/iterable_mcd/monad.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD
+#define BOOST_HANA_TEST_MONAD
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/iterable_mcd/monad_plus.cpp b/src/boost/libs/hana/test/foldable/iterable_mcd/monad_plus.cpp
new file mode 100644
index 00000000..2aac153d
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/iterable_mcd/monad_plus.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD
+#define BOOST_HANA_TEST_MONAD_PLUS
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/iterable_mcd/orderable.cpp b/src/boost/libs/hana/test/foldable/iterable_mcd/orderable.cpp
new file mode 100644
index 00000000..50632df3
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/iterable_mcd/orderable.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD
+#define BOOST_HANA_TEST_ORDERABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/iterable_mcd/searchable.cpp b/src/boost/libs/hana/test/foldable/iterable_mcd/searchable.cpp
new file mode 100644
index 00000000..d2d1fa1f
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/iterable_mcd/searchable.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD
+#define BOOST_HANA_TEST_SEARCHABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/iterable_mcd/sequence.cpp b/src/boost/libs/hana/test/foldable/iterable_mcd/sequence.cpp
new file mode 100644
index 00000000..bf3d5a9d
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/iterable_mcd/sequence.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD
+#define BOOST_HANA_TEST_SEQUENCE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/unpack_mcd/iterable.cpp b/src/boost/libs/hana/test/foldable/unpack_mcd/iterable.cpp
new file mode 100644
index 00000000..d0d4f50a
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/unpack_mcd/iterable.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD
+#define BOOST_HANA_TEST_ITERABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/unpack_mcd/monad.cpp b/src/boost/libs/hana/test/foldable/unpack_mcd/monad.cpp
new file mode 100644
index 00000000..e7450de3
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/unpack_mcd/monad.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD
+#define BOOST_HANA_TEST_MONAD
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/unpack_mcd/monad_plus.cpp b/src/boost/libs/hana/test/foldable/unpack_mcd/monad_plus.cpp
new file mode 100644
index 00000000..e41ca257
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/unpack_mcd/monad_plus.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD
+#define BOOST_HANA_TEST_MONAD_PLUS
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/unpack_mcd/orderable.cpp b/src/boost/libs/hana/test/foldable/unpack_mcd/orderable.cpp
new file mode 100644
index 00000000..70ef8e9a
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/unpack_mcd/orderable.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD
+#define BOOST_HANA_TEST_ORDERABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/unpack_mcd/searchable.cpp b/src/boost/libs/hana/test/foldable/unpack_mcd/searchable.cpp
new file mode 100644
index 00000000..900cc878
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/unpack_mcd/searchable.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD
+#define BOOST_HANA_TEST_SEARCHABLE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/foldable/unpack_mcd/sequence.cpp b/src/boost/libs/hana/test/foldable/unpack_mcd/sequence.cpp
new file mode 100644
index 00000000..5af417ae
--- /dev/null
+++ b/src/boost/libs/hana/test/foldable/unpack_mcd/sequence.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD
+#define BOOST_HANA_TEST_SEQUENCE
+#include <laws/templates/seq.hpp>
diff --git a/src/boost/libs/hana/test/functional.cpp b/src/boost/libs/hana/test/functional.cpp
new file mode 100644
index 00000000..beb5381b
--- /dev/null
+++ b/src/boost/libs/hana/test/functional.cpp
@@ -0,0 +1,503 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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.hpp>
+
+#include <laws/base.hpp>
+#include <support/tracked.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <int i = 0>
+struct nonpod : Tracked {
+ nonpod() : Tracked{i} { }
+};
+
+template <int i = 0>
+struct undefined { };
+
+struct move_only {
+ move_only() = default;
+ move_only(move_only&&) = default;
+ move_only(move_only const&) = delete;
+};
+
+
+int main() {
+ hana::test::_injection<0> f{};
+ hana::test::_injection<1> g{};
+ hana::test::_injection<2> h{};
+ using hana::test::ct_eq;
+
+ // always
+ {
+ auto z = ct_eq<0>{};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::always(z)(), z
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::always(z)(undefined<1>{}), z
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::always(z)(undefined<1>{}, undefined<2>{}), z
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::always(z)(undefined<1>{}, undefined<2>{}, undefined<3>{}), z
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::always(z)(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}), z
+ ));
+
+ hana::always(z)(nonpod<>{});
+ auto m = hana::always(move_only{})(undefined<1>{}); (void)m;
+ }
+
+ // apply (tested separately)
+ {
+
+ }
+
+ // arg
+ {
+ // moveonly friendliness:
+ move_only z = hana::arg<1>(move_only{}); (void)z;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<1>(ct_eq<1>{}),
+ ct_eq<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<1>(ct_eq<1>{}, undefined<2>{}),
+ ct_eq<1>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<1>(ct_eq<1>{}, undefined<2>{}, undefined<3>{}),
+ ct_eq<1>{}
+ ));
+ hana::arg<1>(nonpod<1>{});
+ hana::arg<1>(nonpod<1>{}, nonpod<2>{});
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<2>(undefined<1>{}, ct_eq<2>{}),
+ ct_eq<2>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<2>(undefined<1>{}, ct_eq<2>{}, undefined<3>{}),
+ ct_eq<2>{}
+ ));
+ hana::arg<2>(nonpod<1>{}, nonpod<2>{});
+ hana::arg<2>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{});
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<3>(undefined<1>{}, undefined<2>{}, ct_eq<3>{}),
+ ct_eq<3>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<3>(undefined<1>{}, undefined<2>{}, ct_eq<3>{}, undefined<4>{}),
+ ct_eq<3>{}
+ ));
+ hana::arg<3>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{});
+ hana::arg<3>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{});
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<4>(undefined<1>{}, undefined<2>{}, undefined<3>{}, ct_eq<4>{}),
+ ct_eq<4>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<4>(undefined<1>{}, undefined<2>{}, undefined<3>{}, ct_eq<4>{}, undefined<5>{}),
+ ct_eq<4>{}
+ ));
+ hana::arg<4>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{});
+ hana::arg<4>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{});
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<5>(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, ct_eq<5>{}),
+ ct_eq<5>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<5>(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, ct_eq<5>{}, undefined<6>{}),
+ ct_eq<5>{}
+ ));
+ hana::arg<5>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{});
+ hana::arg<5>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{}, nonpod<6>{});
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<6>(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, undefined<5>{}, ct_eq<6>{}),
+ ct_eq<6>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::arg<6>(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, undefined<5>{}, ct_eq<6>{}, undefined<7>{}),
+ ct_eq<6>{}
+ ));
+ hana::arg<6>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{}, nonpod<6>{});
+ hana::arg<6>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{}, nonpod<6>{}, nonpod<7>{});
+ }
+
+ // compose
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::compose(f, g)(ct_eq<0>{}),
+ f(g(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::compose(f, g)(ct_eq<0>{}, ct_eq<1>{}),
+ f(g(ct_eq<0>{}), ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::compose(f, g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(g(ct_eq<0>{}), ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::compose(f, g, h)(ct_eq<0>{}),
+ f(g(h(ct_eq<0>{})))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::compose(f, g, h)(ct_eq<0>{}, ct_eq<1>{}),
+ f(g(h(ct_eq<0>{})), ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::compose(f, g, h)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(g(h(ct_eq<0>{})), ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ auto h = [capture = move_only{}](int) { (void)capture; return 1; };
+ auto i = [](int) { return 1; };
+ hana::compose(std::move(h), i)(1);
+
+ {
+ // Compose move-only functions.
+ auto f = [capture = move_only{}](int) { (void)capture; return 1; };
+ auto g = [capture = move_only{}](int) { (void)capture; return 1; };
+ auto c = hana::compose(std::move(f), std::move(g)); (void)c;
+ }
+ }
+
+ // curry
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<0>(f)(),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<1>(f)(ct_eq<1>{}),
+ f(ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<2>(f)(ct_eq<1>{})(ct_eq<2>{}),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<2>(f)(ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<3>(f)(ct_eq<1>{})(ct_eq<2>{})(ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<3>(f)(ct_eq<1>{})(ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<3>(f)(ct_eq<1>{}, ct_eq<2>{})(ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<3>(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+
+ // Make sure curry is idempotent; this is important because it allows
+ // currying a function in generic contexts where it is unknown whether
+ // the function is already curried.
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<0>(hana::curry<0>(f))(),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<1>(hana::curry<1>(f))(ct_eq<1>{}),
+ f(ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<2>(hana::curry<2>(f))(ct_eq<1>{})(ct_eq<2>{}),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<2>(hana::curry<2>(f))(ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<3>(hana::curry<3>(f))(ct_eq<1>{})(ct_eq<2>{})(ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<3>(hana::curry<3>(f))(ct_eq<1>{})(ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<3>(hana::curry<3>(f))(ct_eq<1>{}, ct_eq<2>{})(ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::curry<3>(hana::curry<3>(f))(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ }
+
+ // demux (tested separately)
+ {
+
+ }
+
+ // fix (tested separately)
+ {
+
+ }
+
+ // flip
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flip(f)(ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<2>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flip(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flip(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
+ f(ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<4>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flip(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}),
+ f(ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})
+ ));
+ }
+
+ // id
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::id(ct_eq<0>{}),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::id(ct_eq<1>{}),
+ ct_eq<1>{}
+ ));
+
+ (void)hana::id(move_only{});
+
+ // make sure we don't return a dangling reference
+ auto f = []() -> decltype(auto) { return hana::id(Tracked{1}); };
+ auto z = f(); (void)z;
+ }
+
+ // lockstep (tested separately)
+ {
+
+ }
+
+ // infix
+ {
+ auto g = hana::infix(f);
+
+ // disregard associativity
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ ct_eq<0>{} ^g^ ct_eq<1>{},
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (ct_eq<0>{} ^g)^ ct_eq<1>{},
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ ct_eq<0>{} ^(g^ ct_eq<1>{}),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ // left partial application
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (ct_eq<0>{}^g)(ct_eq<1>{}),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (ct_eq<0>{}^g)(ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (ct_eq<0>{}^g)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+ // right partial application
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (g^ct_eq<1>{})(ct_eq<0>{}),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (g^ct_eq<2>{})(ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (g^ct_eq<3>{})(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+ // equivalence with the base function
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ g(ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ g(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ g(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ }
+
+ // on
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::on(f, g)(),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::on(f, g)(ct_eq<0>{}),
+ f(g(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::on(f, g)(ct_eq<0>{}, ct_eq<1>{}),
+ f(g(ct_eq<0>{}), g(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::on(f, g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::on(f, g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}), g(ct_eq<3>{}))
+ ));
+
+ // check the infix version
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (f ^hana::on^ g)(),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (f ^hana::on^ g)(ct_eq<0>{}),
+ f(g(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (f ^hana::on^ g)(ct_eq<0>{}, ct_eq<1>{}),
+ f(g(ct_eq<0>{}), g(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (f ^hana::on^ g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ (f ^hana::on^ g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}), g(ct_eq<3>{}))
+ ));
+ }
+
+ // overload
+ {
+ // 1 function
+ {
+ auto f = hana::overload([](int) { return ct_eq<1>{}; });
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq<1>{}));
+ }
+
+ // 2 functions
+ {
+ auto f = hana::overload(
+ [](int) { return ct_eq<1>{}; },
+ [](float) { return ct_eq<2>{}; }
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq<1>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(float{}), ct_eq<2>{}));
+ }
+
+ // 3 functions
+ {
+ auto f = hana::overload(
+ [](int) { return ct_eq<1>{}; },
+ [](float) { return ct_eq<2>{}; },
+ static_cast<ct_eq<3>(*)(char)>([](char) { return ct_eq<3>{}; })
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq<1>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(float{}), ct_eq<2>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(char{}), ct_eq<3>{}));
+ }
+
+ // 4 functions
+ {
+ auto f = hana::overload(
+ [](int) { return ct_eq<1>{}; },
+ [](float) { return ct_eq<2>{}; },
+ static_cast<ct_eq<3>(*)(char)>([](char) { return ct_eq<3>{}; }),
+ [](auto) { return ct_eq<4>{}; }
+ );
+
+ struct otherwise { };
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq<1>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(float{}), ct_eq<2>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(char{}), ct_eq<3>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(f(otherwise{}), ct_eq<4>{}));
+ }
+
+ // check move-only friendliness for bare functions
+ {
+ void (*g)(move_only) = [](move_only) { };
+ hana::overload(g)(move_only{});
+ }
+
+ // check non-strict matches which require a conversion
+ {
+ struct convertible_to_int { operator int() const { return 1; } };
+ auto f = [](int) { return ct_eq<0>{}; };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::overload(f)(convertible_to_int{}),
+ ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::overload(static_cast<ct_eq<0>(*)(int)>(f))(convertible_to_int{}),
+ ct_eq<0>{}
+ ));
+ }
+ }
+
+ // partial (tested separately)
+ {
+
+ }
+
+ // placeholder (tested separately)
+ {
+
+ }
+}
diff --git a/src/boost/libs/hana/test/functional/apply.cpp b/src/boost/libs/hana/test/functional/apply.cpp
new file mode 100644
index 00000000..ff1c81cf
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/apply.cpp
@@ -0,0 +1,262 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/apply.hpp>
+
+#include <laws/base.hpp>
+#include <support/tracked.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <int i = 0>
+struct nonpod : Tracked {
+ nonpod() : Tracked{i} { }
+};
+
+struct NonCopyable {
+ NonCopyable() = default;
+ NonCopyable(NonCopyable const&) = delete;
+ NonCopyable& operator=(NonCopyable const&) = delete;
+};
+
+struct TestClass {
+ explicit TestClass(int x) : data(x) { }
+ TestClass(TestClass const&) = delete;
+ TestClass& operator=(TestClass const&) = delete;
+
+ int& operator()(NonCopyable&&) & { return data; }
+ int const& operator()(NonCopyable&&) const & { return data; }
+ int volatile& operator()(NonCopyable&&) volatile & { return data; }
+ int const volatile& operator()(NonCopyable&&) const volatile & { return data; }
+
+ int&& operator()(NonCopyable&&) && { return std::move(data); }
+ int const&& operator()(NonCopyable&&) const && { return std::move(data); }
+ int volatile&& operator()(NonCopyable&&) volatile && { return std::move(data); }
+ int const volatile&& operator()(NonCopyable&&) const volatile && { return std::move(data); }
+
+ int data;
+};
+
+struct DerivedFromTestClass : TestClass {
+ explicit DerivedFromTestClass(int x) : TestClass(x) { }
+};
+
+
+template <typename Signature, typename Expect, typename Functor>
+void test_b12(Functor&& f) {
+ // Create the callable object.
+ using ClassFunc = Signature TestClass::*;
+ ClassFunc func_ptr = &TestClass::operator();
+
+ // Create the dummy arg.
+ NonCopyable arg;
+
+ // Check that the deduced return type of invoke is what is expected.
+ using DeducedReturnType = decltype(
+ hana::apply(func_ptr, std::forward<Functor>(f), std::move(arg))
+ );
+ static_assert(std::is_same<DeducedReturnType, Expect>::value, "");
+
+ // Check that result_of_t matches Expect.
+ using ResultOfReturnType = typename std::result_of<ClassFunc&&(Functor&&, NonCopyable&&)>::type;
+ static_assert(std::is_same<ResultOfReturnType, Expect>::value, "");
+
+ // Run invoke and check the return value.
+ DeducedReturnType ret = hana::apply(func_ptr, std::forward<Functor>(f), std::move(arg));
+ BOOST_HANA_RUNTIME_CHECK(ret == 42);
+}
+
+template <typename Expect, typename Functor>
+void test_b34(Functor&& f) {
+ // Create the callable object.
+ using ClassFunc = int TestClass::*;
+ ClassFunc func_ptr = &TestClass::data;
+
+ // Check that the deduced return type of invoke is what is expected.
+ using DeducedReturnType = decltype(
+ hana::apply(func_ptr, std::forward<Functor>(f))
+ );
+ static_assert(std::is_same<DeducedReturnType, Expect>::value, "");
+
+ // Check that result_of_t matches Expect.
+ using ResultOfReturnType = typename std::result_of<ClassFunc&&(Functor&&)>::type;
+ static_assert(std::is_same<ResultOfReturnType, Expect>::value, "");
+
+ // Run invoke and check the return value.
+ DeducedReturnType ret = hana::apply(func_ptr, std::forward<Functor>(f));
+ BOOST_HANA_RUNTIME_CHECK(ret == 42);
+}
+
+template <typename Expect, typename Functor>
+void test_b5(Functor&& f) {
+ NonCopyable arg;
+
+ // Check that the deduced return type of invoke is what is expected.
+ using DeducedReturnType = decltype(
+ hana::apply(std::forward<Functor>(f), std::move(arg))
+ );
+ static_assert(std::is_same<DeducedReturnType, Expect>::value, "");
+
+ // Check that result_of_t matches Expect.
+ using ResultOfReturnType = typename std::result_of<Functor&&(NonCopyable&&)>::type;
+ static_assert(std::is_same<ResultOfReturnType, Expect>::value, "");
+
+ // Run invoke and check the return value.
+ DeducedReturnType ret = hana::apply(std::forward<Functor>(f), std::move(arg));
+ BOOST_HANA_RUNTIME_CHECK(ret == 42);
+}
+
+int& foo(NonCopyable&&) {
+ static int data = 42;
+ return data;
+}
+
+int main() {
+ // Test normal usage with a function object
+ {
+ hana::test::_injection<0> f{};
+ using hana::test::ct_eq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::apply(f),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::apply(f, ct_eq<0>{}),
+ f(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::apply(f, ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::apply(f, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::apply(f, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+ // Make sure we can use apply with non-PODs
+ hana::apply(f, nonpod<>{});
+ }
+
+ // Bullets 1 & 2 in the standard
+ {
+ TestClass cl(42);
+ test_b12<int&(NonCopyable&&) &, int&>(cl);
+ test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
+ test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
+ test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
+
+ test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
+ test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
+ test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
+ test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
+ }
+ {
+ DerivedFromTestClass cl(42);
+ test_b12<int&(NonCopyable&&) &, int&>(cl);
+ test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
+ test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
+ test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
+
+ test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
+ test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
+ test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
+ test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
+ }
+ {
+ TestClass cl_obj(42);
+ TestClass *cl = &cl_obj;
+ test_b12<int&(NonCopyable&&) &, int&>(cl);
+ test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
+ test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
+ test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
+ }
+ {
+ DerivedFromTestClass cl_obj(42);
+ DerivedFromTestClass *cl = &cl_obj;
+ test_b12<int&(NonCopyable&&) &, int&>(cl);
+ test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
+ test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
+ test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
+ }
+
+ // Bullets 3 & 4 in the standard
+ {
+ using Fn = TestClass;
+ Fn cl(42);
+ test_b34<int&>(cl);
+ test_b34<int const&>(static_cast<Fn const&>(cl));
+ test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
+ test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
+
+ test_b34<int&&>(static_cast<Fn &&>(cl));
+ test_b34<int const&&>(static_cast<Fn const&&>(cl));
+ test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
+ test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
+ }
+ {
+ using Fn = DerivedFromTestClass;
+ Fn cl(42);
+ test_b34<int&>(cl);
+ test_b34<int const&>(static_cast<Fn const&>(cl));
+ test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
+ test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
+
+ test_b34<int&&>(static_cast<Fn &&>(cl));
+ test_b34<int const&&>(static_cast<Fn const&&>(cl));
+ test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
+ test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
+ }
+ {
+ using Fn = TestClass;
+ Fn cl_obj(42);
+ Fn* cl = &cl_obj;
+ test_b34<int&>(cl);
+ test_b34<int const&>(static_cast<Fn const*>(cl));
+ test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
+ test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
+ }
+ {
+ using Fn = DerivedFromTestClass;
+ Fn cl_obj(42);
+ Fn* cl = &cl_obj;
+ test_b34<int&>(cl);
+ test_b34<int const&>(static_cast<Fn const*>(cl));
+ test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
+ test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
+ }
+
+ // Bullet 5 in the standard
+ using FooType = int&(NonCopyable&&);
+ {
+ FooType& fn = foo;
+ test_b5<int &>(fn);
+ }
+ {
+ FooType* fn = foo;
+ test_b5<int &>(fn);
+ }
+ {
+ using Fn = TestClass;
+ Fn cl(42);
+ test_b5<int&>(cl);
+ test_b5<int const&>(static_cast<Fn const&>(cl));
+ test_b5<int volatile&>(static_cast<Fn volatile&>(cl));
+ test_b5<int const volatile&>(static_cast<Fn const volatile &>(cl));
+
+ test_b5<int&&>(static_cast<Fn &&>(cl));
+ test_b5<int const&&>(static_cast<Fn const&&>(cl));
+ test_b5<int volatile&&>(static_cast<Fn volatile&&>(cl));
+ test_b5<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
+ }
+}
diff --git a/src/boost/libs/hana/test/functional/capture.cpp b/src/boost/libs/hana/test/functional/capture.cpp
new file mode 100644
index 00000000..f64a65c0
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/capture.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/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/capture.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ // 0-arg capture
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture()(f)(),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture()(f)(ct_eq<0>{}),
+ f(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture()(f)(ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture()(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ // 1-arg capture
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{})(f)(),
+ f(ct_eq<77>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{})(f)(ct_eq<0>{}),
+ f(ct_eq<77>{}, ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{})(f)(ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<77>{}, ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{})(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<77>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ // 2-args capture
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{}, ct_eq<88>{})(f)(),
+ f(ct_eq<77>{}, ct_eq<88>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{}, ct_eq<88>{})(f)(ct_eq<0>{}),
+ f(ct_eq<77>{}, ct_eq<88>{}, ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{}, ct_eq<88>{})(f)(ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<77>{}, ct_eq<88>{}, ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{}, ct_eq<88>{})(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<77>{}, ct_eq<88>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ // 3-args capture
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{}, ct_eq<88>{}, ct_eq<99>{})(f)(),
+ f(ct_eq<77>{}, ct_eq<88>{}, ct_eq<99>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{}, ct_eq<88>{}, ct_eq<99>{})(f)(ct_eq<0>{}),
+ f(ct_eq<77>{}, ct_eq<88>{}, ct_eq<99>{}, ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{}, ct_eq<88>{}, ct_eq<99>{})(f)(ct_eq<0>{}, ct_eq<1>{}),
+ f(ct_eq<77>{}, ct_eq<88>{}, ct_eq<99>{}, ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::capture(ct_eq<77>{}, ct_eq<88>{}, ct_eq<99>{})(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<77>{}, ct_eq<88>{}, ct_eq<99>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/functional/demux.cpp b/src/boost/libs/hana/test/functional/demux.cpp
new file mode 100644
index 00000000..07285bce
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/demux.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/equal.hpp>
+#include <boost/hana/functional/demux.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct MoveOnly {
+ MoveOnly() = default;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly(MoveOnly&&) = default;
+};
+
+int main() {
+ hana::test::_injection<0> f{};
+ hana::test::_injection<1> g{};
+ hana::test::_injection<2> h{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::demux(f)()(),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::demux(f)(g)(ct_eq<1>{}),
+ f(g(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::demux(f)(g)(ct_eq<1>{}, ct_eq<2>{}),
+ f(g(ct_eq<1>{}, ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::demux(f)(g)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(g(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::demux(f)(g, h)(ct_eq<1>{}),
+ f(g(ct_eq<1>{}), h(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::demux(f)(g, h)(ct_eq<1>{}, ct_eq<2>{}),
+ f(g(ct_eq<1>{}, ct_eq<2>{}), h(ct_eq<1>{}, ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::demux(f)(g, h)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(g(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), h(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}))
+ ));
+
+ // Make sure we can pass move-only types when a single function
+ // is demux'ed. In other words, make sure the arguments are
+ // perfect-forwarded when a single function is demux'ed.
+ {
+ hana::demux(f)(g)(MoveOnly{});
+ hana::demux(f)(g)(MoveOnly{}, MoveOnly{});
+ hana::demux(f)(g)(MoveOnly{}, MoveOnly{}, MoveOnly{});
+ }
+}
diff --git a/src/boost/libs/hana/test/functional/fix.cpp b/src/boost/libs/hana/test/functional/fix.cpp
new file mode 100644
index 00000000..79041b4a
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/fix.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/functional/fix.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/mult.hpp>
+namespace hana = boost::hana;
+
+
+BOOST_HANA_CONSTEXPR_LAMBDA auto fact = hana::fix([](auto fact, auto n) {
+ return hana::eval_if(hana::equal(n, hana::ullong_c<0>),
+ hana::always(hana::ullong_c<1>),
+ [=](auto _) { return hana::mult(n, fact(_(n) - hana::ullong_c<1>)); }
+ );
+});
+
+constexpr unsigned long long reference(unsigned long long n)
+{ return n == 0 ? 1 : n * reference(n - 1); }
+
+template <int n>
+void test() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ fact(hana::ullong_c<n>),
+ hana::ullong_c<reference(n)>
+ ));
+ test<n - 1>();
+}
+
+template <> void test<-1>() { }
+
+int main() {
+ test<15>();
+}
diff --git a/src/boost/libs/hana/test/functional/iterate.cpp b/src/boost/libs/hana/test/functional/iterate.cpp
new file mode 100644
index 00000000..f4080576
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/iterate.cpp
@@ -0,0 +1,151 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/iterate.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+
+#include <laws/base.hpp>
+
+#include <vector>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct undefined { };
+
+constexpr int incr(int i) { return i + 1; }
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ // "real usage" tests
+ static_assert(hana::iterate<3>(incr, 0) == 3, "");
+ {
+ std::vector<int> vec;
+ hana::iterate<10>([&](int i) { vec.push_back(i); return i + 1; }, 0);
+ BOOST_HANA_RUNTIME_CHECK(
+ vec == std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+ );
+ }
+
+ // equivalence between iterate<n>(f, x) and iterate<n>(f)(x)
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<0>(undefined{})(ct_eq<0>{}),
+ hana::iterate<0>(undefined{}, ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<4>(f)(ct_eq<0>{}),
+ hana::iterate<4>(f, ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<10>(f)(ct_eq<0>{}),
+ hana::iterate<10>(f, ct_eq<0>{})
+ ));
+
+ // systematic tests
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<0>(undefined{}, ct_eq<0>{}),
+ ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<1>(f, ct_eq<0>{}),
+ f(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<2>(f, ct_eq<0>{}),
+ f(f(ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<3>(f, ct_eq<0>{}),
+ f(f(f(ct_eq<0>{})))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<4>(f, ct_eq<0>{}),
+ f(f(f(f(ct_eq<0>{}))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<5>(f, ct_eq<0>{}),
+ f(f(f(f(f(ct_eq<0>{})))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<6>(f, ct_eq<0>{}),
+ f(f(f(f(f(f(ct_eq<0>{}))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<7>(f, ct_eq<0>{}),
+ f(f(f(f(f(f(f(ct_eq<0>{})))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<11>(f, ct_eq<0>{}),
+ f(f(f(f(f(f(f(f(f(f(f(ct_eq<0>{})))))))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<12>(f, ct_eq<0>{}),
+ f(f(f(f(f(f(f(f(f(f(f(f(ct_eq<0>{}))))))))))))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::iterate<13>(f, ct_eq<0>{}),
+ f(f(f(f(f(f(f(f(f(f(f(f(f(ct_eq<0>{})))))))))))))
+ ));
+
+ // We can't nest too many calls to f, because that uses a hana::tuple
+ // internally and some implementation (libstdc++) have trouble with
+ // deeply-nested calls to `std::is_constructible`, which is required by
+ // hana::tuple. Hence, we use an homogeneous function for the remaining
+ // tests.
+ static_assert(hana::iterate<23>(incr, 0) == 23, "");
+ static_assert(hana::iterate<24>(incr, 0) == 24, "");
+ static_assert(hana::iterate<25>(incr, 0) == 25, "");
+ static_assert(hana::iterate<26>(incr, 0) == 26, "");
+ static_assert(hana::iterate<27>(incr, 0) == 27, "");
+ static_assert(hana::iterate<28>(incr, 0) == 28, "");
+ static_assert(hana::iterate<29>(incr, 0) == 29, "");
+
+ static_assert(hana::iterate<30>(incr, 0) == 30, "");
+ static_assert(hana::iterate<31>(incr, 0) == 31, "");
+ static_assert(hana::iterate<32>(incr, 0) == 32, "");
+ static_assert(hana::iterate<33>(incr, 0) == 33, "");
+ static_assert(hana::iterate<34>(incr, 0) == 34, "");
+ static_assert(hana::iterate<35>(incr, 0) == 35, "");
+ static_assert(hana::iterate<36>(incr, 0) == 36, "");
+ static_assert(hana::iterate<37>(incr, 0) == 37, "");
+ static_assert(hana::iterate<38>(incr, 0) == 38, "");
+ static_assert(hana::iterate<39>(incr, 0) == 39, "");
+
+ static_assert(hana::iterate<40>(incr, 0) == 40, "");
+ static_assert(hana::iterate<41>(incr, 0) == 41, "");
+ static_assert(hana::iterate<42>(incr, 0) == 42, "");
+ static_assert(hana::iterate<43>(incr, 0) == 43, "");
+ static_assert(hana::iterate<44>(incr, 0) == 44, "");
+ static_assert(hana::iterate<45>(incr, 0) == 45, "");
+ static_assert(hana::iterate<46>(incr, 0) == 46, "");
+ static_assert(hana::iterate<47>(incr, 0) == 47, "");
+ static_assert(hana::iterate<48>(incr, 0) == 48, "");
+ static_assert(hana::iterate<49>(incr, 0) == 49, "");
+
+ static_assert(hana::iterate<50>(incr, 0) == 50, "");
+ static_assert(hana::iterate<51>(incr, 0) == 51, "");
+ static_assert(hana::iterate<52>(incr, 0) == 52, "");
+ static_assert(hana::iterate<53>(incr, 0) == 53, "");
+ static_assert(hana::iterate<54>(incr, 0) == 54, "");
+ static_assert(hana::iterate<55>(incr, 0) == 55, "");
+ static_assert(hana::iterate<56>(incr, 0) == 56, "");
+ static_assert(hana::iterate<57>(incr, 0) == 57, "");
+ static_assert(hana::iterate<58>(incr, 0) == 58, "");
+ static_assert(hana::iterate<59>(incr, 0) == 59, "");
+}
diff --git a/src/boost/libs/hana/test/functional/lockstep.cpp b/src/boost/libs/hana/test/functional/lockstep.cpp
new file mode 100644
index 00000000..086d02ca
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/lockstep.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/functional/lockstep.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+ hana::test::_injection<1> g{};
+ hana::test::_injection<2> h{};
+ hana::test::_injection<3> i{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::lockstep(f)()(),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::lockstep(f)(g)(ct_eq<1>{}),
+ f(g(ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::lockstep(f)(g, h)(ct_eq<1>{}, ct_eq<2>{}),
+ f(g(ct_eq<1>{}), h(ct_eq<2>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::lockstep(f)(g, h, i)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(g(ct_eq<1>{}), h(ct_eq<2>{}), i(ct_eq<3>{}))
+ ));
+}
diff --git a/src/boost/libs/hana/test/functional/overload_linearly.cpp b/src/boost/libs/hana/test/functional/overload_linearly.cpp
new file mode 100644
index 00000000..6f537f58
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/overload_linearly.cpp
@@ -0,0 +1,122 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/overload_linearly.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct A { };
+struct AA : A { };
+struct B { };
+struct C { };
+
+int main() {
+ // 2 functions without overlap
+ {
+ auto f = hana::overload_linearly(
+ [](A) { return ct_eq<0>{}; },
+ [](B) { return ct_eq<1>{}; }
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(A{}),
+ ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(AA{}),
+ f(A{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(B{}),
+ ct_eq<1>{}
+ ));
+ }
+
+ // 2 functions with overlap
+ {
+ auto f = hana::overload_linearly(
+ [](A) { return ct_eq<0>{}; },
+ [](A) { return ct_eq<1>{}; }
+ );
+
+ auto g = hana::overload_linearly(
+ [](A) { return ct_eq<0>{}; },
+ [](AA) { return ct_eq<1>{}; }
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(A{}),
+ ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(AA{}),
+ f(A{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ g(A{}),
+ ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ g(AA{}),
+ g(A{})
+ ));
+ }
+
+ // 3 functions
+ {
+ auto f = hana::overload_linearly(
+ [](A) { return ct_eq<0>{}; },
+ [](B) { return ct_eq<1>{}; },
+ [](C) { return ct_eq<2>{}; }
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(A{}),
+ ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(AA{}),
+ f(A{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(B{}),
+ ct_eq<1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(C{}),
+ ct_eq<2>{}
+ ));
+ }
+
+ // 1 function (github issue #280)
+ {
+ auto f = hana::overload_linearly(
+ [](A) { return ct_eq<0>{}; }
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(A{}),
+ ct_eq<0>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ f(AA{}),
+ f(A{})
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/functional/partial.cpp b/src/boost/libs/hana/test/functional/partial.cpp
new file mode 100644
index 00000000..e6f56243
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/partial.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/equal.hpp>
+#include <boost/hana/functional/partial.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f)(),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f)(ct_eq<1>{}),
+ f(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f)(ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f, ct_eq<1>{})(),
+ f(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f, ct_eq<1>{})(ct_eq<2>{}),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f, ct_eq<1>{})(ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f, ct_eq<1>{}, ct_eq<2>{})(),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f, ct_eq<1>{}, ct_eq<2>{})(ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f, ct_eq<1>{}, ct_eq<2>{})(ct_eq<3>{}, ct_eq<4>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::partial(f, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})(),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/functional/placeholder.cpp b/src/boost/libs/hana/test/functional/placeholder.cpp
new file mode 100644
index 00000000..be6c9e61
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/placeholder.cpp
@@ -0,0 +1,119 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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 <utility>
+namespace hana = boost::hana;
+using hana::_;
+
+
+struct extra_t { virtual ~extra_t() { } };
+extra_t extra{};
+
+constexpr struct { } invalid{};
+
+template <typename ...> using bool_t = bool;
+constexpr bool valid_call(...) { return false; }
+template <typename F, typename ...Args>
+constexpr auto valid_call(F&& f, Args&& ...args)
+ -> bool_t<decltype(std::forward<F>(f)(std::forward<Args>(args)...))>
+{ return true; }
+
+#define BOOST_HANA_TEST_BINARY_OP(op, x, y) \
+ static_assert((_ op _)(x, y) == (x op y), ""); \
+ BOOST_HANA_RUNTIME_CHECK((_ op _)(x, y, extra) == (x op y)); \
+ BOOST_HANA_RUNTIME_CHECK((_ op _)(x, y, extra, extra) == (x op y)); \
+ static_assert(!valid_call(_ op _), ""); \
+ static_assert(!valid_call(_ op _, invalid), ""); \
+ static_assert(!valid_call(_ op _, invalid, invalid), ""); \
+ \
+ static_assert((_ op y)(x) == (x op y), ""); \
+ BOOST_HANA_RUNTIME_CHECK((_ op y)(x, extra) == (x op y)); \
+ BOOST_HANA_RUNTIME_CHECK((_ op y)(x, extra, extra) == (x op y)); \
+ static_assert(!valid_call(_ op y), ""); \
+ static_assert(!valid_call(_ op y, invalid), ""); \
+ \
+ static_assert((x op _)(y) == (x op y), ""); \
+ BOOST_HANA_RUNTIME_CHECK((x op _)(y, extra) == (x op y)); \
+ BOOST_HANA_RUNTIME_CHECK((x op _)(y, extra, extra) == (x op y)); \
+ static_assert(!valid_call(x op _), ""); \
+ static_assert(!valid_call(x op _, invalid), ""); \
+ static_assert(!valid_call(x op _, invalid), ""); \
+/**/
+
+#define BOOST_HANA_TEST_UNARY_OP(op, x) \
+ static_assert((op _)(x) == (op x), ""); \
+ BOOST_HANA_RUNTIME_CHECK((op _)(x, extra) == (op x)); \
+ BOOST_HANA_RUNTIME_CHECK((op _)(x, extra, extra) == (op x)); \
+ static_assert(!valid_call(op _), ""); \
+ static_assert(!valid_call(op _, invalid), ""); \
+/**/
+
+struct incr_t {
+ template <typename X>
+ constexpr auto operator()(X x) const -> decltype(x + 1)
+ { return x + 1; }
+};
+constexpr incr_t incr{};
+
+int main() {
+ // Arithmetic
+ BOOST_HANA_TEST_UNARY_OP(+, 1)
+ BOOST_HANA_TEST_UNARY_OP(-, 1)
+ BOOST_HANA_TEST_BINARY_OP(+, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(-, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(*, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(/, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(%, 6, 3)
+
+ // Bitwise
+ BOOST_HANA_TEST_UNARY_OP(~, 5)
+ BOOST_HANA_TEST_BINARY_OP(&, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(|, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(^, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(<<, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(>>, 6, 3)
+
+ // Comparison
+ BOOST_HANA_TEST_BINARY_OP(==, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(!=, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(<, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(<=, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(>, 6, 3)
+ BOOST_HANA_TEST_BINARY_OP(>=, 6, 3)
+
+ // Logical
+ BOOST_HANA_TEST_BINARY_OP(||, true, false)
+ BOOST_HANA_TEST_BINARY_OP(&&, true, true)
+ BOOST_HANA_TEST_UNARY_OP(!, true)
+
+ // Member access
+ constexpr int i = 4;
+ constexpr int array[] = {0, 1, 2};
+ BOOST_HANA_TEST_UNARY_OP(*, &i)
+
+ static_assert(_[0](array) == array[0], "");
+ BOOST_HANA_RUNTIME_CHECK(_[0](array, extra) == array[0]);
+ BOOST_HANA_RUNTIME_CHECK(_[0](array, extra, extra) == array[0]);
+ static_assert(_[1](array) == array[1], "");
+ static_assert(_[1](array) == array[1], "");
+ static_assert(_[2](array) == array[2], "");
+ static_assert(!valid_call(_[invalid]), "");
+ static_assert(!valid_call(_[invalid], array), "");
+ static_assert(!valid_call(_[invalid], invalid), "");
+ static_assert(!valid_call(_[0], invalid), "");
+
+ // Call operator
+ static_assert(_(1)(incr) == incr(1), "");
+ BOOST_HANA_RUNTIME_CHECK(_(1)(incr, extra) == incr(1));
+ BOOST_HANA_RUNTIME_CHECK(_(1)(incr, extra, extra) == incr(1));
+ static_assert(_(2)(incr) == incr(2), "");
+ static_assert(_(3)(incr) == incr(3), "");
+ static_assert(!valid_call(_(invalid)), "");
+ static_assert(!valid_call(_(invalid), incr), "");
+ static_assert(!valid_call(_(invalid), invalid), "");
+ static_assert(!valid_call(_(1), invalid), "");
+}
diff --git a/src/boost/libs/hana/test/functional/reverse_partial.cpp b/src/boost/libs/hana/test/functional/reverse_partial.cpp
new file mode 100644
index 00000000..b5a131a1
--- /dev/null
+++ b/src/boost/libs/hana/test/functional/reverse_partial.cpp
@@ -0,0 +1,65 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/reverse_partial.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ constexpr auto rp = hana::reverse_partial;
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f)(),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f)(ct_eq<1>{}),
+ f(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f)(ct_eq<1>{}, ct_eq<2>{}),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f, ct_eq<1>{})(),
+ f(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f, ct_eq<1>{})(ct_eq<2>{}),
+ f(ct_eq<2>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f, ct_eq<1>{})(ct_eq<2>{}, ct_eq<3>{}),
+ f(ct_eq<2>{}, ct_eq<3>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f, ct_eq<1>{}, ct_eq<2>{})(),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f, ct_eq<1>{}, ct_eq<2>{})(ct_eq<3>{}),
+ f(ct_eq<3>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f, ct_eq<1>{}, ct_eq<2>{})(ct_eq<3>{}, ct_eq<4>{}),
+ f(ct_eq<3>{}, ct_eq<4>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ rp(f, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})(),
+ f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/group.cpp b/src/boost/libs/hana/test/group.cpp
new file mode 100644
index 00000000..1c069b4c
--- /dev/null
+++ b/src/boost/libs/hana/test/group.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/concept/group.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/negate.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/group.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::TestGroup<int>{hana::make_tuple(0,1,2,3,4,5)};
+ hana::test::TestGroup<long>{hana::make_tuple(0l,1l,2l,3l,4l,5l)};
+
+ // minus
+ static_assert(hana::minus(6, 4) == 6 - 4, "");
+
+ // negate
+ static_assert(hana::negate(6) == -6, "");
+}
diff --git a/src/boost/libs/hana/test/identity/applicative.full_mcd.cpp b/src/boost/libs/hana/test/identity/applicative.full_mcd.cpp
new file mode 100644
index 00000000..ceb00326
--- /dev/null
+++ b/src/boost/libs/hana/test/identity/applicative.full_mcd.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_APPLICATIVE_FULL_MCD
+#include "main.hpp"
diff --git a/src/boost/libs/hana/test/identity/applicative.monad_mcd.cpp b/src/boost/libs/hana/test/identity/applicative.monad_mcd.cpp
new file mode 100644
index 00000000..7c255253
--- /dev/null
+++ b/src/boost/libs/hana/test/identity/applicative.monad_mcd.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_APPLICATIVE_MONAD_MCD
+#include "main.hpp"
diff --git a/src/boost/libs/hana/test/identity/functor.adjust_mcd.cpp b/src/boost/libs/hana/test/identity/functor.adjust_mcd.cpp
new file mode 100644
index 00000000..972d12e6
--- /dev/null
+++ b/src/boost/libs/hana/test/identity/functor.adjust_mcd.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FUNCTOR_ADJUST_MCD
+#include "main.hpp"
diff --git a/src/boost/libs/hana/test/identity/functor.transform_mcd.cpp b/src/boost/libs/hana/test/identity/functor.transform_mcd.cpp
new file mode 100644
index 00000000..e9bbba14
--- /dev/null
+++ b/src/boost/libs/hana/test/identity/functor.transform_mcd.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD
+#include "main.hpp"
diff --git a/src/boost/libs/hana/test/identity/main.hpp b/src/boost/libs/hana/test/identity/main.hpp
new file mode 100644
index 00000000..012aeb54
--- /dev/null
+++ b/src/boost/libs/hana/test/identity/main.hpp
@@ -0,0 +1,150 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/ap.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fill.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/replace_if.hpp>
+#include <boost/hana/tap.hpp>
+#include <boost/hana/then.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/applicative.hpp>
+#include <laws/base.hpp>
+#include <laws/functor.hpp>
+#include <laws/monad.hpp>
+#include <support/cnumeric.hpp>
+#include <support/identity.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ // Functor
+ {
+ auto functor = ::identity;
+ // adjust_if
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::adjust_if(functor(ct_eq<0>{}), hana::always(cnumeric<bool, true>), f),
+ functor(f(ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::adjust_if(functor(ct_eq<0>{}), hana::always(cnumeric<bool, false>), f),
+ functor(ct_eq<0>{})
+ ));
+ }
+
+ // fill
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fill(functor(ct_eq<0>{}), ct_eq<1>{}),
+ functor(ct_eq<1>{})
+ ));
+ }
+
+ // transform
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(functor(ct_eq<0>{}), f),
+ functor(f(ct_eq<0>{}))
+ ));
+ }
+
+ // replace_if
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(functor(ct_eq<0>{}), hana::always(cnumeric<bool, true>), ct_eq<1>{}),
+ functor(ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::replace_if(functor(ct_eq<0>{}), hana::always(cnumeric<bool, false>), ct_eq<1>{}),
+ functor(ct_eq<0>{})
+ ));
+ }
+ }
+
+ // Applicative
+ {
+ auto a = ::identity;
+ using A = ::Identity;
+
+ // ap
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(a(f), a(ct_eq<0>{})),
+ a(f(ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(a(f), a(ct_eq<0>{}), a(ct_eq<1>{})),
+ a(f(ct_eq<0>{}, ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(a(f), a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{})),
+ a(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(a(f), a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{}), a(ct_eq<3>{})),
+ a(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}))
+ ));
+ }
+
+ // lift
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::lift<A>(ct_eq<0>{}),
+ a(ct_eq<0>{})
+ ));
+ }
+ }
+
+ // Monad
+ {
+ auto monad = ::identity;
+ using M = ::Identity;
+ auto f = hana::compose(monad, hana::test::_injection<0>{});
+
+ // chain
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(monad(ct_eq<1>{}), f),
+ f(ct_eq<1>{})
+ ));
+ }
+
+ // tap
+ {
+ bool executed = false;
+ auto exec = [&](auto) { executed = true; };
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(monad(ct_eq<0>{}), hana::tap<M>(exec)),
+ monad(ct_eq<0>{})
+ ));
+ BOOST_HANA_RUNTIME_CHECK(executed);
+ }
+
+ // then
+ {
+ struct invalid { };
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::then(monad(invalid{}), monad(ct_eq<0>{})),
+ monad(ct_eq<0>{})
+ ));
+ }
+ }
+}
diff --git a/src/boost/libs/hana/test/identity/monad.chain_mcd.cpp b/src/boost/libs/hana/test/identity/monad.chain_mcd.cpp
new file mode 100644
index 00000000..bad96d72
--- /dev/null
+++ b/src/boost/libs/hana/test/identity/monad.chain_mcd.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_MONAD_CHAIN_MCD
+#include "main.hpp"
diff --git a/src/boost/libs/hana/test/identity/monad.flatten_mcd.cpp b/src/boost/libs/hana/test/identity/monad.flatten_mcd.cpp
new file mode 100644
index 00000000..3ff28218
--- /dev/null
+++ b/src/boost/libs/hana/test/identity/monad.flatten_mcd.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_MONAD_FLATTEN_MCD
+#include "main.hpp"
diff --git a/src/boost/libs/hana/test/if_/non_copyable.cpp b/src/boost/libs/hana/test/if_/non_copyable.cpp
new file mode 100644
index 00000000..0de09ee4
--- /dev/null
+++ b/src/boost/libs/hana/test/if_/non_copyable.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/bool.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/fwd/not.hpp>
+#include <boost/hana/fwd/while.hpp>
+#include <boost/hana/if.hpp>
+namespace hana = boost::hana;
+
+
+// This test makes sure that if_ can be used with non-copyable branches.
+
+template <bool Value>
+struct Boolean { };
+
+namespace boost { namespace hana {
+ template <bool Value>
+ struct while_impl<Boolean<Value>> {
+ // Not implemented
+ };
+
+ template <bool Value>
+ struct not_impl<Boolean<Value>> {
+ // Not implemented
+ };
+
+ template <bool Value>
+ struct eval_if_impl<Boolean<Value>> {
+ template <typename Cond, typename Then, typename Else>
+ static constexpr decltype(auto) apply(Cond const&, Then&& t, Else&& e) {
+ return hana::eval_if(hana::bool_c<Value>, static_cast<Then&&>(t),
+ static_cast<Else&&>(e));
+ }
+ };
+}}
+
+template <int v>
+struct NonCopyable {
+ static constexpr int value = v;
+ NonCopyable() = default;
+ NonCopyable(NonCopyable const&) = delete;
+ NonCopyable(NonCopyable&&) = default;
+
+ NonCopyable& operator=(NonCopyable const&) = delete;
+ NonCopyable& operator=(NonCopyable&&) = default;
+};
+
+static_assert(hana::if_(Boolean<true>{}, NonCopyable<3>{}, NonCopyable<4>{}).value == 3, "");
+static_assert(hana::if_(Boolean<false>{}, NonCopyable<3>{}, NonCopyable<4>{}).value == 4, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/index_if.cpp b/src/boost/libs/hana/test/index_if.cpp
new file mode 100644
index 00000000..b899f0ca
--- /dev/null
+++ b/src/boost/libs/hana/test/index_if.cpp
@@ -0,0 +1,31 @@
+// 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/index_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <cstddef>
+#include <support/counter.hpp>
+
+namespace hana = boost::hana;
+
+
+int main() {
+ // Tests hana::index_if on an infinite iterable
+ constexpr Counter<> c{};
+ auto pred = [](auto i) {
+ return [=](auto x) {
+ return hana::bool_c<decltype(x)::value == decltype(i)::value>;
+ };
+ };
+
+ static_assert(hana::value(decltype(hana::index_if(c, pred(hana::size_c<0>)).value()){}) == 0, "");
+ static_assert(hana::value(decltype(hana::index_if(c, pred(hana::size_c<1>)).value()){}) == 1, "");
+ static_assert(hana::value(decltype(hana::index_if(c, pred(hana::size_c<2>)).value()){}) == 2, "");
+ static_assert(hana::value(decltype(hana::index_if(c, pred(hana::size_c<3>)).value()){}) == 3, "");
+ static_assert(hana::value(decltype(hana::index_if(c, pred(hana::size_c<4>)).value()){}) == 4, "");
+ static_assert(hana::value(decltype(hana::index_if(c, pred(hana::size_c<5>)).value()){}) == 5, "");
+ static_assert(hana::value(decltype(hana::index_if(c, pred(hana::size_c<6>)).value()){}) == 6, "");
+}
diff --git a/src/boost/libs/hana/test/integral_constant/arithmetic.cpp b/src/boost/libs/hana/test/integral_constant/arithmetic.cpp
new file mode 100644
index 00000000..5968ebe3
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/arithmetic.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/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/euclidean_ring.hpp>
+#include <laws/group.hpp>
+#include <laws/monoid.hpp>
+#include <laws/ring.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto ints = hana::make_tuple(
+ hana::int_c<-10>,
+ hana::int_c<-2>,
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<3>,
+ hana::int_c<4>
+ );
+
+ hana::test::TestMonoid<hana::integral_constant_tag<int>>{ints};
+ hana::test::TestGroup<hana::integral_constant_tag<int>>{ints};
+ hana::test::TestRing<hana::integral_constant_tag<int>>{ints};
+ hana::test::TestEuclideanRing<hana::integral_constant_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/integral_constant/comparable.cpp b/src/boost/libs/hana/test/integral_constant/comparable.cpp
new file mode 100644
index 00000000..a9677341
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/comparable.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/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto ints = hana::make_tuple(
+ hana::int_c<-10>,
+ hana::int_c<-2>,
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<3>,
+ hana::int_c<4>
+ );
+
+ hana::test::TestComparable<hana::integral_constant_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/integral_constant/constant.cpp b/src/boost/libs/hana/test/integral_constant/constant.cpp
new file mode 100644
index 00000000..5ef1248c
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/constant.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/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/value.hpp>
+
+#include <laws/constant.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // value
+ static_assert(hana::value(hana::integral_c<int, 0>) == 0, "");
+ static_assert(hana::value(hana::integral_c<int, 1>) == 1, "");
+
+
+ // laws
+ hana::test::TestConstant<hana::integral_constant_tag<int>>{
+ hana::make_tuple(
+ hana::int_c<-10>,
+ hana::int_c<-2>,
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<3>,
+ hana::int_c<4>
+ ),
+ hana::tuple_t<int, long, long long>
+ };
+
+ hana::test::TestConstant<hana::integral_constant_tag<bool>>{
+ hana::make_tuple(
+ hana::true_c, hana::false_c
+ ),
+ hana::tuple_t<bool>
+ };
+}
diff --git a/src/boost/libs/hana/test/integral_constant/constexpr_init.cpp b/src/boost/libs/hana/test/integral_constant/constexpr_init.cpp
new file mode 100644
index 00000000..0656eb6d
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/constexpr_init.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/bool.hpp>
+#include <boost/hana/integral_constant.hpp>
+namespace hana = boost::hana;
+
+
+/*
+When we use `int_<...>` in a template, Clang 3.5 says:
+
+--------------------------------
+include/boost/hana/integral_constant.hpp:80:20: error: constexpr variable 'int_<1>' must be initialized by a constant expression
+ constexpr auto int_ = integral<int, i>;
+ ^ ~~~~~~~~~~~~~~~~
+test/integral/constexpr_bug.cpp:41:37: note: in instantiation of variable template specialization 'boost::hana::int_' requested here
+constexpr auto check_int() { return int_<1>; }
+ ^
+include/boost/hana/integral_constant.hpp:80:27: note: subexpression not valid in a constant expression
+ constexpr auto int_ = integral<int, i>;
+ ^
+include/boost/hana/integral_constant.hpp:80:27: note: in call to 'integral_type(integral)'
+--------------------------------
+
+if we define int_ & friends like
+
+ template <int i>
+ constexpr auto int_ = integral<int, i>;
+
+Instead, we do
+
+ template <int i>
+ constexpr decltype(integral<int, i>) int_{};
+
+which is equivalent but uglier. Note that everything works just fine when
+we're not in a template.
+*/
+
+template <typename T>
+constexpr auto check_int() { return hana::int_c<1>; }
+
+template <typename T>
+constexpr auto check_true() { return hana::true_c; }
+
+template <typename T>
+constexpr auto check_size_t() { return hana::size_c<0>; }
+
+
+int main() { }
diff --git a/src/boost/libs/hana/test/integral_constant/github_354.cpp b/src/boost/libs/hana/test/integral_constant/github_354.cpp
new file mode 100644
index 00000000..33ce2f37
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/github_354.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/bool.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/integral_constant.hpp>
+namespace hana = boost::hana;
+
+
+static_assert(hana::is_convertible<hana::bool_<true>, bool>::value, "");
+static_assert(hana::to<bool>(hana::bool_c<true>) == true, "");
+
+static_assert(hana::is_convertible<hana::integral_constant<int, 1>, int>::value, "");
+static_assert(hana::to<int>(hana::integral_c<int, 1>) == 1, "");
+
+static_assert(hana::is_convertible<hana::integral_constant<long, 1l>, long>::value, "");
+static_assert(hana::to<long>(hana::integral_c<long, 1l>) == 1l, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/integral_constant/hash.cpp b/src/boost/libs/hana/test/integral_constant/hash.cpp
new file mode 100644
index 00000000..59cf0705
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/hash.cpp
@@ -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)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/config.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>
+namespace hana = boost::hana;
+
+
+int main() {
+ // Unsigned integral constants should hash to `unsigned long long`
+ {
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<unsigned char, 10>),
+ hana::type_c<hana::integral_constant<unsigned long long, 10>>
+ ));
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<unsigned short, 10>),
+ hana::type_c<hana::integral_constant<unsigned long long, 10>>
+ ));
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<unsigned int, 10>),
+ hana::type_c<hana::integral_constant<unsigned long long, 10>>
+ ));
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<unsigned long, 10>),
+ hana::type_c<hana::integral_constant<unsigned long long, 10>>
+ ));
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<unsigned long long, 10>),
+ hana::type_c<hana::integral_constant<unsigned long long, 10>>
+ ));
+ }
+
+ // Signed integral constants should hash to `signed long long`
+ {
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<signed char, 10>),
+ hana::type_c<hana::integral_constant<signed long long, 10>>
+ ));
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<signed short, 10>),
+ hana::type_c<hana::integral_constant<signed long long, 10>>
+ ));
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<signed int, 10>),
+ hana::type_c<hana::integral_constant<signed long long, 10>>
+ ));
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<signed long, 10>),
+ hana::type_c<hana::integral_constant<signed long long, 10>>
+ ));
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<signed long long, 10>),
+ hana::type_c<hana::integral_constant<signed long long, 10>>
+ ));
+ }
+
+ // `char` should hash to either `signed long long` or `unsigned long long`,
+ // depending on its signedness
+ {
+ using T = std::conditional_t<
+ std::is_signed<char>::value,
+ signed long long,
+ unsigned long long
+ >;
+
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::integral_c<char, 10>),
+ hana::type_c<hana::integral_constant<T, 10>>
+ ));
+ }
+
+ // Pointers to members should hash to themselves.
+ // This test is disabled in pre-C++17, because pointers to non-static
+ // data members can't be used as non-type template arguments before that.
+ // See http://stackoverflow.com/q/35398848/627587.
+ {
+#if __cplusplus > 201402L
+
+ struct Foo { int bar; };
+ constexpr auto x = hana::integral_constant<int Foo::*, &Foo::bar>{};
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(x),
+ hana::type_c<hana::integral_constant<int Foo::*, &Foo::bar>>
+ ));
+
+#endif
+ }
+
+ // Booleans should hash to themselves
+ {
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::true_c),
+ hana::type_c<hana::true_>
+ ));
+
+ BOOST_HANA_CONSTANT_ASSERT(hana::equal(
+ hana::hash(hana::false_c),
+ hana::type_c<hana::false_>
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/integral_constant/hashable.cpp b/src/boost/libs/hana/test/integral_constant/hashable.cpp
new file mode 100644
index 00000000..5c31355d
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/hashable.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/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/hashable.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto ints = hana::make_tuple(
+ hana::integral_constant<char, 42>{}
+ , hana::integral_constant<signed char, 42>{}
+ , hana::integral_constant<signed short, 42>{}
+ , hana::integral_constant<signed int, 42>{}
+ , hana::integral_constant<signed long, 42>{}
+ , hana::integral_constant<unsigned char, 42>{}
+ , hana::integral_constant<unsigned short, 42>{}
+ , hana::integral_constant<unsigned int, 42>{}
+ , hana::integral_constant<unsigned long, 42>{}
+ );
+
+ hana::test::TestHashable<hana::integral_constant_tag<void>>{ints};
+}
diff --git a/src/boost/libs/hana/test/integral_constant/logical.cpp b/src/boost/libs/hana/test/integral_constant/logical.cpp
new file mode 100644
index 00000000..70641d37
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/logical.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/eval_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/logical.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // eval_if
+ {
+ auto t = [](auto) { return hana::test::ct_eq<3>{}; };
+ auto e = [](auto) { return hana::test::ct_eq<4>{}; };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval_if(hana::true_c, t, e),
+ hana::test::ct_eq<3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval_if(hana::false_c, t, e),
+ hana::test::ct_eq<4>{}
+ ));
+ }
+
+ // not_
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::not_(hana::true_c),
+ hana::false_c
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::not_(hana::false_c),
+ hana::true_c
+ ));
+ }
+
+ // laws
+ hana::test::TestLogical<hana::integral_constant_tag<int>>{hana::make_tuple(
+ hana::int_c<-2>, hana::int_c<0>, hana::int_c<1>, hana::int_c<3>
+ )};
+
+ hana::test::TestLogical<hana::integral_constant_tag<bool>>{hana::make_tuple(
+ hana::false_c, hana::true_c
+ )};
+}
diff --git a/src/boost/libs/hana/test/integral_constant/operators.cpp b/src/boost/libs/hana/test/integral_constant/operators.cpp
new file mode 100644
index 00000000..33919858
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/operators.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/integral_constant.hpp>
+
+#include <boost/hana/and.hpp>
+#include <boost/hana/div.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/greater_equal.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/less_equal.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/negate.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/or.hpp>
+#include <boost/hana/plus.hpp>
+namespace hana = boost::hana;
+
+
+// Arithmetic operators
+BOOST_HANA_CONSTANT_CHECK(+hana::int_c<1> == hana::int_c<1>);
+BOOST_HANA_CONSTANT_CHECK(-hana::int_c<1> == hana::int_c<-1>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<1> + hana::int_c<2> == hana::int_c<3>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<1> - hana::int_c<2> == hana::int_c<-1>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<3> * hana::int_c<2> == hana::int_c<6>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<6> / hana::int_c<3> == hana::int_c<2>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<6> % hana::int_c<4> == hana::int_c<2>);
+BOOST_HANA_CONSTANT_CHECK(~hana::int_c<6> == hana::int_c<~6>);
+BOOST_HANA_CONSTANT_CHECK((hana::int_c<6> & hana::int_c<3>) == hana::int_c<6 & 3>);
+BOOST_HANA_CONSTANT_CHECK((hana::int_c<4> | hana::int_c<2>) == hana::int_c<4 | 2>);
+BOOST_HANA_CONSTANT_CHECK((hana::int_c<6> ^ hana::int_c<3>) == hana::int_c<6 ^ 3>);
+BOOST_HANA_CONSTANT_CHECK((hana::int_c<6> << hana::int_c<3>) == hana::int_c<(6 << 3)>);
+BOOST_HANA_CONSTANT_CHECK((hana::int_c<6> >> hana::int_c<3>) == hana::int_c<(6 >> 3)>);
+
+// Comparison operators
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<0> == hana::int_c<0>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<1> != hana::int_c<0>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<0> < hana::int_c<1>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<0> <= hana::int_c<1>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<0> <= hana::int_c<0>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<1> > hana::int_c<0>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<1> >= hana::int_c<0>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<0> >= hana::int_c<0>);
+
+// Logical operators
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<3> || hana::int_c<0>);
+BOOST_HANA_CONSTANT_CHECK(hana::int_c<3> && hana::int_c<1>);
+BOOST_HANA_CONSTANT_CHECK(!hana::int_c<0>);
+BOOST_HANA_CONSTANT_CHECK(!!hana::int_c<3>);
+
+int main() { }
diff --git a/src/boost/libs/hana/test/integral_constant/orderable.cpp b/src/boost/libs/hana/test/integral_constant/orderable.cpp
new file mode 100644
index 00000000..b32b33c5
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/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/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/orderable.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ constexpr auto ints = hana::make_tuple(
+ hana::int_c<-10>,
+ hana::int_c<-2>,
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<3>,
+ hana::int_c<4>
+ );
+
+ hana::test::TestOrderable<hana::integral_constant_tag<int>>{ints};
+}
diff --git a/src/boost/libs/hana/test/integral_constant/std_api.cpp b/src/boost/libs/hana/test/integral_constant/std_api.cpp
new file mode 100644
index 00000000..95e9d5fe
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/std_api.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/integral_constant.hpp>
+
+#include <cstddef>
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// operator()
+static_assert(hana::size_c<0>() == 0, "");
+static_assert(hana::size_c<1>() == 1, "");
+static_assert(hana::int_c<-3>() == -3, "");
+
+// decltype(operator())
+static_assert(std::is_same<decltype(hana::size_c<0>()), std::size_t>{}, "");
+static_assert(std::is_same<decltype(hana::int_c<-3>()), int>{}, "");
+
+// conversions
+constexpr std::size_t a = hana::size_c<0>, b = hana::size_c<1>;
+static_assert(a == 0 && b == 1, "");
+
+constexpr int c = hana::int_c<0>, d = hana::int_c<-3>;
+static_assert(c == 0 && d == -3, "");
+
+// nested ::value
+static_assert(decltype(hana::int_c<1>)::value == 1, "");
+
+// nested ::type
+static_assert(std::is_same<
+ decltype(hana::int_c<1>)::type,
+ std::remove_cv_t<decltype(hana::int_c<1>)>
+>{}, "");
+
+// nested ::value_type
+static_assert(std::is_same<decltype(hana::int_c<1>)::value_type, int>{}, "");
+
+// inherits from std::integral_constant
+static_assert(std::is_base_of<std::integral_constant<int, 3>,
+ hana::integral_constant<int, 3>>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/integral_constant/tag.cpp b/src/boost/libs/hana/test/integral_constant/tag.cpp
new file mode 100644
index 00000000..35b42020
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/tag.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/core/tag_of.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// Make sure we have the right tag, even when including ext/std/integral_constant.hpp
+static_assert(std::is_same<
+ hana::tag_of_t<hana::integral_constant<int, 10>>,
+ hana::integral_constant_tag<int>
+>{}, "");
+
+struct derived : hana::integral_constant<int, 10> { };
+static_assert(std::is_same<
+ hana::tag_of_t<derived>,
+ hana::integral_constant_tag<int>
+>{}, "");
+
+
+int main() { }
diff --git a/src/boost/libs/hana/test/integral_constant/times.cpp b/src/boost/libs/hana/test/integral_constant/times.cpp
new file mode 100644
index 00000000..51f354fd
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/times.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/core/is_a.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/value.hpp>
+namespace hana = boost::hana;
+
+
+void function() { }
+void function_index(...) { }
+
+int main() {
+ // times member function
+ {
+ int counter = 0;
+ hana::int_c<3>.times([&] { ++counter; });
+ BOOST_HANA_RUNTIME_CHECK(counter == 3);
+
+ // Call .times with a normal function used to fail.
+ hana::int_c<3>.times(function);
+
+ // make sure times can be accessed as a static member function too
+ decltype(hana::int_c<5>)::times([]{ });
+
+ // make sure xxx.times can be used as a function object
+ auto z = hana::int_c<5>.times;
+ (void)z;
+ }
+
+ // times.with_index
+ {
+ int index = 0;
+ hana::int_c<3>.times.with_index([&](auto i) {
+ static_assert(hana::is_an<hana::integral_constant_tag<int>>(i), "");
+ BOOST_HANA_RUNTIME_CHECK(hana::value(i) == index);
+ ++index;
+ });
+
+ // Calling .times.with_index with a normal function used to fail.
+ hana::int_c<3>.times.with_index(function_index);
+
+ // make sure times.with_index can be accessed as a static member
+ // function too
+ auto times = hana::int_c<5>.times;
+ decltype(times)::with_index([](auto) { });
+
+ // make sure xxx.times.with_index can be used as a function object
+ auto z = hana::int_c<5>.times.with_index;
+ (void)z;
+
+ // make sure we're calling the function in the right order
+ int current = 0;
+ hana::int_c<5>.times.with_index([&](auto i) {
+ BOOST_HANA_RUNTIME_CHECK(hana::value(i) == current);
+ ++current;
+ });
+ }
+}
diff --git a/src/boost/libs/hana/test/integral_constant/udl.cpp b/src/boost/libs/hana/test/integral_constant/udl.cpp
new file mode 100644
index 00000000..05b0186f
--- /dev/null
+++ b/src/boost/libs/hana/test/integral_constant/udl.cpp
@@ -0,0 +1,75 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/negate.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+BOOST_HANA_CONSTANT_CHECK(0_c == hana::llong_c<0>);
+BOOST_HANA_CONSTANT_CHECK(1_c == hana::llong_c<1>);
+BOOST_HANA_CONSTANT_CHECK(12_c == hana::llong_c<12>);
+BOOST_HANA_CONSTANT_CHECK(123_c == hana::llong_c<123>);
+BOOST_HANA_CONSTANT_CHECK(1234567_c == hana::llong_c<1234567>);
+BOOST_HANA_CONSTANT_CHECK(-34_c == hana::llong_c<-34>);
+
+
+static_assert(std::is_same<
+ decltype(-1234_c)::value_type,
+ long long
+>{}, "");
+static_assert(-1234_c == -1234ll, "");
+BOOST_HANA_CONSTANT_CHECK(-12_c < 0_c);
+
+
+constexpr auto deadbeef = hana::llong_c<0xDEADBEEF>;
+
+//hexadecimal
+BOOST_HANA_CONSTANT_CHECK(deadbeef == 0xDEADBEEF_c);
+BOOST_HANA_CONSTANT_CHECK(deadbeef == 0xDeAdBeEf_c);
+BOOST_HANA_CONSTANT_CHECK(deadbeef == 0xdeadbeef_c);
+
+//decimal
+BOOST_HANA_CONSTANT_CHECK(deadbeef == hana::llong_c<3735928559>); // test the test
+BOOST_HANA_CONSTANT_CHECK(deadbeef == 3735928559_c);
+
+//binary
+BOOST_HANA_CONSTANT_CHECK(deadbeef == hana::llong_c<0b11011110101011011011111011101111>); // test the test
+BOOST_HANA_CONSTANT_CHECK(deadbeef == 0b11011110101011011011111011101111_c);
+
+//octal
+BOOST_HANA_CONSTANT_CHECK(deadbeef == hana::llong_c<033653337357>); // test the test
+BOOST_HANA_CONSTANT_CHECK(deadbeef == 033653337357_c);
+
+BOOST_HANA_CONSTANT_CHECK(0x0_c == hana::llong_c<0>);
+BOOST_HANA_CONSTANT_CHECK(0b0_c == hana::llong_c<0>);
+BOOST_HANA_CONSTANT_CHECK(00_c == hana::llong_c<0>);
+
+BOOST_HANA_CONSTANT_CHECK(0x1_c == hana::llong_c<1>);
+BOOST_HANA_CONSTANT_CHECK(0b1_c == hana::llong_c<1>);
+BOOST_HANA_CONSTANT_CHECK(01_c == hana::llong_c<1>);
+
+BOOST_HANA_CONSTANT_CHECK(-0x1_c == hana::llong_c<-1>);
+BOOST_HANA_CONSTANT_CHECK(-0b1_c == hana::llong_c<-1>);
+BOOST_HANA_CONSTANT_CHECK(-01_c == hana::llong_c<-1>);
+
+BOOST_HANA_CONSTANT_CHECK(0x10_c == hana::llong_c<16>);
+BOOST_HANA_CONSTANT_CHECK(0b10_c == hana::llong_c<2>);
+BOOST_HANA_CONSTANT_CHECK(010_c == hana::llong_c<8>);
+
+BOOST_HANA_CONSTANT_CHECK(-0x10_c == hana::llong_c<-16>);
+BOOST_HANA_CONSTANT_CHECK(-0b10_c == hana::llong_c<-2>);
+BOOST_HANA_CONSTANT_CHECK(-010_c == hana::llong_c<-8>);
+
+// digit separators
+static_assert(123'456 == 123456, ""); // test the test
+BOOST_HANA_CONSTANT_CHECK(123'456_c == hana::llong_c<123456>);
+
+int main() { }
diff --git a/src/boost/libs/hana/test/issues/clang_20046.cpp b/src/boost/libs/hana/test/issues/clang_20046.cpp
new file mode 100644
index 00000000..7dc68742
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/clang_20046.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/type.hpp>
+namespace hana = boost::hana;
+
+
+template <typename ...> struct F { struct type; };
+struct M { template <typename ...> struct apply { struct type; }; };
+struct T;
+
+int main() {
+ // See http://llvm.org/bugs/show_bug.cgi?id=20046
+ [](auto) { return hana::trait<F>; }(1);
+ [](auto) { return hana::type_c<T>; }(1);
+ [](auto) { return hana::template_<F>; }(1);
+ [](auto) { return hana::metafunction<F>; }(1);
+ [](auto) { return hana::metafunction_class<M>; }(1);
+}
diff --git a/src/boost/libs/hana/test/issues/github_112.cpp b/src/boost/libs/hana/test/issues/github_112.cpp
new file mode 100644
index 00000000..6286cfab
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_112.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/accessors.hpp>
+#include <boost/hana/adapt_struct.hpp>
+#include <boost/hana/define_struct.hpp>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (int, age)
+ );
+};
+
+struct Employee {
+ int age;
+};
+
+BOOST_HANA_ADAPT_STRUCT(Employee, age);
+
+constexpr auto person_members = hana::accessors<Person>();
+constexpr auto employee_members = hana::accessors<Employee>();
+
+int main() {
+ (void)person_members;
+ (void)employee_members;
+}
diff --git a/src/boost/libs/hana/test/issues/github_113.cpp b/src/boost/libs/hana/test/issues/github_113.cpp
new file mode 100644
index 00000000..26156981
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_113.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/adapt_struct.hpp>
+#include <boost/hana/define_struct.hpp>
+namespace hana = boost::hana;
+
+
+struct Person {
+ BOOST_HANA_DEFINE_STRUCT(Person,
+ (int, Person)
+ );
+};
+
+struct Employee {
+ int Employee;
+};
+
+BOOST_HANA_ADAPT_STRUCT(Employee, Employee);
+
+int main() { }
diff --git a/src/boost/libs/hana/test/issues/github_149.cpp b/src/boost/libs/hana/test/issues/github_149.cpp
new file mode 100644
index 00000000..59d8f4d5
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_149.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/map.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+auto opt = hana::just(hana::make_map());
+
+int main() { }
diff --git a/src/boost/libs/hana/test/issues/github_15.cpp b/src/boost/libs/hana/test/issues/github_15.cpp
new file mode 100644
index 00000000..09c8149c
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_15.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/always.hpp>
+
+#include <support/tracked.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <typename T>
+decltype(auto) call_always(T&& x) {
+ return hana::always(std::forward<T>(x))();
+}
+
+int main() {
+ auto copy = call_always(Tracked{1});
+ (void)copy;
+}
diff --git a/src/boost/libs/hana/test/issues/github_165.cpp b/src/boost/libs/hana/test/issues/github_165.cpp
new file mode 100644
index 00000000..2d170df8
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_165.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/tuple.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+constexpr int f() {
+ // copy-assign
+ {
+ hana::tuple<int> xs{1};
+ hana::tuple<long> ys{1};
+ xs = xs;
+ ys = xs;
+ }
+
+ // move-assign
+ {
+ hana::tuple<int> xs{1}, xxs{1};
+ hana::tuple<long> ys{1};
+ xs = std::move(xxs);
+ ys = std::move(xs);
+ }
+
+ return 0;
+}
+
+static_assert(f() == 0, ""); // force f() to be constexpr
+
+
+int main() { }
diff --git a/src/boost/libs/hana/test/issues/github_202.cpp b/src/boost/libs/hana/test/issues/github_202.cpp
new file mode 100644
index 00000000..83a0d636
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_202.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/integral_constant.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <vector>
+namespace hana = boost::hana;
+
+
+using Vector = std::vector<int>;
+
+static_assert(
+ sizeof(hana::tuple<
+ hana::pair<hana::int_<0>, Vector>,
+ hana::pair<hana::int_<1>, Vector>,
+ hana::pair<hana::int_<2>, Vector>,
+ hana::pair<hana::int_<3>, Vector>
+ >)
+ ==
+ sizeof(hana::tuple<Vector, Vector, Vector, Vector>)
+, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/issues/github_221.cpp b/src/boost/libs/hana/test/issues/github_221.cpp
new file mode 100644
index 00000000..5bdd82e5
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_221.cpp
@@ -0,0 +1,452 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/all_of.hpp>
+#include <boost/hana/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/count_if.hpp>
+#include <boost/hana/drop_while.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/tuple.hpp>
+#include <boost/hana/filter.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/functional/id.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/group.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/lexicographical_compare.hpp>
+#include <boost/hana/maximum.hpp>
+#include <boost/hana/minimum.hpp>
+#include <boost/hana/none_of.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/partition.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/remove_if.hpp>
+#include <boost/hana/replace_if.hpp>
+#include <boost/hana/sort.hpp>
+#include <boost/hana/span.hpp>
+#include <boost/hana/take_while.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unique.hpp>
+#include <boost/hana/while.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto increment = hana::partial(hana::plus, hana::int_c<1>);
+
+int main() {
+
+ // adjust_if
+ {
+ constexpr auto x = hana::adjust_if(hana::make_tuple(hana::int_c<0>), hana::id, increment);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::make_tuple(hana::int_c<0>)));
+
+ constexpr auto y = hana::adjust_if(hana::make_tuple(hana::int_c<1>), hana::id, increment);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(y, hana::make_tuple(hana::int_c<2>)));
+
+ constexpr auto z = hana::adjust_if(hana::make_tuple(hana::int_c<3>), hana::id, increment);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::make_tuple(hana::int_c<4>)));
+
+ constexpr auto l = hana::adjust_if(hana::tuple_c<int, 3>, hana::id, increment);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(l, hana::make_tuple(hana::int_c<4>)));
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::adjust_if(hana::tuple_c<int, 3>, hana::id, increment);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::make_tuple(hana::int_c<4>)));
+ }
+
+ // all_of
+ {
+ BOOST_HANA_CONSTANT_CHECK(!hana::all_of(hana::make_tuple(hana::int_c<0>), hana::id));
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(hana::make_tuple(hana::int_c<1>), hana::id));
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(hana::make_tuple(hana::int_c<3>), hana::id));
+ // test with lvalue
+ BOOST_HANA_CONSTANT_CHECK(hana::all_of(hana::tuple_c<int, 3>, hana::id));
+ }
+
+ // any_of
+ {
+ BOOST_HANA_CONSTANT_CHECK(!hana::any_of(hana::make_tuple(hana::int_c<0>), hana::id));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(hana::make_tuple(hana::int_c<1>), hana::id));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(hana::make_tuple(hana::int_c<3>), hana::id));
+ // test with lvalue
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(hana::tuple_c<int, 3>, hana::id));
+ }
+
+ // count_if
+ {
+ constexpr auto x = hana::count_if(hana::make_tuple(hana::int_c<0>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::size_c<0>));
+
+ constexpr auto y = hana::count_if(hana::make_tuple(hana::int_c<1>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(y, hana::size_c<1>));
+
+ constexpr auto z = hana::count_if(hana::make_tuple(hana::int_c<3>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::size_c<1>));
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::count_if(hana::tuple_c<int, 3>, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::size_c<1>));
+ }
+
+ // drop_while
+ {
+ constexpr auto x = hana::drop_while(
+ hana::make_tuple(hana::int_c<0>), hana::id
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x,
+ hana::make_tuple(hana::int_c<0>)
+ )
+ );
+ constexpr auto y = hana::drop_while(
+ hana::make_tuple(hana::int_c<1>, hana::int_c<3>, hana::int_c<0>), hana::id
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(y,
+ hana::make_tuple(hana::int_c<0>)
+ )
+ );
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::drop_while(
+ hana::tuple_c<int, 1, 3, 0>, hana::id
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x,
+ hana::make_tuple(hana::int_c<0>)
+ )
+ );
+ }
+
+ // filter
+ {
+ constexpr auto x = hana::filter(hana::make_tuple(hana::int_c<0>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::make_tuple()));
+
+ constexpr auto y = hana::filter(hana::make_tuple(hana::int_c<1>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(y, hana::make_tuple(hana::int_c<1>)));
+
+ constexpr auto z = hana::filter(hana::make_tuple(hana::int_c<3>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::make_tuple(hana::int_c<3>)));
+
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::filter(hana::tuple_c<int, 3>, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::make_tuple(hana::int_c<3>)));
+ }
+
+ // find_if
+ {
+ constexpr auto x = hana::find_if(hana::make_tuple(hana::int_c<0>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::nothing));
+
+ constexpr auto y = hana::find_if(hana::make_tuple(hana::int_c<1>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(y, hana::just(hana::int_c<1>)));
+
+ constexpr auto z = hana::find_if(hana::make_tuple(hana::int_c<3>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::just(hana::int_c<3>)));
+ }
+ {
+ // test with lvalue
+ constexpr auto z = hana::find_if(hana::tuple_c<int, 3>, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::just(hana::int_c<3>)));
+ }
+ {
+ // test with std::tuple (for default implementation of find_if)
+ constexpr auto x = hana::find_if(std::make_tuple(hana::int_c<0>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::nothing));
+
+ constexpr auto y = hana::find_if(std::make_tuple(hana::int_c<1>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(y, hana::just(hana::int_c<1>)));
+
+ constexpr auto z = hana::find_if(std::make_tuple(hana::int_c<3>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::just(hana::int_c<3>)));
+ }
+ {
+ // test with lvalue
+ constexpr auto seq = std::make_tuple(hana::int_c<3>);
+ constexpr auto x = hana::find_if(seq, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::just(hana::int_c<3>)));
+ }
+
+ // group
+ {
+ constexpr auto x = hana::group(
+ hana::make_tuple(
+ hana::int_c<0>,
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<1>,
+ hana::int_c<2>
+ ),
+ hana::plus
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x,
+ hana::make_tuple(
+ hana::tuple_c<int, 0>,
+ hana::tuple_c<int, 0, 1, 1, 2>
+ )
+ )
+ );
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::group(hana::tuple_c<int, 0, 0, 1, 1, 2>, hana::plus);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x,
+ hana::make_tuple(
+ hana::tuple_c<int, 0>,
+ hana::tuple_c<int, 0, 1, 1, 2>
+ )
+ )
+ );
+ }
+
+ // lexicographical_compare
+ {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::lexicographical_compare(
+ hana::make_tuple(hana::int_c<0>, hana::int_c<0>),
+ hana::make_tuple(hana::int_c<0>, hana::int_c<3>),
+ hana::plus
+ )
+ );
+ }
+ {
+ // test with lvalue
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::lexicographical_compare(
+ hana::tuple_c<int, 0, 0>,
+ hana::tuple_c<int, 0, 3>,
+ hana::plus
+ )
+ );
+ }
+
+ // maximum
+ {
+ constexpr auto x = hana::maximum(
+ hana::make_tuple(
+ hana::int_c<0>,
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<3>,
+ hana::int_c<2>
+ ),
+ hana::plus
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::int_c<2>));
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::maximum(hana::tuple_c<int, 0, 0, 1, 3, 2>, hana::plus);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::int_c<2>));
+ }
+
+ // minimum
+ {
+ constexpr auto x = hana::minimum(
+ hana::make_tuple(
+ hana::int_c<0>,
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<3>,
+ hana::int_c<2>
+ ),
+ hana::plus
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::int_c<0>));
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::minimum(hana::tuple_c<int, 0, 0, 1, 3, 2>, hana::plus);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::int_c<0>));
+ }
+
+ // none_of
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::none_of(hana::make_tuple(hana::int_c<0>), hana::id));
+ BOOST_HANA_CONSTANT_CHECK(!hana::none_of(hana::make_tuple(hana::int_c<1>), hana::id));
+ BOOST_HANA_CONSTANT_CHECK(!hana::none_of(hana::make_tuple(hana::int_c<3>), hana::id));
+ }
+ {
+ // test with lvalue
+ BOOST_HANA_CONSTANT_CHECK(hana::none_of(hana::tuple_c<int, 0>, hana::id));
+ BOOST_HANA_CONSTANT_CHECK(!hana::none_of(hana::tuple_c<int, 1>, hana::id));
+ BOOST_HANA_CONSTANT_CHECK(!hana::none_of(hana::tuple_c<int, 3>, hana::id));
+ }
+
+ // partition
+ {
+ constexpr auto x = hana::partition(
+ hana::make_tuple(
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<3>
+ ),
+ hana::id
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x,
+ hana::make_pair(
+ hana::tuple_c<int, 1, 3>,
+ hana::tuple_c<int, 0>
+ )
+ )
+ );
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::partition(hana::tuple_c<int, 0, 1, 3>, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x,
+ hana::make_pair(
+ hana::tuple_c<int, 1, 3>,
+ hana::tuple_c<int, 0>
+ )
+ )
+ );
+ }
+
+ // remove_if
+ {
+ constexpr auto x = hana::remove_if(hana::make_tuple(hana::int_c<0>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::make_tuple(hana::int_c<0>)));
+
+ constexpr auto y = hana::remove_if(hana::make_tuple(hana::int_c<1>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(y, hana::make_tuple()));
+
+ constexpr auto z = hana::remove_if(hana::make_tuple(hana::int_c<3>), hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::make_tuple()));
+ }
+ {
+ // test with lvalue
+ constexpr auto z = hana::remove_if(hana::tuple_c<int, 3>, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::make_tuple()));
+ }
+
+ // replace_if
+ {
+ constexpr auto x = hana::replace_if(
+ hana::make_tuple(hana::int_c<0>),
+ hana::id,
+ hana::int_c<42>
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::make_tuple(hana::int_c<0>)));
+
+ constexpr auto y = hana::replace_if(
+ hana::make_tuple(hana::int_c<1>),
+ hana::id,
+ hana::int_c<42>
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(y, hana::make_tuple(hana::int_c<42>)));
+
+ constexpr auto z = hana::replace_if(
+ hana::make_tuple(hana::int_c<3>),
+ hana::id,
+ hana::int_c<42>
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::make_tuple(hana::int_c<42>)));
+ }
+ {
+ // test with lvalue
+ constexpr auto z = hana::replace_if(
+ hana::tuple_c<int, 3>,
+ hana::id,
+ hana::int_c<42>
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(z, hana::make_tuple(hana::int_c<42>)));
+ }
+
+ // sort
+ {
+ constexpr auto x = hana::sort(
+ hana::make_tuple(
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<2>
+ ),
+ hana::plus);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::tuple_c<int, 2, 1, 0>));
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::sort(hana::tuple_c<int, 0, 1, 2>, hana::plus);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::tuple_c<int, 2, 1, 0>));
+ }
+ // span
+ {
+ constexpr auto x = hana::span(
+ hana::make_tuple(
+ hana::int_c<2>,
+ hana::int_c<1>,
+ hana::int_c<0>
+ ),
+ hana::id
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::equal(x,
+ hana::make_pair(
+ hana::tuple_c<int, 2, 1>,
+ hana::tuple_c<int, 0>
+ )
+ )
+ );
+ }
+ {
+ // test with an lvalue
+ constexpr auto x = hana::span(hana::tuple_c<int, 2, 1, 0>, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::equal(x,
+ hana::make_pair(
+ hana::tuple_c<int, 2, 1>,
+ hana::tuple_c<int, 0>
+ )
+ )
+ );
+ }
+
+ // take_while
+ {
+ constexpr auto x = hana::take_while(
+ hana::make_tuple(
+ hana::int_c<2>,
+ hana::int_c<1>,
+ hana::int_c<0>
+ ),
+ hana::id
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::tuple_c<int, 2, 1>));
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::take_while(hana::tuple_c<int, 2, 1, 0>, hana::id);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::tuple_c<int, 2, 1>));
+ }
+
+ // unique
+ {
+ constexpr auto x = hana::unique(
+ hana::make_tuple(
+ hana::int_c<0>,
+ hana::int_c<0>,
+ hana::int_c<1>,
+ hana::int_c<2>
+ ),
+ hana::plus
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::tuple_c<int, 0, 0>));
+ }
+ {
+ // test with lvalue
+ constexpr auto x = hana::unique(hana::tuple_c<int, 0, 0, 1, 2>, hana::plus);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::tuple_c<int, 0, 0>));
+ }
+
+ // while
+ {
+ constexpr auto x = hana::while_(hana::id, hana::int_c<-3>, increment);
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(x, hana::int_c<0>));
+ }
+}
diff --git a/src/boost/libs/hana/test/issues/github_234.cpp b/src/boost/libs/hana/test/issues/github_234.cpp
new file mode 100644
index 00000000..bf44412f
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_234.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/contains.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/set.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ auto set = hana::make_set(hana::int_c<1>, hana::integral_c<signed char, 'x'>);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(set, hana::int_c<1>));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(set, hana::integral_c<signed char, 'x'>));
+ }
+
+ {
+ auto map = hana::make_map(
+ hana::make_pair(hana::int_c<1>, 1),
+ hana::make_pair(hana::integral_c<signed char, 'x'>, 'x')
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(map, hana::int_c<1>));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(map, hana::integral_c<signed char, 'x'>));
+ }
+}
diff --git a/src/boost/libs/hana/test/issues/github_252.cpp b/src/boost/libs/hana/test/issues/github_252.cpp
new file mode 100644
index 00000000..34df48d2
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_252.cpp
@@ -0,0 +1,38 @@
+// Copyright Sergey Nizovtsev 2016
+// Distributed under the 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/functional/partial.hpp>
+#include <boost/hana/product.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/traits.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+namespace hana = boost::hana;
+
+int main() {
+ constexpr auto type = hana::type_c<int[2][3][4]>;
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::is_an<hana::integral_constant_tag<size_t>>(
+ hana::traits::extent(type, hana::uint_c<1>)
+ )
+ );
+
+ // Check that we can multiple extents in size_t's ring
+ hana::product<hana::integral_constant_tag<size_t>>(
+ hana::transform(
+ hana::to_tuple(
+ hana::make_range(
+ hana::size_c<0>,
+ hana::traits::rank(type)
+ )
+ ),
+ hana::partial(hana::traits::extent, type)
+ )
+ );
+}
diff --git a/src/boost/libs/hana/test/issues/github_260.cpp b/src/boost/libs/hana/test/issues/github_260.cpp
new file mode 100644
index 00000000..8b242856
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_260.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/functional/curry.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/functional/reverse_partial.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <tuple>
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct DefaultConstructible {
+ DefaultConstructible() = default;
+};
+
+int main() {
+ auto curry_tuple = hana::make_tuple(
+ std::make_tuple(hana::curry<2>(DefaultConstructible{})(DefaultConstructible{}))
+ );
+
+ auto partial_tuple = hana::make_tuple(
+ std::make_tuple(hana::partial(DefaultConstructible{}, DefaultConstructible{}))
+ );
+
+ auto reverse_partial_tuple = hana::make_tuple(
+ std::make_tuple(hana::reverse_partial(DefaultConstructible{}, DefaultConstructible{}))
+ );
+
+ static_assert(std::is_default_constructible<decltype(curry_tuple)>::value, "");
+ static_assert(std::is_default_constructible<decltype(partial_tuple)>::value, "");
+ static_assert(std::is_default_constructible<decltype(reverse_partial_tuple)>::value, "");
+}
diff --git a/src/boost/libs/hana/test/issues/github_266.cpp b/src/boost/libs/hana/test/issues/github_266.cpp
new file mode 100644
index 00000000..52059da0
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_266.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/bool.hpp>
+#include <boost/hana/experimental/types.hpp>
+#include <boost/hana/replace_if.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct predicate { hana::true_ operator()(...) const; };
+
+int main() {
+ auto types = hana::experimental::types<void, void>{};
+ hana::replace_if(types, predicate{}, hana::type<struct anything>{});
+}
diff --git a/src/boost/libs/hana/test/issues/github_269.cpp b/src/boost/libs/hana/test/issues/github_269.cpp
new file mode 100644
index 00000000..242684aa
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_269.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/concept.hpp>
+namespace hana = boost::hana;
+
+
+using T = int;
+
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Applicative<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Comonad<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Comparable<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Constant<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::EuclideanRing<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Foldable<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Functor<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Group<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Hashable<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::IntegralConstant<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Iterable<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Logical<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Metafunction<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Monad<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::MonadPlus<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Monoid<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Orderable<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Product<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Ring<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Searchable<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Sequence<T>>{});
+BOOST_HANA_CONSTANT_CHECK(hana::IntegralConstant<hana::Struct<T>>{});
+
+int main() { }
diff --git a/src/boost/libs/hana/test/issues/github_297.cpp b/src/boost/libs/hana/test/issues/github_297.cpp
new file mode 100644
index 00000000..40bf403b
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_297.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/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+
+#include <memory>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto map = hana::make_map(
+ hana::make_pair(hana::int_c<0>, 123),
+ hana::make_pair(hana::int_c<1>, 456)
+ );
+
+ std::unique_ptr<decltype(map)> p1{}, p2{};
+ using std::swap;
+ swap(p1, p2);
+}
diff --git a/src/boost/libs/hana/test/issues/github_31.cpp b/src/boost/libs/hana/test/issues/github_31.cpp
new file mode 100644
index 00000000..ddbdefcd
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_31.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/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/fwd/at.hpp>
+#include <boost/hana/fwd/drop_front.hpp>
+#include <boost/hana/fwd/is_empty.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+// A simple infinite Iterable.
+template <int i>
+struct counter { };
+
+namespace boost { namespace hana {
+ template <int i>
+ struct at_impl<counter<i>> {
+ template <typename N>
+ static constexpr auto apply(counter<i>, N const&) {
+ return hana::int_c<i + N::value>;
+ }
+ };
+
+ template <int i>
+ struct drop_front_impl<counter<i>> {
+ template <typename N>
+ static constexpr auto apply(counter<i>, N) { return counter<i + N::value>{}; }
+ };
+
+ template <int i>
+ struct is_empty_impl<counter<i>> {
+ static constexpr auto apply(counter<i>) { return hana::false_c; }
+ };
+}}
+
+
+int main() {
+ // find_if and any_of should short-circuit and stop even though the
+ // Iterable is infinite.
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(counter<1>{}, hana::equal.to(hana::int_c<4>)));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(counter<1>{}, hana::equal.to(hana::int_c<4>)),
+ hana::just(hana::int_c<4>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/issues/github_331.cpp b/src/boost/libs/hana/test/issues/github_331.cpp
new file mode 100644
index 00000000..246f3943
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_331.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/at.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+// In GitHub issue #331, we noticed that `first` and `second` could sometimes
+// return the wrong member in case of nested pairs. This is due to the way we
+// inherit from base classes to enable EBO. We also check for `basic_tuple`,
+// because both are implemented similarly.
+
+int main() {
+ {
+ using Nested = hana::pair<hana::int_<1>, hana::int_<2>>;
+ using Pair = hana::pair<hana::int_<0>, Nested>;
+ Pair pair{};
+
+ auto a = hana::first(pair);
+ static_assert(std::is_same<decltype(a), hana::int_<0>>{}, "");
+
+ auto b = hana::second(pair);
+ static_assert(std::is_same<decltype(b), Nested>{}, "");
+ }
+
+ {
+ using Nested = hana::basic_tuple<hana::int_<1>, hana::int_<2>>;
+ using Tuple = hana::basic_tuple<hana::int_<0>, Nested>;
+ Tuple tuple{};
+
+ auto a = hana::at_c<0>(tuple);
+ static_assert(std::is_same<decltype(a), hana::int_<0>>{}, "");
+
+ auto b = hana::at_c<1>(tuple);
+ static_assert(std::is_same<decltype(b), Nested>{}, "");
+ }
+
+ // Original test case submitted by Vittorio Romeo
+ {
+ hana::pair<hana::int_<1>, hana::bool_<false>> p{};
+ auto copy = hana::make_pair(hana::int_c<0>, p);
+ auto move = hana::make_pair(hana::int_c<0>, std::move(p));
+
+ copy = move; // copy assign
+ copy = std::move(move); // move assign
+ }
+}
diff --git a/src/boost/libs/hana/test/issues/github_362.cpp b/src/boost/libs/hana/test/issues/github_362.cpp
new file mode 100644
index 00000000..885d386b
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_362.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/integral_constant.hpp>
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+
+static constexpr auto x = 4'321'000_c;
+static_assert(decltype(x)::value == 4'321'000, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/issues/github_365.cpp b/src/boost/libs/hana/test/issues/github_365.cpp
new file mode 100644
index 00000000..63d756f4
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_365.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/accessors.hpp>
+#include <boost/hana/adapt_struct.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/define_struct.hpp>
+#include <boost/hana/second.hpp>
+
+#include <cstddef>
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+//
+// This test makes sure that `hana::accessors` does not decay C-style array
+// members to pointers.
+//
+
+struct Foo {
+ float array[3];
+};
+
+BOOST_HANA_ADAPT_STRUCT(Foo,
+ array
+);
+
+template <std::size_t N>
+using FloatArray = float[N];
+
+struct Bar {
+ BOOST_HANA_DEFINE_STRUCT(Bar,
+ (FloatArray<3>, array)
+ );
+};
+
+int main() {
+ {
+ Foo foo = {{1.0f, 2.0f, 3.0f}};
+ auto accessors = hana::accessors<Foo>();
+ auto get_array = hana::second(hana::at_c<0>(accessors));
+ static_assert(std::is_same<decltype(get_array(foo)), float(&)[3]>{}, "");
+ float (&array)[3] = get_array(foo);
+ BOOST_HANA_RUNTIME_CHECK(array[0] == 1.0f);
+ BOOST_HANA_RUNTIME_CHECK(array[1] == 2.0f);
+ BOOST_HANA_RUNTIME_CHECK(array[2] == 3.0f);
+ }
+
+ {
+ Bar bar = {{1.0f, 2.0f, 3.0f}};
+ auto accessors = hana::accessors<Bar>();
+ auto get_array = hana::second(hana::at_c<0>(accessors));
+ static_assert(std::is_same<decltype(get_array(bar)), float(&)[3]>{}, "");
+ float (&array)[3] = get_array(bar);
+ BOOST_HANA_RUNTIME_CHECK(array[0] == 1.0f);
+ BOOST_HANA_RUNTIME_CHECK(array[1] == 2.0f);
+ BOOST_HANA_RUNTIME_CHECK(array[2] == 3.0f);
+ }
+}
diff --git a/src/boost/libs/hana/test/issues/github_75/tu1.cpp b/src/boost/libs/hana/test/issues/github_75/tu1.cpp
new file mode 100644
index 00000000..d4b570f7
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_75/tu1.cpp
@@ -0,0 +1,7 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/test/issues/github_75/tu2.cpp b/src/boost/libs/hana/test/issues/github_75/tu2.cpp
new file mode 100644
index 00000000..68833766
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_75/tu2.cpp
@@ -0,0 +1,5 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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>
diff --git a/src/boost/libs/hana/test/issues/github_91.cpp b/src/boost/libs/hana/test/issues/github_91.cpp
new file mode 100644
index 00000000..88f1832e
--- /dev/null
+++ b/src/boost/libs/hana/test/issues/github_91.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/concept/comparable.hpp>
+#include <boost/hana/concept/euclidean_ring.hpp>
+#include <boost/hana/concept/group.hpp>
+#include <boost/hana/concept/monoid.hpp>
+#include <boost/hana/concept/orderable.hpp>
+#include <boost/hana/concept/ring.hpp>
+#include <boost/hana/integral_constant.hpp>
+namespace hana = boost::hana;
+
+
+using T = decltype(hana::int_c<1>);
+
+static_assert(hana::Comparable<T>::value, "");
+static_assert(hana::Orderable<T>::value, "");
+static_assert(hana::Monoid<T>::value, "");
+static_assert(hana::Group<T>::value, "");
+static_assert(hana::Ring<T>::value, "");
+static_assert(hana::EuclideanRing<T>::value, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/lazy.cpp b/src/boost/libs/hana/test/lazy.cpp
new file mode 100644
index 00000000..87d9f2e7
--- /dev/null
+++ b/src/boost/libs/hana/test/lazy.cpp
@@ -0,0 +1,342 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/lazy.hpp>
+
+#include <boost/hana/ap.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/duplicate.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval.hpp>
+#include <boost/hana/extend.hpp>
+#include <boost/hana/extract.hpp>
+#include <boost/hana/flatten.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/lift.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/applicative.hpp>
+#include <laws/base.hpp>
+#include <laws/comonad.hpp>
+#include <laws/functor.hpp>
+#include <laws/monad.hpp>
+#include <support/tracked.hpp>
+
+#include <array>
+#include <iostream>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+namespace boost { namespace hana {
+ // We provide this instance for unit tests only because it is _so_ much
+ // more convenient, but this instance is too dangerous for general usage.
+ // See the documentation of `hana::lazy` for more info.
+ template <>
+ struct equal_impl<lazy_tag, lazy_tag> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return hana::equal(hana::eval(x), hana::eval(y)); }
+ };
+}}
+
+auto invalid = [](auto x)
+{ return x.this_function_must_not_be_instantiated; };
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ auto eqs = hana::make_tuple(
+ hana::make_lazy(ct_eq<0>{}),
+ hana::make_lazy(ct_eq<1>{}),
+ hana::make_lazy(ct_eq<2>{})
+ );
+ auto eq_elems = hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<1>{});
+ auto nested = hana::make_tuple(
+ hana::make_lazy(hana::make_lazy(ct_eq<0>{})),
+ hana::make_lazy(hana::make_lazy(ct_eq<1>{})),
+ hana::make_lazy(hana::make_lazy(ct_eq<2>{}))
+ );
+
+ //////////////////////////////////////////////////////////////////////////
+ // Lazy methods
+ //////////////////////////////////////////////////////////////////////////
+ {
+ // lazy
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_lazy(f)(),
+ hana::make_lazy(f())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_lazy(f)(ct_eq<0>{}),
+ hana::make_lazy(f(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_lazy(f)(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_lazy(f(ct_eq<0>{}, ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_lazy(f)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_lazy(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))
+ ));
+
+ // The function is not applied.
+ hana::make_lazy(invalid)();
+ hana::make_lazy(invalid)(ct_eq<0>{});
+ hana::make_lazy(invalid)(ct_eq<0>{}, ct_eq<1>{});
+ hana::make_lazy(invalid)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+ }
+
+ // eval
+ {
+ // With lazy expressions
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval(hana::make_lazy(ct_eq<0>{})),
+ ct_eq<0>{}
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval(hana::make_lazy(ct_eq<1>{})),
+ ct_eq<1>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval(hana::make_lazy(f)()),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval(hana::make_lazy(f)(ct_eq<3>{})),
+ f(ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval(hana::make_lazy(f)(ct_eq<3>{}, ct_eq<4>{})),
+ f(ct_eq<3>{}, ct_eq<4>{})
+ ));
+
+ // Should call a nullary function
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval([]{ return ct_eq<3>{}; }),
+ ct_eq<3>{}
+ ));
+
+ // Should call a unary function with hana::id.
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval([](auto _) { return _(ct_eq<3>{}); }),
+ ct_eq<3>{}
+ ));
+
+ // For overloaded function objects that are both nullary and unary,
+ // the nullary overload should be preferred.
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::eval(f),
+ f()
+ ));
+ }
+
+ // Make sure this does not move from a destroyed object, as that
+ // used to be the case.
+ {
+ auto x = hana::flatten(hana::make_lazy(hana::make_lazy(Tracked{1})));
+ auto z = hana::eval(x); (void)z;
+ }
+
+ // In some cases where a type has a constructor that is way too
+ // general, copying a lazy value holding an object of that type
+ // could trigger the instantiation of that constructor. If that
+ // constructor was ill-formed, the compilation would fail. We
+ // make sure this does not happen.
+ {
+ {
+ auto expr = hana::make_lazy(hana::test::trap_construct{});
+ auto implicit_copy = expr; (void)implicit_copy;
+ decltype(expr) explicit_copy(expr); (void)explicit_copy;
+ }
+
+ {
+ auto expr = hana::make_lazy(hana::test::trap_construct{})();
+ auto implicit_copy = expr; (void)implicit_copy;
+ decltype(expr) explicit_copy(expr); (void)explicit_copy;
+ }
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Functor
+ //////////////////////////////////////////////////////////////////////////
+ {
+ // transform
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::make_lazy(ct_eq<0>{}), f),
+ hana::make_lazy(f(ct_eq<0>{}))
+ ));
+ }
+
+ // laws
+ hana::test::TestFunctor<hana::lazy_tag>{eqs, eq_elems};
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Applicative
+ //////////////////////////////////////////////////////////////////////////
+ {
+ // ap
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(hana::make_lazy(f), hana::make_lazy(ct_eq<0>{})),
+ hana::make_lazy(f(ct_eq<0>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(hana::make_lazy(f), hana::make_lazy(ct_eq<0>{}), hana::make_lazy(ct_eq<1>{})),
+ hana::make_lazy(f(ct_eq<0>{}, ct_eq<1>{}))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(hana::make_lazy(f), hana::make_lazy(ct_eq<0>{}), hana::make_lazy(ct_eq<1>{}), hana::make_lazy(ct_eq<2>{})),
+ hana::make_lazy(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))
+ ));
+
+ // The function is not applied.
+ hana::ap(hana::make_lazy(invalid), hana::make_lazy(ct_eq<0>{}));
+ hana::ap(hana::make_lazy(invalid), hana::make_lazy(ct_eq<0>{}), hana::make_lazy(ct_eq<1>{}));
+ hana::ap(hana::make_lazy(invalid), hana::make_lazy(ct_eq<0>{}), hana::make_lazy(ct_eq<1>{}), hana::make_lazy(ct_eq<2>{}));
+ }
+
+ // lift
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::lift<hana::lazy_tag>(ct_eq<0>{}),
+ hana::make_lazy(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::lift<hana::lazy_tag>(ct_eq<1>{}),
+ hana::make_lazy(ct_eq<1>{})
+ ));
+ }
+
+ // laws
+ hana::test::TestApplicative<hana::lazy_tag>{eqs};
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Monad
+ //////////////////////////////////////////////////////////////////////////
+ {
+ auto f_ = hana::compose(hana::make_lazy, f);
+
+ // chain
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(hana::make_lazy(ct_eq<0>{}), f_),
+ f_(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(hana::make_lazy(ct_eq<1>{}), f_),
+ f_(ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_lazy(ct_eq<1>{}) | f_,
+ f_(ct_eq<1>{})
+ ));
+ }
+
+ // flatten
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(hana::make_lazy(hana::make_lazy(ct_eq<0>{}))),
+ hana::make_lazy(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(hana::make_lazy(hana::make_lazy(ct_eq<1>{}))),
+ hana::make_lazy(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(hana::make_lazy(hana::make_lazy(hana::make_lazy(ct_eq<1>{})))),
+ hana::make_lazy(hana::make_lazy(ct_eq<1>{}))
+ ));
+ }
+
+ // laws
+ hana::test::TestMonad<hana::lazy_tag>{eqs, nested};
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Comonad
+ //////////////////////////////////////////////////////////////////////////
+ {
+ // extract
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::extract(hana::make_lazy(ct_eq<4>{})),
+ ct_eq<4>{}
+ ));
+ }
+
+ // duplicate
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::duplicate(hana::make_lazy(ct_eq<4>{})),
+ hana::make_lazy(hana::make_lazy(ct_eq<4>{}))
+ ));
+ }
+
+ // extend
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::extend(hana::make_lazy(ct_eq<4>{}), f),
+ hana::make_lazy(f(hana::make_lazy(ct_eq<4>{})))
+ ));
+ }
+
+ // laws
+ hana::test::TestComonad<hana::lazy_tag>{eqs};
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Make sure the monadic chain is evaluated in the right order.
+ //////////////////////////////////////////////////////////////////////////
+ {
+ std::array<bool, 3> executed = {{false, false, false}};
+ int dummy = 0;
+
+ std::cout << "creating the monadic chain...\n";
+ auto chain = hana::make_lazy(dummy)
+ | [&](int dummy) {
+ std::cout << "executing the first computation...\n";
+ executed[0] = true;
+ BOOST_HANA_RUNTIME_CHECK(
+ executed == std::array<bool, 3>{{true, false, false}}
+ );
+ return hana::make_lazy(dummy);
+ }
+ | [&](int dummy) {
+ std::cout << "executing the second computation...\n";
+ executed[1] = true;
+ BOOST_HANA_RUNTIME_CHECK(
+ executed == std::array<bool, 3>{{true, true, false}}
+ );
+ return hana::make_lazy(dummy);
+ }
+ | [&](int dummy) {
+ std::cout << "executing the third computation...\n";
+ executed[2] = true;
+ BOOST_HANA_RUNTIME_CHECK(
+ executed == std::array<bool, 3>{{true, true, true}}
+ );
+ return hana::make_lazy(dummy);
+ };
+
+ BOOST_HANA_RUNTIME_CHECK(
+ executed == std::array<bool, 3>{{false, false, false}}
+ );
+
+ std::cout << "evaluating the chain...\n";
+ hana::eval(chain);
+ }
+}
diff --git a/src/boost/libs/hana/test/logical.cpp b/src/boost/libs/hana/test/logical.cpp
new file mode 100644
index 00000000..b4148e48
--- /dev/null
+++ b/src/boost/libs/hana/test/logical.cpp
@@ -0,0 +1,84 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/logical.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/while.hpp>
+
+#include <laws/logical.hpp>
+
+#include <vector>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::TestLogical<bool>{hana::make_tuple(true, false)};
+
+ // eval_if
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::eval_if(true, hana::always(1), hana::always(2)),
+ 1
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::eval_if(false, hana::always(1), hana::always(2)),
+ 2
+ ));
+ }
+
+ // not_
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(hana::not_(true), false));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(hana::not_(false), true));
+ }
+
+ // while_
+ {
+ auto less_than = [](auto n) {
+ return [n](auto v) { return v.size() < n; };
+ };
+ auto f = [](auto v) {
+ v.push_back(v.size());
+ return v;
+ };
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(0u), std::vector<int>{}, f),
+ std::vector<int>{}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(1u), std::vector<int>{}, f),
+ std::vector<int>{0}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(2u), std::vector<int>{}, f),
+ std::vector<int>{0, 1}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(3u), std::vector<int>{}, f),
+ std::vector<int>{0, 1, 2}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(4u), std::vector<int>{}, f),
+ std::vector<int>{0, 1, 2, 3}
+ ));
+
+ // Make sure it can be called with an lvalue state:
+ std::vector<int> v{};
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(4u), v, f),
+ std::vector<int>{0, 1, 2, 3}
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/map/any_of.cpp b/src/boost/libs/hana/test/map/any_of.cpp
new file mode 100644
index 00000000..8d352c56
--- /dev/null
+++ b/src/boost/libs/hana/test/map/any_of.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/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/not.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ hana::make_map(),
+ hana::equal.to(key<1>()
+ ))));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ hana::make_map(p<1, 1>()),
+ hana::equal.to(key<1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ hana::make_map(p<1, 1>()),
+ hana::equal.to(key<2>())
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::equal.to(key<1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::equal.to(key<2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::equal.to(key<3>())
+ )));
+}
diff --git a/src/boost/libs/hana/test/map/assign.copy.cpp b/src/boost/libs/hana/test/map/assign.copy.cpp
new file mode 100644
index 00000000..d5d09839
--- /dev/null
+++ b/src/boost/libs/hana/test/map/assign.copy.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/at_key.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+
+#include <laws/base.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+namespace test = hana::test;
+
+
+int main() {
+ {
+ using Map = hana::map<>;
+ Map map0;
+ Map map;
+ map0 = map;
+ }
+ {
+ using Map = hana::map<hana::pair<test::ct_eq<0>, int>>;
+ Map map0 = hana::make_map(hana::make_pair(test::ct_eq<0>{}, 999));
+ Map map = hana::make_map(hana::make_pair(test::ct_eq<0>{}, 4));
+ map0 = map;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<0>{}) == 4);
+ }
+ {
+ using Map = hana::map<hana::pair<test::ct_eq<0>, int>,
+ hana::pair<test::ct_eq<1>, char>>;
+ Map map0 = hana::make_map(hana::make_pair(test::ct_eq<0>{}, 999),
+ hana::make_pair(test::ct_eq<1>{}, 'z'));
+ Map map = hana::make_map(hana::make_pair(test::ct_eq<0>{}, 4),
+ hana::make_pair(test::ct_eq<1>{}, 'a'));
+ map0 = map;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<0>{}) == 4);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<1>{}) == 'a');
+ }
+ {
+ using Map = hana::map<hana::pair<test::ct_eq<0>, int>,
+ hana::pair<test::ct_eq<1>, char>,
+ hana::pair<test::ct_eq<2>, std::string>>;
+ Map map0 = hana::make_map(hana::make_pair(test::ct_eq<0>{}, 999),
+ hana::make_pair(test::ct_eq<1>{}, 'z'),
+ hana::make_pair(test::ct_eq<2>{}, std::string{"zzzzzzzz"}));
+ Map map = hana::make_map(hana::make_pair(test::ct_eq<0>{}, 4),
+ hana::make_pair(test::ct_eq<1>{}, 'a'),
+ hana::make_pair(test::ct_eq<2>{}, std::string{"abc"}));
+ map0 = map;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<0>{}) == 4);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<1>{}) == 'a');
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<2>{}) == "abc");
+ }
+}
diff --git a/src/boost/libs/hana/test/map/assign.move.cpp b/src/boost/libs/hana/test/map/assign.move.cpp
new file mode 100644
index 00000000..a04f55e4
--- /dev/null
+++ b/src/boost/libs/hana/test/map/assign.move.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_key.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+
+#include <laws/base.hpp>
+
+#include <string>
+#include <utility>
+namespace hana = boost::hana;
+namespace test = hana::test;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data = 1) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ int get() const {return data_;}
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+ bool operator< (const MoveOnly& x) const { return data_ < x.data_; }
+};
+
+int main() {
+ {
+ using Map = hana::map<>;
+ Map map0;
+ Map map;
+ map0 = std::move(map);
+ }
+ {
+ using Map = hana::map<hana::pair<test::ct_eq<0>, MoveOnly>>;
+ Map map0 = hana::make_map(hana::make_pair(test::ct_eq<0>{}, MoveOnly{999}));
+ Map map = hana::make_map(hana::make_pair(test::ct_eq<0>{}, MoveOnly{4}));
+ map0 = std::move(map);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<0>{}) == MoveOnly{4});
+ }
+ {
+ using Map = hana::map<hana::pair<test::ct_eq<0>, MoveOnly>,
+ hana::pair<test::ct_eq<1>, MoveOnly>>;
+ Map map0 = hana::make_map(hana::make_pair(test::ct_eq<0>{}, MoveOnly{999}),
+ hana::make_pair(test::ct_eq<1>{}, MoveOnly{888}));
+ Map map = hana::make_map(hana::make_pair(test::ct_eq<0>{}, MoveOnly{4}),
+ hana::make_pair(test::ct_eq<1>{}, MoveOnly{5}));
+ map0 = std::move(map);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<0>{}) == MoveOnly{4});
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<1>{}) == MoveOnly{5});
+ }
+ {
+ using Map = hana::map<hana::pair<test::ct_eq<0>, MoveOnly>,
+ hana::pair<test::ct_eq<1>, MoveOnly>,
+ hana::pair<test::ct_eq<2>, MoveOnly>>;
+ Map map0 = hana::make_map(hana::make_pair(test::ct_eq<0>{}, MoveOnly{999}),
+ hana::make_pair(test::ct_eq<1>{}, MoveOnly{888}),
+ hana::make_pair(test::ct_eq<2>{}, MoveOnly{777}));
+ Map map = hana::make_map(hana::make_pair(test::ct_eq<0>{}, MoveOnly{4}),
+ hana::make_pair(test::ct_eq<1>{}, MoveOnly{5}),
+ hana::make_pair(test::ct_eq<2>{}, MoveOnly{6}));
+ map0 = std::move(map);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<0>{}) == MoveOnly{4});
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<1>{}) == MoveOnly{5});
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<2>{}) == MoveOnly{6});
+ }
+ {
+ using Map = hana::map<hana::pair<test::ct_eq<0>, MoveOnly>,
+ hana::pair<test::ct_eq<1>, MoveOnly>,
+ hana::pair<test::ct_eq<2>, MoveOnly>,
+ hana::pair<test::ct_eq<3>, std::string>>;
+ Map map0 = hana::make_map(hana::make_pair(test::ct_eq<0>{}, MoveOnly{999}),
+ hana::make_pair(test::ct_eq<1>{}, MoveOnly{888}),
+ hana::make_pair(test::ct_eq<2>{}, MoveOnly{777}),
+ hana::make_pair(test::ct_eq<3>{}, std::string{"zzzzz"}));
+ Map map = hana::make_map(hana::make_pair(test::ct_eq<0>{}, MoveOnly{4}),
+ hana::make_pair(test::ct_eq<1>{}, MoveOnly{5}),
+ hana::make_pair(test::ct_eq<2>{}, MoveOnly{6}),
+ hana::make_pair(test::ct_eq<3>{}, std::string{"abc"}));
+ map0 = std::move(map);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<0>{}) == MoveOnly{4});
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<1>{}) == MoveOnly{5});
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<2>{}) == MoveOnly{6});
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(map0, test::ct_eq<3>{}) == std::string{"abc"});
+ }
+}
diff --git a/src/boost/libs/hana/test/map/at_key.collisions.cpp b/src/boost/libs/hana/test/map/at_key.collisions.cpp
new file mode 100644
index 00000000..3df10c4a
--- /dev/null
+++ b/src/boost/libs/hana/test/map/at_key.collisions.cpp
@@ -0,0 +1,149 @@
+// Copyright Jason Rice 2016
+// Distributed under the 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/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/hash.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct A { };
+struct B { };
+
+struct the_hash;
+
+namespace boost { namespace hana {
+ template <>
+ struct hash_impl<A> {
+ static constexpr auto apply(A const&) {
+ return hana::type_c<the_hash>;
+ }
+ };
+
+ template <>
+ struct hash_impl<B> {
+ static constexpr auto apply(B const&) {
+ return hana::type_c<the_hash>;
+ }
+ };
+
+ template <>
+ struct equal_impl<A, A> {
+ static constexpr auto apply(A const&, A const&) {
+ return hana::true_c;
+ }
+ };
+
+ template <>
+ struct equal_impl<B, B> {
+ static constexpr auto apply(B const&, B const&) {
+ return hana::true_c;
+ }
+ };
+}}
+
+int main() {
+ constexpr auto key1 = A{};
+ constexpr auto key2 = B{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(key1, key1));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(key2, key2));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(key1, key2)));
+
+ // ensure the hashes actually collide
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::hash(key1), hana::hash(key2)));
+
+ {
+ auto map = hana::to_map(hana::make_tuple(
+ hana::make_pair(key1, key1),
+ hana::make_pair(key2, key2)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, key1),
+ key1
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, key2),
+ key2
+ ));
+ }
+
+ {
+ auto map = hana::to_map(hana::make_tuple(
+ hana::make_pair(key2, key2),
+ hana::make_pair(key1, key1)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, key1),
+ key1
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, key2),
+ key2
+ ));
+ }
+
+ {
+ auto map = hana::to_map(hana::make_tuple(
+ hana::make_pair(key1, key1),
+ hana::make_pair(hana::int_c<56>, hana::int_c<56>),
+ hana::make_pair(key2, key2)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, key1),
+ key1
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, hana::int_c<56>),
+ hana::int_c<56>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, key2),
+ key2
+ ));
+ }
+
+ {
+ auto map = hana::to_map(hana::make_tuple(
+ hana::make_pair(key1, key1),
+ hana::make_pair(hana::int_c<56>, hana::int_c<56>),
+ hana::make_pair(key2, key2),
+ hana::make_pair(hana::int_c<42>, hana::int_c<42>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, key1),
+ key1
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, hana::int_c<56>),
+ hana::int_c<56>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, key2),
+ key2
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(map, hana::int_c<42>),
+ hana::int_c<42>
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/map/at_key.cpp b/src/boost/libs/hana/test/map/at_key.cpp
new file mode 100644
index 00000000..c948216c
--- /dev/null
+++ b/src/boost/libs/hana/test/map/at_key.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/assert.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/map.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(hana::make_map(p<0, 0>()), key<0>()),
+ val<0>()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(hana::make_map(p<0, 0>(), p<1,1>()), key<0>()),
+ val<0>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(hana::make_map(p<0, 0>(), p<1,1>()), key<1>()),
+ val<1>()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(hana::make_map(p<0, 0>(), p<1,1>(), p<2,2>()), key<0>()),
+ val<0>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(hana::make_map(p<0, 0>(), p<1,1>(), p<2,2>()), key<1>()),
+ val<1>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at_key(hana::make_map(p<0, 0>(), p<1,1>(), p<2,2>()), key<2>()),
+ val<2>()
+ ));
+
+ // check operators
+ auto m = hana::make_map(p<2, 2>(), p<1, 1>());
+ auto const const_m = hana::make_map(p<2, 2>(), p<1, 1>());
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(m[key<1>()], val<1>()));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(const_m[key<1>()], val<1>()));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(std::move(m)[key<1>()], val<1>()));
+}
diff --git a/src/boost/libs/hana/test/map/at_key.ref.cpp b/src/boost/libs/hana/test/map/at_key.ref.cpp
new file mode 100644
index 00000000..c845bc13
--- /dev/null
+++ b/src/boost/libs/hana/test/map/at_key.ref.cpp
@@ -0,0 +1,84 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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 <utility>
+namespace hana = boost::hana;
+
+
+template <typename T>
+T const& cref(T& t) { return t; }
+
+int main() {
+ // using at_key
+ {
+ auto xs = hana::make_map(
+ hana::make_pair(hana::int_c<0>, 0),
+ hana::make_pair(hana::int_c<1>, '1'),
+ hana::make_pair(hana::int_c<2>, 2.2)
+ );
+
+ // Make sure we return lvalue-references
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(xs, hana::int_c<0>) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(xs, hana::int_c<1>) == '1');
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(xs, hana::int_c<2>) == 2.2);
+
+ int& a = hana::at_key(xs, hana::int_c<0>);
+ char& b = hana::at_key(xs, hana::int_c<1>);
+ double& c = hana::at_key(xs, hana::int_c<2>);
+ a = 9;
+ b = '9';
+ c = 9.9;
+
+ // Make sure we return lvalue-references to const on a const map
+ int const& ca = hana::at_key(cref(xs), hana::int_c<0>);
+ char const& cb = hana::at_key(cref(xs), hana::int_c<1>);
+ double const& cc = hana::at_key(cref(xs), hana::int_c<2>);
+
+ BOOST_HANA_RUNTIME_CHECK(ca == 9);
+ BOOST_HANA_RUNTIME_CHECK(cb == '9');
+ BOOST_HANA_RUNTIME_CHECK(cc == 9.9);
+ }
+
+ // using operator[]
+ {
+ auto xs = hana::make_map(
+ hana::make_pair(hana::int_c<0>, 0),
+ hana::make_pair(hana::int_c<1>, '1'),
+ hana::make_pair(hana::int_c<2>, 2.2)
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(xs[hana::int_c<0>] == 0);
+ BOOST_HANA_RUNTIME_CHECK(xs[hana::int_c<1>] == '1');
+ BOOST_HANA_RUNTIME_CHECK(xs[hana::int_c<2>] == 2.2);
+
+ xs[hana::int_c<0>] = 9;
+ xs[hana::int_c<1>] = '9';
+ xs[hana::int_c<2>] = 9.9;
+
+ BOOST_HANA_RUNTIME_CHECK(xs[hana::int_c<0>] == 9);
+ BOOST_HANA_RUNTIME_CHECK(xs[hana::int_c<1>] == '9');
+ BOOST_HANA_RUNTIME_CHECK(xs[hana::int_c<2>] == 9.9);
+ }
+
+ // Make sure we return a rvalue-reference from a temporary map
+ // (https://github.com/boostorg/hana/issues/90)
+ {
+ auto xs = hana::make_map(
+ hana::make_pair(hana::int_c<0>, 0),
+ hana::make_pair(hana::int_c<1>, '1'),
+ hana::make_pair(hana::int_c<2>, 2.2)
+ );
+
+ char&& c = hana::at_key(std::move(xs), hana::int_c<1>);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(xs, hana::int_c<1>) == '1');
+ c = '9';
+ BOOST_HANA_RUNTIME_CHECK(hana::at_key(xs, hana::int_c<1>) == '9');
+ }
+}
diff --git a/src/boost/libs/hana/test/map/at_key.stackoverflow.cpp b/src/boost/libs/hana/test/map/at_key.stackoverflow.cpp
new file mode 100644
index 00000000..7f71799a
--- /dev/null
+++ b/src/boost/libs/hana/test/map/at_key.stackoverflow.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/at_key.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+//
+// Make sure that http://stackoverflow.com/q/32702383/627587 works.
+//
+
+auto at = [](auto& map, auto key) -> auto& {
+ return map[key];
+};
+
+template <typename Map, typename Keys>
+auto& traverse(Map& map, Keys const& keys){
+ return hana::fold_left(keys, map, at);
+}
+
+int main() {
+ auto xs = hana::make_map(hana::make_pair(hana::int_c<0>,
+ hana::make_map(hana::make_pair(hana::int_c<1>,
+ hana::make_map(hana::make_pair(hana::int_c<2>,
+ hana::make_map(hana::make_pair(hana::int_c<3>, 10))))))));
+
+ int& i = traverse(xs, hana::range_c<int, 0, 4>);
+ BOOST_HANA_RUNTIME_CHECK(i == 10);
+ i = 99;
+ BOOST_HANA_RUNTIME_CHECK(traverse(xs, hana::range_c<int, 0, 4>) == 99);
+}
diff --git a/src/boost/libs/hana/test/map/cnstr.copy.cpp b/src/boost/libs/hana/test/map/cnstr.copy.cpp
new file mode 100644
index 00000000..881de02b
--- /dev/null
+++ b/src/boost/libs/hana/test/map/cnstr.copy.cpp
@@ -0,0 +1,114 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/fwd/hash.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/type.hpp>
+
+#include <string>
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+ friend auto operator==(NoCopy const&, NoCopy const&) { return hana::true_c; }
+ friend auto operator!=(NoCopy const&, NoCopy const&) { return hana::false_c; }
+};
+
+// Note: It is also useful to check with a non-empty class, because that
+// triggers different instantiations due to EBO.
+struct NoCopy_nonempty {
+ NoCopy_nonempty() = default;
+ NoCopy_nonempty(NoCopy_nonempty const&) = delete;
+ int i;
+ friend auto operator==(NoCopy_nonempty const&, NoCopy_nonempty const&) { return hana::true_c; }
+ friend auto operator!=(NoCopy_nonempty const&, NoCopy_nonempty const&) { return hana::false_c; }
+};
+
+namespace boost { namespace hana {
+ template <>
+ struct hash_impl<NoCopy> {
+ static constexpr auto apply(NoCopy const&)
+ { return hana::type_c<NoCopy>; };
+ };
+
+ template <>
+ struct hash_impl<NoCopy_nonempty> {
+ static constexpr auto apply(NoCopy_nonempty const&)
+ { return hana::type_c<NoCopy_nonempty>; };
+ };
+}}
+
+
+int main() {
+ {
+ auto t0 = hana::make_map();
+ auto t_implicit = t0;
+ auto t_explicit(t0);
+
+ (void)t_explicit;
+ (void)t_implicit;
+ }
+ {
+ auto t0 = hana::make_map(hana::make_pair(hana::int_c<2>, hana::int_c<20>));
+ auto t_implicit = t0;
+ auto t_explicit(t0);
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_map(hana::make_pair(hana::int_c<2>, hana::int_c<20>),
+ hana::make_pair(hana::int_c<3>, hana::int_c<30>));
+ auto t_implicit = t0;
+ auto t_explicit(t0);
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_map(hana::make_pair(hana::int_c<2>, hana::int_c<20>),
+ hana::make_pair(hana::int_c<3>, hana::int_c<30>),
+ hana::make_pair(hana::type_c<void>, hana::type_c<void*>));
+ auto t_implicit = t0;
+ auto t_explicit(t0);
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ constexpr auto t0 = hana::make_map(
+ hana::make_pair(hana::int_c<2>, hana::int_c<20>),
+ hana::make_pair(hana::int_c<3>, hana::int_c<30>),
+ hana::make_pair(hana::type_c<void>, hana::type_c<void*>));
+ constexpr auto t_implicit = t0;
+ constexpr auto t_explicit(t0);
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_map(hana::make_pair(hana::int_c<2>, std::string{"abcdef"}));
+ auto copy = t0;
+ BOOST_HANA_RUNTIME_CHECK(
+ copy == hana::make_map(hana::make_pair(hana::int_c<2>, std::string{"abcdef"}))
+ );
+ }
+
+ {
+ using Map1 = hana::map<hana::pair<NoCopy, NoCopy>>;
+ Map1 map1; (void)map1;
+ static_assert(!std::is_copy_constructible<Map1>::value, "");
+
+ using Map2 = hana::map<hana::pair<NoCopy_nonempty, NoCopy_nonempty>>;
+ Map2 map2; (void)map2;
+ static_assert(!std::is_copy_constructible<Map2>::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/map/cnstr.default.cpp b/src/boost/libs/hana/test/map/cnstr.default.cpp
new file mode 100644
index 00000000..cd1320c8
--- /dev/null
+++ b/src/boost/libs/hana/test/map/cnstr.default.cpp
@@ -0,0 +1,74 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/fwd/hash.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct NoDefault {
+ NoDefault() = delete;
+ NoDefault(NoDefault const&) = default;
+ constexpr explicit NoDefault(int) { }
+};
+
+auto operator==(NoDefault const&, NoDefault const&) { return hana::true_c; }
+auto operator!=(NoDefault const&, NoDefault const&) { return hana::false_c; }
+
+// Note: It is also useful to check with a non-empty class, because that
+// triggers different instantiations due to EBO.
+struct NoDefault_nonempty {
+ NoDefault_nonempty() = delete;
+ NoDefault_nonempty(NoDefault_nonempty const&) = default;
+ constexpr explicit NoDefault_nonempty(int k) : i(k) { }
+ int i;
+};
+
+auto operator==(NoDefault_nonempty const&, NoDefault_nonempty const&) { return hana::true_c; }
+auto operator!=(NoDefault_nonempty const&, NoDefault_nonempty const&) { return hana::false_c; }
+
+struct Default {
+ Default() = default;
+ Default(Default const&) = default;
+ constexpr explicit Default(int) { }
+};
+
+auto operator==(Default const&, Default const&) { return hana::true_c; }
+auto operator!=(Default const&, Default const&) { return hana::false_c; }
+
+namespace boost { namespace hana {
+ template <>
+ struct hash_impl<NoDefault> {
+ static constexpr auto apply(NoDefault const&)
+ { return hana::type_c<NoDefault>; };
+ };
+
+ template <>
+ struct hash_impl<NoDefault_nonempty> {
+ static constexpr auto apply(NoDefault_nonempty const&)
+ { return hana::type_c<NoDefault_nonempty>; };
+ };
+
+ template <>
+ struct hash_impl<Default> {
+ static constexpr auto apply(Default const&)
+ { return hana::type_c<Default>; };
+ };
+}}
+
+int main() {
+ auto map1 = hana::make_map(hana::make_pair(Default(1), Default(1)));
+ static_assert(std::is_default_constructible<decltype(map1)>::value, "");
+
+ auto map2 = hana::make_map(hana::make_pair(NoDefault(1), NoDefault(1)));
+ static_assert(!std::is_default_constructible<decltype(map2)>::value, "");
+
+ auto map3 = hana::make_map(hana::make_pair(NoDefault_nonempty(1), NoDefault_nonempty(1)));
+ static_assert(!std::is_default_constructible<decltype(map3)>::value, "");
+}
diff --git a/src/boost/libs/hana/test/map/cnstr.move.cpp b/src/boost/libs/hana/test/map/cnstr.move.cpp
new file mode 100644
index 00000000..c6f9dca5
--- /dev/null
+++ b/src/boost/libs/hana/test/map/cnstr.move.cpp
@@ -0,0 +1,123 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/fwd/hash.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/type.hpp>
+
+#include <support/constexpr_move_only.hpp>
+#include <support/tracked_move_only.hpp>
+
+#include <string>
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+constexpr bool in_constexpr_context() {
+ auto t0 = hana::make_map(
+ hana::make_pair(ConstexprMoveOnly<2>{}, ConstexprMoveOnly<20>{}),
+ hana::make_pair(ConstexprMoveOnly<3>{}, ConstexprMoveOnly<30>{}));
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_implicit;
+ (void)t_explicit;
+ return true;
+}
+
+static_assert(in_constexpr_context(), "");
+
+
+struct NoMove {
+ NoMove() = default;
+ NoMove(NoMove const&) = delete;
+ NoMove(NoMove&&) = delete;
+ friend auto operator==(NoMove const&, NoMove const&) { return hana::true_c; }
+ friend auto operator!=(NoMove const&, NoMove const&) { return hana::false_c; }
+};
+
+// Note: It is also useful to check with a non-empty class, because that
+// triggers different instantiations due to EBO.
+struct NoMove_nonempty {
+ NoMove_nonempty() = default;
+ NoMove_nonempty(NoMove_nonempty const&) = delete;
+ NoMove_nonempty(NoMove_nonempty&&) = delete;
+ int i;
+ friend auto operator==(NoMove_nonempty const&, NoMove_nonempty const&) { return hana::true_c; }
+ friend auto operator!=(NoMove_nonempty const&, NoMove_nonempty const&) { return hana::false_c; }
+};
+
+namespace boost { namespace hana {
+ template <>
+ struct hash_impl<NoMove> {
+ static constexpr auto apply(NoMove const&)
+ { return hana::type_c<NoMove>; };
+ };
+
+ template <>
+ struct hash_impl<NoMove_nonempty> {
+ static constexpr auto apply(NoMove_nonempty const&)
+ { return hana::type_c<NoMove_nonempty>; };
+ };
+}}
+
+int main() {
+ {
+ auto t0 = hana::make_map();
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_explicit;
+ (void)t_implicit;
+ }
+ {
+ auto t0 = hana::make_map(hana::make_pair(TrackedMoveOnly<1>{}, TrackedMoveOnly<10>{}));
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_map(hana::make_pair(TrackedMoveOnly<1>{}, TrackedMoveOnly<10>{}),
+ hana::make_pair(TrackedMoveOnly<2>{}, TrackedMoveOnly<20>{}));
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_map(hana::make_pair(TrackedMoveOnly<1>{}, TrackedMoveOnly<10>{}),
+ hana::make_pair(TrackedMoveOnly<2>{}, TrackedMoveOnly<20>{}),
+ hana::make_pair(TrackedMoveOnly<3>{}, TrackedMoveOnly<30>{}));
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_map(hana::make_pair(hana::int_c<2>, std::string{"abcdef"}));
+ auto moved = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(
+ moved == hana::make_map(hana::make_pair(hana::int_c<2>, std::string{"abcdef"}))
+ );
+ }
+
+ {
+ using Map1 = hana::map<hana::pair<NoMove, NoMove>>;
+ Map1 map1; (void)map1;
+ static_assert(!std::is_move_constructible<Map1>::value, "");
+
+ using Map2 = hana::map<hana::pair<NoMove_nonempty, NoMove_nonempty>>;
+ Map2 map2; (void)map2;
+ static_assert(!std::is_move_constructible<Map2>::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/map/cnstr.trap.cpp b/src/boost/libs/hana/test/map/cnstr.trap.cpp
new file mode 100644
index 00000000..b9ce84e6
--- /dev/null
+++ b/src/boost/libs/hana/test/map/cnstr.trap.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/bool.hpp>
+#include <boost/hana/detail/wrong.hpp>
+#include <boost/hana/fwd/hash.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/type.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+// This test makes sure that we do not instantiate rogue constructors when
+// doing copies and moves
+
+template <int i>
+struct Trap {
+ Trap() = default;
+ Trap(Trap const&) = default;
+#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
+ Trap(Trap&) = default;
+#endif
+ Trap(Trap&&) = default;
+
+ template <typename X>
+ Trap(X&&) {
+ static_assert(hana::detail::wrong<X>{},
+ "this constructor must not be instantiated");
+ }
+};
+
+template <int i, int j>
+constexpr auto operator==(Trap<i> const&, Trap<j> const&)
+{ return hana::bool_c<i == j>; }
+
+template <int i, int j>
+constexpr auto operator!=(Trap<i> const&, Trap<j> const&)
+{ return hana::bool_c<i != j>; }
+
+namespace boost { namespace hana {
+ template <int i>
+ struct hash_impl<Trap<i>> {
+ static constexpr auto apply(Trap<i> const&)
+ { return hana::type_c<Trap<i>>; };
+ };
+}}
+
+int main() {
+ {
+ auto expr = hana::make_map(
+ hana::make_pair(Trap<0>{}, Trap<0>{})
+ );
+ auto implicit_copy = expr;
+ decltype(expr) explicit_copy(expr);
+
+ (void)implicit_copy;
+ (void)explicit_copy;
+ }
+ {
+ auto expr = hana::make_map(
+ hana::make_pair(Trap<0>{}, Trap<0>{})
+ );
+ auto implicit_move = std::move(expr);
+ decltype(expr) explicit_move(std::move(implicit_move));
+
+ (void)implicit_move;
+ (void)explicit_move;
+ }
+}
diff --git a/src/boost/libs/hana/test/map/cnstr.variadic.cpp b/src/boost/libs/hana/test/map/cnstr.variadic.cpp
new file mode 100644
index 00000000..8143d2cf
--- /dev/null
+++ b/src/boost/libs/hana/test/map/cnstr.variadic.cpp
@@ -0,0 +1,186 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/map.hpp>
+#include <boost/hana/pair.hpp>
+
+#include <laws/base.hpp>
+#include <support/constexpr_move_only.hpp>
+#include <support/minimal_product.hpp>
+#include <support/tracked_move_only.hpp>
+
+#include <string>
+#include <vector>
+namespace hana = boost::hana;
+
+
+template <int i>
+using pair = ::product_t<hana::test::ct_eq<i>, hana::test::ct_eq<-i>>;
+
+// Check with move-only literal types.
+constexpr bool in_constexpr_context() {
+ hana::map<hana::pair<ConstexprMoveOnly<2>, ConstexprMoveOnly<20>>,
+ hana::pair<ConstexprMoveOnly<3>, ConstexprMoveOnly<30>>> map{
+ hana::make_pair(ConstexprMoveOnly<2>{}, ConstexprMoveOnly<20>{}),
+ hana::make_pair(ConstexprMoveOnly<3>{}, ConstexprMoveOnly<30>{})
+ };
+ (void)map;
+ return true;
+}
+
+static_assert(in_constexpr_context(), "");
+
+int main() {
+ // Basic check with non trivial runtime state
+ {
+ std::vector<std::string> v{"Hello", "world", "!"};
+
+ hana::map<
+ hana::pair<hana::test::ct_eq<1>, std::string>,
+ hana::pair<hana::test::ct_eq<2>, std::vector<std::string>>
+ > map{
+ hana::make_pair(hana::test::ct_eq<1>{}, std::string{"Hello world!"}),
+ hana::make_pair(hana::test::ct_eq<2>{}, v)
+ };
+
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::at_key(map, hana::test::ct_eq<1>{}) == std::string{"Hello world!"}
+ );
+
+ BOOST_HANA_RUNTIME_CHECK(
+ hana::at_key(map, hana::test::ct_eq<2>{}) == v
+ );
+ }
+
+ {
+ hana::map<> map{};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map()
+ ));
+ }
+
+ {
+ hana::map<pair<0>> map{pair<0>{}};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{})
+ ));
+ }
+
+ {
+ hana::map<pair<0>, pair<1>> map{pair<0>{}, pair<1>{}};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{}, pair<1>{})
+ ));
+ }
+
+ {
+ hana::map<pair<0>, pair<1>, pair<2>> map{pair<0>{}, pair<1>{}, pair<2>{}};
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{}, pair<1>{}, pair<2>{})
+ ));
+ }
+
+ {
+ hana::map<pair<0>, pair<1>, pair<2>, pair<3>> map{
+ pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}
+ };
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{})
+ ));
+ }
+
+ {
+ hana::map<pair<0>, pair<1>, pair<2>, pair<3>, pair<4>> map{
+ pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}, pair<4>{}
+ };
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}, pair<4>{})
+ ));
+ }
+
+ {
+ hana::map<pair<0>, pair<1>, pair<2>, pair<3>, pair<4>, pair<5>> map{
+ pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}, pair<4>{}, pair<5>{}
+ };
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}, pair<4>{}, pair<5>{})
+ ));
+ }
+
+ // Use parenthesis syntax instead of braces
+ {
+ hana::map<> map = hana::map<>();
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map()
+ ));
+ }
+
+ {
+ hana::map<pair<0>> map(
+ pair<0>{}
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{})
+ ));
+ }
+
+ {
+ hana::map<pair<0>, pair<1>> map(
+ pair<0>{}, pair<1>{}
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{}, pair<1>{})
+ ));
+ }
+
+ {
+ hana::map<pair<0>, pair<1>, pair<2>> map(
+ pair<0>{}, pair<1>{}, pair<2>{}
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{}, pair<1>{}, pair<2>{})
+ ));
+ }
+
+ {
+ hana::map<pair<0>, pair<1>, pair<2>, pair<3>> map(
+ pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}
+ );
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ map,
+ hana::make_map(pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{})
+ ));
+ }
+
+ // Check with move-only types
+ {
+ hana::map<hana::pair<TrackedMoveOnly<1>, TrackedMoveOnly<10>>,
+ hana::pair<TrackedMoveOnly<2>, TrackedMoveOnly<20>>> map{
+ hana::make_pair(TrackedMoveOnly<1>{}, TrackedMoveOnly<10>{}),
+ hana::make_pair(TrackedMoveOnly<2>{}, TrackedMoveOnly<20>{})
+ };
+ }
+
+ // The following used to fail when we did not constrain the
+ // constructor properly:
+ {
+ hana::map<pair<1>> map{};
+ hana::test::_injection<0> f{};
+ auto x = f(map);
+ }
+}
diff --git a/src/boost/libs/hana/test/map/contains.cpp b/src/boost/libs/hana/test/map/contains.cpp
new file mode 100644
index 00000000..901d0a66
--- /dev/null
+++ b/src/boost/libs/hana/test/map/contains.cpp
@@ -0,0 +1,117 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/map.hpp>
+#include <boost/hana/not.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(),
+ key<0>()
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(),
+ key<1>()
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>()),
+ key<0>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(p<0,0>()),
+ key<1>()
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(p<0,0>()),
+ key<2>()
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>()),
+ key<0>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>()),
+ key<1>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>()),
+ key<2>()
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>()),
+ key<0>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>()),
+ key<1>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>()),
+ key<2>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>()),
+ key<3>()
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<0>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<1>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<2>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<3>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<4>()
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<5>()
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<6>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<7>()
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<8>()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_map(p<0,0>(), p<1,1>(), p<2,2>(), p<3,3>(), p<6,6>(), p<8,8>()),
+ key<9>()
+ )));
+}
diff --git a/src/boost/libs/hana/test/map/difference.cpp b/src/boost/libs/hana/test/map/difference.cpp
new file mode 100644
index 00000000..5d1b4f45
--- /dev/null
+++ b/src/boost/libs/hana/test/map/difference.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/assert.hpp>
+#include <boost/hana/difference.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/map.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_map(),
+ hana::make_map()
+ ),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_map(p<1, 1>()),
+ hana::make_map()
+ ),
+ hana::make_map(p<1, 1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<2, 2>())
+ ),
+ hana::make_map(p<1, 1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<1, 2>())
+ ),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_map(p<1, 1>(),
+ p<2, 2>(),
+ p<3, 3>()),
+ hana::make_map(p<2, 2>(),
+ p<4, 4>())
+ ),
+ hana::make_map(p<1, 1>(),
+ p<3, 3>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_map(p<1, 1>(),
+ p<2, 2>()),
+ hana::make_map(p<2, 3>(),
+ p<1, 4>())
+ ),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_map(p<1, 1>(),
+ p<2, 2>(),
+ p<3, 3>(),
+ p<4, 4>(),
+ p<5, 5>(),
+ p<6, 6>(),
+ p<7, 7>(),
+ p<8, 8>(),
+ p<9, 9>(),
+ p<10, 10>()),
+ hana::make_map(p<0, 2>(),
+ p<2, 4>(),
+ p<3, 6>(),
+ p<4, 8>(),
+ p<5, 10>(),
+ p<20, 30>())
+ ),
+ hana::make_map(p<1, 1>(),
+ p<6, 6>(),
+ p<7, 7>(),
+ p<8, 8>(),
+ p<9, 9>(),
+ p<10, 10>())
+ ));
+
+}
diff --git a/src/boost/libs/hana/test/map/equal.cpp b/src/boost/libs/hana/test/map/equal.cpp
new file mode 100644
index 00000000..c12be4e4
--- /dev/null
+++ b/src/boost/libs/hana/test/map/equal.cpp
@@ -0,0 +1,97 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/map.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_map(),
+ hana::make_map()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(p<1, 1>()),
+ hana::make_map()
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(),
+ hana::make_map(p<1, 1>())
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<1, 1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<1, 2>())
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<2, 1>())
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::make_map(p<2, 2>(), p<1, 1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::make_map(p<9, 1>(), p<2, 2>()))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::make_map(p<1, 9>(), p<2, 2>()))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::make_map(p<1, 1>(), p<9, 2>()))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::make_map(p<1, 1>(), p<2, 9>()))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()))
+ ));
+
+ // operators
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_map(p<2, 2>(), p<1, 1>())
+ ==
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_map(p<1, 1>())
+ !=
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ );
+}
diff --git a/src/boost/libs/hana/test/map/erase_key.cpp b/src/boost/libs/hana/test/map/erase_key.cpp
new file mode 100644
index 00000000..ddea439d
--- /dev/null
+++ b/src/boost/libs/hana/test/map/erase_key.cpp
@@ -0,0 +1,70 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/map.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(), undefined{}),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(p<1, 1>()), key<1>()),
+ hana::make_map()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(p<1, 1>()), key<99>()),
+ hana::make_map(p<1, 1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(p<1, 1>(), p<2, 2>()), key<99>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(p<1, 1>(), p<2, 2>()), key<1>()),
+ hana::make_map(p<2, 2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(p<1, 1>(), p<2, 2>()), key<2>()),
+ hana::make_map(p<1, 1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()), key<99>()),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()), key<1>()),
+ hana::make_map(p<2, 2>(), p<3, 3>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()), key<2>()),
+ hana::make_map(p<1, 1>(), p<3, 3>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()), key<3>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+}
diff --git a/src/boost/libs/hana/test/map/find_if.cpp b/src/boost/libs/hana/test/map/find_if.cpp
new file mode 100644
index 00000000..93579dfc
--- /dev/null
+++ b/src/boost/libs/hana/test/map/find_if.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/find_if.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_map(), hana::equal.to(key<1>())),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_map(p<1, 1>()), hana::equal.to(key<1>())),
+ hana::just(val<1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_map(p<1, 1>()), hana::equal.to(key<2>())),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_map(p<1, 1>(), p<2, 2>()), hana::equal.to(key<1>())),
+ hana::just(val<1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_map(p<1, 1>(), p<2, 2>()), hana::equal.to(key<2>())),
+ hana::just(val<2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_map(p<1, 1>(), p<2, 2>()), hana::equal.to(key<3>())),
+ hana::nothing
+ ));
+}
diff --git a/src/boost/libs/hana/test/map/fold_left.cpp b/src/boost/libs/hana/test/map/fold_left.cpp
new file mode 100644
index 00000000..558120c9
--- /dev/null
+++ b/src/boost/libs/hana/test/map/fold_left.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/contains.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+struct undefined { };
+
+int main() {
+ auto sequence = ::seq;
+
+ // Use pointers to work around a Clang ICE
+ hana::test::_injection<0> f{};
+ auto* fp = &f;
+
+ hana::test::ct_eq<999> state{};
+ auto* statep = &state;
+
+ auto check = [=](auto ...pairs) {
+ auto possible_results = hana::transform(hana::permutations(sequence(pairs...)),
+ [=](auto xs) {
+ return hana::fold_left(xs, *statep, *fp);
+ }
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ possible_results,
+ hana::fold_left(hana::make_map(pairs...), state, f)
+ ));
+ };
+
+ check();
+ check(p<1, 1>());
+ check(p<1, 1>(), p<2, 2>());
+ check(p<1, 1>(), p<2, 2>(), p<3, 3>());
+ check(p<1, 1>(), p<2, 2>(), p<3, 3>(), p<4, 4>());
+}
diff --git a/src/boost/libs/hana/test/map/fold_right.cpp b/src/boost/libs/hana/test/map/fold_right.cpp
new file mode 100644
index 00000000..2ff88d89
--- /dev/null
+++ b/src/boost/libs/hana/test/map/fold_right.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/contains.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+struct undefined { };
+
+int main() {
+ auto sequence = ::seq;
+
+ // Use pointers to work around a Clang ICE
+ hana::test::_injection<0> f{};
+ auto* fp = &f;
+
+ hana::test::ct_eq<999> state{};
+ auto* statep = &state;
+
+ auto check = [=](auto ...pairs) {
+ auto possible_results = hana::transform(hana::permutations(sequence(pairs...)),
+ [=](auto xs) {
+ return hana::fold_right(xs, *statep, *fp);
+ }
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ possible_results,
+ hana::fold_right(hana::make_map(pairs...), state, f)
+ ));
+ };
+
+ check();
+ check(p<1, 1>());
+ check(p<1, 1>(), p<2, 2>());
+ check(p<1, 1>(), p<2, 2>(), p<3, 3>());
+ check(p<1, 1>(), p<2, 2>(), p<3, 3>(), p<4, 4>());
+}
diff --git a/src/boost/libs/hana/test/map/insert.cpp b/src/boost/libs/hana/test/map/insert.cpp
new file mode 100644
index 00000000..fa8329b9
--- /dev/null
+++ b/src/boost/libs/hana/test/map/insert.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/equal.hpp>
+#include <boost/hana/insert.hpp>
+#include <boost/hana/map.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(), p<1, 1>()),
+ hana::make_map(p<1, 1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(p<1, 1>()), p<1, 99>()),
+ hana::make_map(p<1, 1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(p<1, 1>()), p<2, 2>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(p<1, 1>(), p<2, 2>()), p<1, 99>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(p<1, 1>(), p<2, 2>()), p<2, 99>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(p<1, 1>(), p<2, 2>()), p<3, 3>()),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()), p<1, 99>()),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()), p<2, 99>()),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()), p<3, 99>()),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()), p<4, 4>()),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>(), p<4, 4>())
+ ));
+}
diff --git a/src/boost/libs/hana/test/map/intersection.cpp b/src/boost/libs/hana/test/map/intersection.cpp
new file mode 100644
index 00000000..7e092ec0
--- /dev/null
+++ b/src/boost/libs/hana/test/map/intersection.cpp
@@ -0,0 +1,99 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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 <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_map(),
+ hana::make_map()
+ ),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_map(p<1, 1>()),
+ hana::make_map()
+ ),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_map(),
+ hana::make_map(p<1, 1>())
+ ),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<1, 2>())
+ ),
+ hana::make_map(p<1, 1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_map(
+ p<1, 2>(),
+ p<2, 3>()),
+ hana::make_map(
+ p<1, 3>(),
+ p<2, 4>(),
+ p<3, 5>())
+ ),
+ hana::make_map(
+ p<1, 2>(),
+ p<2, 3>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_map(
+ p<1, 3>(),
+ p<2, 4>(),
+ p<3, 5>()),
+ hana::make_map(
+ p<1, 2>(),
+ p<2, 3>())
+ ),
+ hana::make_map(
+ p<1, 3>(),
+ p<2, 4>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_map(
+ p<1, 100>(),
+ p<2, 200>()),
+ hana::make_map(
+ p<3, 300>(),
+ p<4, 400>())
+ ),
+ hana::make_map()
+ ));
+
+}
diff --git a/src/boost/libs/hana/test/map/is_subset.cpp b/src/boost/libs/hana/test/map/is_subset.cpp
new file mode 100644
index 00000000..3ac5da1d
--- /dev/null
+++ b/src/boost/libs/hana/test/map/is_subset.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/assert.hpp>
+#include <boost/hana/is_subset.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/not.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_map(),
+ hana::make_map()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_map(),
+ hana::make_map(p<1, 1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_map(),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_map(p<2, 2>(), p<1, 1>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_subset(
+ hana::make_map(p<3, 3>(), p<1, 1>()),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ )));
+}
diff --git a/src/boost/libs/hana/test/map/keys.cpp b/src/boost/libs/hana/test/map/keys.cpp
new file mode 100644
index 00000000..8c54cb9a
--- /dev/null
+++ b/src/boost/libs/hana/test/map/keys.cpp
@@ -0,0 +1,49 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/equal.hpp>
+#include <boost/hana/keys.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/permutations.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ constexpr auto list = ::seq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::keys(hana::make_map()),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::keys(hana::make_map(p<1, 1>())),
+ list(key<1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::permutations(list(key<1>(), key<2>())),
+ hana::keys(hana::make_map(p<1, 1>(), p<2, 2>()))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::permutations(list(key<1>(), key<2>(), key<3>())),
+ hana::keys(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()))
+ ));
+}
diff --git a/src/boost/libs/hana/test/map/laws.cpp b/src/boost/libs/hana/test/map/laws.cpp
new file mode 100644
index 00000000..c3a0d670
--- /dev/null
+++ b/src/boost/libs/hana/test/map/laws.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/map.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/searchable.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ auto maps = hana::make_tuple(
+ hana::make_map(),
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<1, 2>()),
+ hana::make_map(p<1, 1>(), p<2, 2>()),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>())
+ );
+
+ hana::test::TestComparable<hana::map_tag>{maps};
+ hana::test::TestSearchable<hana::map_tag>{maps, hana::make_tuple(key<1>(), key<4>())};
+ hana::test::TestFoldable<hana::map_tag>{maps};
+}
diff --git a/src/boost/libs/hana/test/map/map.cpp b/src/boost/libs/hana/test/map/map.cpp
new file mode 100644
index 00000000..bbaceadc
--- /dev/null
+++ b/src/boost/libs/hana/test/map/map.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/map.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <typename ...Pairs>
+struct check_map {
+ static_assert(std::is_same<
+ hana::map<Pairs...>,
+ decltype(hana::make_map(std::declval<Pairs>()...))
+ >{}, "");
+};
+
+template <int i>
+using pair = ::product_t<hana::test::ct_eq<i>, hana::test::ct_eq<-i>>;
+
+template struct check_map<>;
+template struct check_map<pair<1>>;
+template struct check_map<pair<1>, pair<2>>;
+template struct check_map<pair<1>, pair<2>, pair<3>>;
+template struct check_map<pair<1>, pair<2>, pair<3>, pair<4>>;
+template struct check_map<pair<1>, pair<2>, pair<3>, pair<4>, pair<5>>;
+template struct check_map<pair<1>, pair<2>, pair<3>, pair<4>, pair<5>, pair<6>>;
+
+int main() { }
diff --git a/src/boost/libs/hana/test/map/symmetric_difference.cpp b/src/boost/libs/hana/test/map/symmetric_difference.cpp
new file mode 100644
index 00000000..9fc8c77f
--- /dev/null
+++ b/src/boost/libs/hana/test/map/symmetric_difference.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)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/symmetric_difference.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_map(),
+ hana::make_map()
+ ),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<1, 1>())
+ ),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_map(p<1, 2>()),
+ hana::make_map(p<2, 4>())
+ ),
+ hana::make_map(p<1, 2>(),
+ p<2, 4>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_map(p<1, 2>(),
+ p<2, 22>()),
+ hana::make_map(p<2, 4>(),
+ p<3, 33>())
+ ),
+ hana::make_map(p<1, 2>(),
+ p<3, 33>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_map(p<1, 2>(),
+ p<2, 22>(),
+ p<3, 33>(),
+ p<5, 55>(),
+ p<8, 88>()),
+ hana::make_map(p<2, 4>(),
+ p<3, 33>(),
+ p<4, 44>(),
+ p<9, 99>())
+ ),
+ hana::make_map(p<1, 2>(),
+ p<5, 55>(),
+ p<8, 88>(),
+ p<4, 44>(),
+ p<9, 99>())
+ ));
+}
diff --git a/src/boost/libs/hana/test/map/to.cpp b/src/boost/libs/hana/test/map/to.cpp
new file mode 100644
index 00000000..b1cea4c2
--- /dev/null
+++ b/src/boost/libs/hana/test/map/to.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/contains.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/permutations.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ constexpr auto foldable = ::seq;
+ auto sequence = ::seq;
+
+ // Foldable -> Map
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_map(foldable()),
+ hana::make_map()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_map(foldable(p<1, 1>())),
+ hana::make_map(p<1, 1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_map(foldable(p<1, 1>(), p<2, 2>())),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_map(foldable(p<1, 1>(), p<2, 2>(), p<3, 3>())),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>())
+ ));
+
+ // with duplicates
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_map(foldable(p<1, 1>(), p<1, 99>())),
+ hana::make_map(p<1, 1>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_map(foldable(p<1, 1>(), p<2, 2>(), p<1, 99>())),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_map(foldable(p<1, 1>(), p<2, 2>(), p<1, 99>(), p<2, 99>())),
+ hana::make_map(p<1, 1>(), p<2, 2>())
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_map(foldable(p<1, 1>(), p<2, 2>(), p<1, 99>(), p<2, 99>(), p<3, 3>())),
+ hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>())
+ ));
+ }
+
+ // Map -> Sequence
+ {
+ auto check = [=](auto ...xs) {
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::permutations(sequence(xs...)),
+ hana::to<::Seq>(hana::make_map(xs...))
+ ));
+ };
+
+ check();
+ check(p<1, 1>());
+ check(p<1, 1>(), p<2, 2>());
+ check(p<1, 1>(), p<2, 2>(), p<3, 3>());
+ check(p<1, 1>(), p<2, 2>(), p<3, 3>(), p<4, 4>());
+ }
+
+ // to_map == to<map_tag>
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_map(foldable(p<1, 1>(), p<2, 2>(), p<1, 99>(), p<2, 99>(), p<3, 3>())),
+ hana::to<hana::map_tag>(foldable(p<1, 1>(), p<2, 2>(), p<1, 99>(), p<2, 99>(), p<3, 3>()))
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/map/union.cpp b/src/boost/libs/hana/test/map/union.cpp
new file mode 100644
index 00000000..dfae6ea0
--- /dev/null
+++ b/src/boost/libs/hana/test/map/union.cpp
@@ -0,0 +1,82 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/map.hpp>
+#include <boost/hana/union.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_map(),
+ hana::make_map()
+ ),
+ hana::make_map()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_map(
+ p<1, 1>()
+ ),
+ hana::make_map()
+ ),
+ hana::make_map(p<1, 1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_map(),
+ hana::make_map(p<1, 1>())
+ ),
+ hana::make_map(p<1, 1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_map(p<1, 1>()),
+ hana::make_map(p<1, 1>())
+ ),
+ hana::make_map(p<1, 1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_map(p<1, 2>()),
+ hana::make_map(p<1, 3>())
+ ),
+ hana::make_map(p<1, 3>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_map(p<1, 10>(),
+ p<2, 20>(),
+ p<3, 30>()),
+ hana::make_map(p<4, 40>(),
+ p<5, 50>(),
+ p<1, 100>())
+ ),
+ hana::make_map(p<2, 20>(),
+ p<3, 30>(),
+ p<4, 40>(),
+ p<5, 50>(),
+ p<1, 100>())
+ ));
+}
diff --git a/src/boost/libs/hana/test/map/unpack.cpp b/src/boost/libs/hana/test/map/unpack.cpp
new file mode 100644
index 00000000..63db677a
--- /dev/null
+++ b/src/boost/libs/hana/test/map/unpack.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/assert.hpp>
+#include <boost/hana/contains.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/unpack.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+struct undefined { };
+
+int main() {
+ auto sequence = ::seq;
+ hana::test::_injection<0> f{};
+
+ auto check = [=](auto ...pairs) {
+ auto possible_results = hana::transform(hana::permutations(sequence(pairs...)),
+ [=](auto xs) { return hana::unpack(xs, f); }
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ possible_results,
+ hana::unpack(hana::make_map(pairs...), f)
+ ));
+ };
+
+ check();
+ check(p<1, 1>());
+ check(p<1, 1>(), p<2, 2>());
+ check(p<1, 1>(), p<2, 2>(), p<3, 3>());
+ check(p<1, 1>(), p<2, 2>(), p<3, 3>(), p<4, 4>());
+}
diff --git a/src/boost/libs/hana/test/map/values.cpp b/src/boost/libs/hana/test/map/values.cpp
new file mode 100644
index 00000000..08082c18
--- /dev/null
+++ b/src/boost/libs/hana/test/map/values.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 <boost/hana/contains.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/map.hpp>
+#include <boost/hana/permutations.hpp>
+
+#include <laws/base.hpp>
+#include <support/minimal_product.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+
+
+template <int i>
+auto key() { return hana::test::ct_eq<i>{}; }
+
+template <int i>
+auto val() { return hana::test::ct_eq<-i>{}; }
+
+template <int i, int j>
+auto p() { return ::minimal_product(key<i>(), val<j>()); }
+
+int main() {
+ constexpr auto list = ::seq;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::values(hana::make_map()),
+ list()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::values(hana::make_map(p<1, 1>())),
+ list(val<1>())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::permutations(list(val<1>(), val<2>())),
+ hana::values(hana::make_map(p<1, 1>(), p<2, 2>()))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::permutations(list(val<1>(), val<2>(), val<3>())),
+ hana::values(hana::make_map(p<1, 1>(), p<2, 2>(), p<3, 3>()))
+ ));
+}
diff --git a/src/boost/libs/hana/test/minimal_product.cpp b/src/boost/libs/hana/test/minimal_product.cpp
new file mode 100644
index 00000000..80f214f5
--- /dev/null
+++ b/src/boost/libs/hana/test/minimal_product.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/tuple.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/second.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/orderable.hpp>
+#include <laws/product.hpp>
+#include <support/minimal_product.hpp>
+#include <support/tracked.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+using hana::test::ct_ord;
+
+
+int main() {
+ // Make sure `first` and `second` are "accessors". If they are not,
+ // `Tracked` should report a double-move.
+ {
+ auto prod = ::minimal_product(::Tracked{1}, ::Tracked{2});
+ auto fst = hana::first(std::move(prod));
+ auto snd = hana::second(std::move(prod));
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable, Orderable, Foldable, Product
+ //////////////////////////////////////////////////////////////////////////
+ auto eq_elems = hana::make_tuple(ct_eq<3>{}, ct_eq<4>{});
+
+ auto eqs = hana::make_tuple(
+ ::minimal_product(ct_eq<3>{}, ct_eq<3>{})
+ , ::minimal_product(ct_eq<3>{}, ct_eq<4>{})
+ , ::minimal_product(ct_eq<4>{}, ct_eq<3>{})
+ , ::minimal_product(ct_eq<4>{}, ct_eq<4>{})
+ );
+
+ auto ords = hana::make_tuple(
+ ::minimal_product(ct_ord<3>{}, ct_ord<3>{})
+ , ::minimal_product(ct_ord<3>{}, ct_ord<4>{})
+ , ::minimal_product(ct_ord<4>{}, ct_ord<3>{})
+ , ::minimal_product(ct_ord<4>{}, ct_ord<4>{})
+ );
+
+ hana::test::TestComparable<::MinimalProduct>{eqs};
+ hana::test::TestOrderable<::MinimalProduct>{ords};
+ hana::test::TestFoldable<::MinimalProduct>{eqs};
+ hana::test::TestProduct<::MinimalProduct>{eq_elems};
+}
diff --git a/src/boost/libs/hana/test/monoid.cpp b/src/boost/libs/hana/test/monoid.cpp
new file mode 100644
index 00000000..ca693261
--- /dev/null
+++ b/src/boost/libs/hana/test/monoid.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/concept/monoid.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/zero.hpp>
+
+#include <laws/monoid.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::TestMonoid<int>{hana::make_tuple(0,1,2,3,4,5)};
+ hana::test::TestMonoid<unsigned int>{hana::make_tuple(0u,1u,2u,3u,4u,5u)};
+ hana::test::TestMonoid<long>{hana::make_tuple(0l,1l,2l,3l,4l,5l)};
+ hana::test::TestMonoid<unsigned long>{hana::make_tuple(0ul,1ul,2ul,3ul,4ul,5ul)};
+
+ // zero
+ static_assert(hana::zero<int>() == 0, "");
+
+ // plus
+ static_assert(hana::plus(6, 4) == 6 + 4, "");
+}
diff --git a/src/boost/libs/hana/test/numeric/main.hpp b/src/boost/libs/hana/test/numeric/main.hpp
new file mode 100644
index 00000000..f092cdee
--- /dev/null
+++ b/src/boost/libs/hana/test/numeric/main.hpp
@@ -0,0 +1,511 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/comparing.hpp>
+#include <boost/hana/div.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/greater_equal.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/less_equal.hpp>
+#include <boost/hana/max.hpp>
+#include <boost/hana/min.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/mod.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/negate.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp>
+#include <boost/hana/one.hpp>
+#include <boost/hana/or.hpp>
+#include <boost/hana/ordering.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/power.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/while.hpp>
+#include <boost/hana/zero.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/euclidean_ring.hpp>
+#include <laws/group.hpp>
+#include <laws/logical.hpp>
+#include <laws/monoid.hpp>
+#include <laws/orderable.hpp>
+#include <support/cnumeric.hpp>
+#include <support/numeric.hpp>
+
+#include <cstdlib>
+#include <vector>
+namespace hana = boost::hana;
+
+
+struct invalid {
+ template <typename T>
+ operator T const() { std::abort(); }
+};
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable
+ //////////////////////////////////////////////////////////////////////////
+ {
+ hana::test::_injection<0> f{};
+ auto x = numeric(1);
+ auto y = numeric(2);
+
+ // equal
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(x, x));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(x, y)));
+ }
+
+ // not_equal
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_equal(x, y));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::not_equal(x, x)));
+ }
+
+ // comparing
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::comparing(f)(x, x),
+ hana::equal(f(x), f(x))
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::comparing(f)(x, y),
+ hana::equal(f(x), f(y))
+ ));
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Orderable
+ //////////////////////////////////////////////////////////////////////////
+ {
+ auto ord = numeric;
+
+ // _injection is also monotonic
+ hana::test::_injection<0> f{};
+
+ // less
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::less(ord(0), ord(1)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord(0), ord(0))));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord(1), ord(0))));
+ }
+
+ // less_equal
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::less_equal(ord(0), ord(1)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::less_equal(ord(0), ord(0)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less_equal(ord(1), ord(0))));
+ }
+
+ // greater_equal
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::greater_equal(ord(1), ord(0)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::greater_equal(ord(0), ord(0)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater_equal(ord(0), ord(1))));
+ }
+
+ // greater
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::greater(ord(1), ord(0)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater(ord(0), ord(0))));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater(ord(0), ord(1))));
+ }
+
+ // max
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::max(ord(0), ord(0)), ord(0)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::max(ord(1), ord(0)), ord(1)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::max(ord(0), ord(1)), ord(1)
+ ));
+ }
+
+ // min
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::min(ord(0), ord(0)),
+ ord(0)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::min(ord(1), ord(0)),
+ ord(0)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::min(ord(0), ord(1)),
+ ord(0)
+ ));
+ }
+
+ // ordering
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::ordering(f)(ord(1), ord(0)),
+ hana::less(f(ord(1)), f(ord(0)))
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::ordering(f)(ord(0), ord(1)),
+ hana::less(f(ord(0)), f(ord(1)))
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::ordering(f)(ord(0), ord(0)),
+ hana::less(f(ord(0)), f(ord(0)))
+ ));
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Monoid
+ //////////////////////////////////////////////////////////////////////////
+ {
+ constexpr int x = 2, y = 3;
+
+ // zero
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::zero<Numeric>(), numeric(0)
+ ));
+ }
+
+ // plus
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::plus(numeric(x), numeric(y)),
+ numeric(x + y)
+ ));
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Group
+ //////////////////////////////////////////////////////////////////////////
+ {
+ constexpr int x = 2, y = 3;
+
+ // minus
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::minus(numeric(x), numeric(y)),
+ numeric(x - y)
+ ));
+ }
+
+ // negate
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::negate(numeric(x)),
+ numeric(-x)
+ ));
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Ring
+ //////////////////////////////////////////////////////////////////////////
+ {
+ constexpr int x = 2, y = 3;
+
+ // one
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Numeric>(),
+ numeric(1)
+ ));
+ }
+
+ // mult
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::mult(numeric(x), numeric(y)),
+ numeric(x * y)
+ ));
+ }
+
+ // power
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::power(numeric(x), hana::zero<CNumeric<int>>()),
+ hana::one<Numeric>()
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::power(numeric(x), hana::one<CNumeric<int>>()),
+ numeric(x)
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::power(numeric(x), cnumeric<int, 2>),
+ hana::mult(numeric(x), numeric(x))
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::power(numeric(x), cnumeric<int, 3>),
+ hana::mult(hana::mult(numeric(x), numeric(x)), numeric(x))
+ ));
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // EuclideanRing
+ //////////////////////////////////////////////////////////////////////////
+ {
+ constexpr int x = 6, y = 3, z = 4;
+
+ // div
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::div(numeric(x), numeric(y)),
+ numeric(x / y)
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::div(numeric(x), numeric(z)),
+ numeric(x/ z)
+ ));
+ }
+
+ // mod
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::mod(numeric(x), numeric(y)),
+ numeric(x % y)
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::mod(numeric(x), numeric(z)),
+ numeric(x % z)
+ ));
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Logical
+ //////////////////////////////////////////////////////////////////////////
+ {
+ auto logical = numeric;
+ auto comparable = numeric;
+
+ // not_
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::not_(logical(true)),
+ logical(false)
+ ));
+ }
+
+ // and_
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::and_(logical(true)),
+ logical(true)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::and_(logical(false)),
+ logical(false)
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::and_(logical(true), logical(true)),
+ logical(true)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::and_(logical(true), logical(false)),
+ logical(false)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::and_(logical(false), invalid{}),
+ logical(false)
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::and_(logical(true), logical(true), logical(true)),
+ logical(true)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::and_(logical(true), logical(true), logical(false)),
+ logical(false)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::and_(logical(true), logical(false), invalid{}),
+ logical(false)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::and_(logical(false), invalid{}, invalid{}),
+ logical(false)
+ ));
+ }
+
+ // or_
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::or_(logical(true)),
+ logical(true)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::or_(logical(false)),
+ logical(false)
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::or_(logical(false), logical(false)),
+ logical(false)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::or_(logical(false), logical(true)),
+ logical(true)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::or_(logical(true), invalid{}),
+ logical(true)
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::or_(logical(false), logical(false), logical(false)),
+ logical(false)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::or_(logical(false), logical(false), logical(true)),
+ logical(true)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::or_(logical(false), logical(true), invalid{}),
+ logical(true)
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::or_(logical(true), invalid{}, invalid{}),
+ logical(true)
+ ));
+ }
+
+ // if_
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::if_(logical(true), comparable(0), comparable(1)),
+ comparable(0)
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::if_(logical(false), comparable(0), comparable(1)),
+ comparable(1)
+ ));
+ }
+
+ // eval_if
+ {
+ auto t = [=](auto) { return comparable(0); };
+ auto e = [=](auto) { return comparable(1); };
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::eval_if(logical(true), t, e),
+ comparable(0)
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::eval_if(logical(false), t, e),
+ comparable(1)
+ ));
+ }
+
+ // while_
+ {
+ auto smaller_than = [](auto n) {
+ return [n](auto v) { return v.size() < n; };
+ };
+ auto f = [](auto v) {
+ v.push_back(v.size());
+ return v;
+ };
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(smaller_than(0u), std::vector<int>{}, f),
+ std::vector<int>{}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(smaller_than(1u), std::vector<int>{}, f),
+ std::vector<int>{0}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(smaller_than(2u), std::vector<int>{}, f),
+ std::vector<int>{0, 1}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(smaller_than(3u), std::vector<int>{}, f),
+ std::vector<int>{0, 1, 2}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(smaller_than(4u), std::vector<int>{}, f),
+ std::vector<int>{0, 1, 2, 3}
+ ));
+
+ // Make sure it can be called with an lvalue state:
+ std::vector<int> v{};
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(smaller_than(4u), v, f),
+ std::vector<int>{0, 1, 2, 3}
+ ));
+ }
+
+ // while_
+ {
+ auto less_than = [](auto n) {
+ return [n](auto v) { return v.size() < n; };
+ };
+ auto f = [](auto v) {
+ v.push_back(v.size());
+ return v;
+ };
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(0u), std::vector<int>{}, f),
+ std::vector<int>{}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(1u), std::vector<int>{}, f),
+ std::vector<int>{0}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(2u), std::vector<int>{}, f),
+ std::vector<int>{0, 1}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(3u), std::vector<int>{}, f),
+ std::vector<int>{0, 1, 2}
+ ));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(4u), std::vector<int>{}, f),
+ std::vector<int>{0, 1, 2, 3}
+ ));
+
+ // Make sure it can be called with an lvalue state:
+ std::vector<int> v{};
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::while_(less_than(4u), v, f),
+ std::vector<int>{0, 1, 2, 3}
+ ));
+ }
+ }
+}
diff --git a/src/boost/libs/hana/test/numeric/minus_mcd.cpp b/src/boost/libs/hana/test/numeric/minus_mcd.cpp
new file mode 100644
index 00000000..f5f67d80
--- /dev/null
+++ b/src/boost/libs/hana/test/numeric/minus_mcd.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_GROUP_MINUS_MCD
+#include "main.hpp"
diff --git a/src/boost/libs/hana/test/numeric/negate_mcd.cpp b/src/boost/libs/hana/test/numeric/negate_mcd.cpp
new file mode 100644
index 00000000..996d71ea
--- /dev/null
+++ b/src/boost/libs/hana/test/numeric/negate_mcd.cpp
@@ -0,0 +1,6 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#define BOOST_HANA_TEST_GROUP_NEGATE_MCD
+#include "main.hpp"
diff --git a/src/boost/libs/hana/test/optional/any_of.cpp b/src/boost/libs/hana/test/optional/any_of.cpp
new file mode 100644
index 00000000..74070fb2
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/any_of.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/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ ct_eq<2> x{};
+ ct_eq<3> y{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(hana::just(x), hana::equal.to(x)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(hana::just(x), hana::equal.to(y))));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(hana::nothing, hana::equal.to(x))));
+}
diff --git a/src/boost/libs/hana/test/optional/ap.cpp b/src/boost/libs/hana/test/optional/ap.cpp
new file mode 100644
index 00000000..2636729c
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/ap.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/equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/ap.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(hana::nothing, hana::nothing),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(hana::just(f), hana::nothing),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(hana::nothing, hana::just(ct_eq<3>{})),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::ap(hana::just(f), hana::just(ct_eq<3>{})),
+ hana::just(f(ct_eq<3>{}))
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/chain.cpp b/src/boost/libs/hana/test/optional/chain.cpp
new file mode 100644
index 00000000..be3f0ec6
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/chain.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/chain.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto f = [](auto x) {
+ return hana::just(hana::test::_injection<0>{}(x));
+ };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(hana::just(ct_eq<3>{}), f),
+ f(ct_eq<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::chain(hana::nothing, f),
+ hana::nothing
+ ));
+
+ // test with operators
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::just(ct_eq<3>{}) | f,
+ f(ct_eq<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::nothing | f,
+ hana::nothing
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/concat.cpp b/src/boost/libs/hana/test/optional/concat.cpp
new file mode 100644
index 00000000..40a2a0da
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/concat.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/concat.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto rv_nothing = [] { return hana::nothing; }; // rvalue nothing
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::concat(rv_nothing(), hana::nothing),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::concat(hana::nothing, rv_nothing()),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::concat(rv_nothing(), rv_nothing()),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::concat(rv_nothing(), hana::just(ct_eq<0>{})),
+ hana::just(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::concat(hana::just(ct_eq<0>{}), rv_nothing()),
+ hana::just(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::concat(hana::nothing, hana::nothing),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::concat(hana::nothing, hana::just(ct_eq<0>{})),
+ hana::just(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::concat(hana::just(ct_eq<0>{}), hana::nothing),
+ hana::just(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::concat(hana::just(ct_eq<0>{}), hana::just(ct_eq<1>{})),
+ hana::just(ct_eq<0>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/copy.trap_construct.cpp b/src/boost/libs/hana/test/optional/copy.trap_construct.cpp
new file mode 100644
index 00000000..09410ab3
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/copy.trap_construct.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/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+// This test makes sure that we do not instantiate rogue contructors when
+// trying to copy a hana::just.
+
+int main() {
+ auto just = hana::just(hana::test::trap_construct{});
+ auto implicit_copy = just;
+ decltype(just) explicit_copy(just);
+
+ (void)implicit_copy;
+ (void)explicit_copy;
+}
diff --git a/src/boost/libs/hana/test/optional/empty.cpp b/src/boost/libs/hana/test/optional/empty.cpp
new file mode 100644
index 00000000..38f25f39
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/empty.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/empty.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::empty<hana::optional_tag>(),
+ hana::nothing
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/equal.cpp b/src/boost/libs/hana/test/optional/equal.cpp
new file mode 100644
index 00000000..476888fb
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/equal.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/not.hpp>
+#include <boost/hana/not_equal.hpp> // for operator !=
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::ct_eq<3> x{};
+ hana::test::ct_eq<4> y{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::nothing, hana::nothing));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(hana::nothing, hana::just(x))));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(hana::just(x), hana::nothing)));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::just(x), hana::just(x)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(hana::just(x), hana::just(y))));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::nothing == hana::nothing);
+ BOOST_HANA_CONSTANT_CHECK(hana::just(x) == hana::just(x));
+ BOOST_HANA_CONSTANT_CHECK(hana::just(x) != hana::just(y));
+ BOOST_HANA_CONSTANT_CHECK(hana::just(x) != hana::nothing);
+ BOOST_HANA_CONSTANT_CHECK(hana::nothing != hana::just(x));
+}
diff --git a/src/boost/libs/hana/test/optional/find_if.cpp b/src/boost/libs/hana/test/optional/find_if.cpp
new file mode 100644
index 00000000..7ee20f82
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/find_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/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ ct_eq<2> x{};
+ ct_eq<3> y{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::just(x), hana::equal.to(x)),
+ hana::just(x)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::just(x), hana::equal.to(y)),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::nothing, hana::equal.to(x)),
+ hana::nothing
+ ));
+
+ // Previously, there was a bug that would make this fail.
+ auto non_const_nothing = hana::nothing;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(non_const_nothing, hana::equal.to(x)),
+ hana::nothing
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/flatten.cpp b/src/boost/libs/hana/test/optional/flatten.cpp
new file mode 100644
index 00000000..6a21a50f
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/flatten.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/flatten.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(hana::nothing),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(hana::just(hana::nothing)),
+ hana::nothing
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::flatten(hana::just(hana::just(ct_eq<4>{}))),
+ hana::just(ct_eq<4>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/fold_left.cpp b/src/boost/libs/hana/test/optional/fold_left.cpp
new file mode 100644
index 00000000..8b9dd801
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/fold_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/fold_left.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::ct_eq<2> x{};
+ hana::test::ct_eq<3> s{};
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::just(x), s, f),
+ f(s, x)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::nothing, s, f),
+ s
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/fold_right.cpp b/src/boost/libs/hana/test/optional/fold_right.cpp
new file mode 100644
index 00000000..2d3c1f5c
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/fold_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/fold_right.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::ct_eq<2> x{};
+ hana::test::ct_eq<3> s{};
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::just(x), s, f),
+ f(x, s)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::nothing, s, f),
+ s
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/is_just.cpp b/src/boost/libs/hana/test/optional/is_just.cpp
new file mode 100644
index 00000000..49b1f98c
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/is_just.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/not.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_just(hana::just(undefined{})));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_just(hana::nothing)));
+}
diff --git a/src/boost/libs/hana/test/optional/is_nothing.cpp b/src/boost/libs/hana/test/optional/is_nothing.cpp
new file mode 100644
index 00000000..6bf772ba
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/is_nothing.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/not.hpp>
+#include <boost/hana/optional.hpp>
+namespace hana = boost::hana;
+
+
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_nothing(hana::nothing));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_nothing(hana::just(undefined{}))));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_nothing(hana::just(hana::nothing))));
+}
diff --git a/src/boost/libs/hana/test/optional/laws.cpp b/src/boost/libs/hana/test/optional/laws.cpp
new file mode 100644
index 00000000..9b0b87cc
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/laws.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/bool.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/applicative.hpp>
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/functor.hpp>
+#include <laws/monad.hpp>
+#include <laws/monad_plus.hpp>
+#include <laws/orderable.hpp>
+#include <laws/searchable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+using hana::test::ct_ord;
+
+
+int main() {
+ auto ords = hana::make_tuple(
+ hana::nothing,
+ hana::just(ct_ord<0>{}),
+ hana::just(ct_ord<1>{}),
+ hana::just(ct_ord<2>{})
+ );
+
+ auto eqs = hana::make_tuple(
+ hana::nothing,
+ hana::just(ct_eq<0>{}),
+ hana::just(ct_eq<1>{}),
+ hana::just(ct_eq<2>{})
+ );
+
+ auto eq_values = hana::make_tuple(ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{});
+
+ auto predicates = hana::make_tuple(
+ hana::equal.to(ct_eq<0>{}),
+ hana::equal.to(ct_eq<2>{}),
+ hana::equal.to(ct_eq<3>{}),
+ hana::always(hana::false_c),
+ hana::always(hana::true_c)
+ );
+
+ auto nested_eqs = hana::make_tuple(
+ hana::nothing,
+ hana::just(hana::just(ct_eq<0>{})),
+ hana::just(hana::nothing),
+ hana::just(hana::just(ct_eq<2>{}))
+ );
+
+
+ hana::test::TestComparable<hana::optional_tag>{eqs};
+ hana::test::TestOrderable<hana::optional_tag>{ords};
+ hana::test::TestFunctor<hana::optional_tag>{eqs, eq_values};
+ hana::test::TestApplicative<hana::optional_tag>{eqs};
+ hana::test::TestMonad<hana::optional_tag>{eqs, nested_eqs};
+ hana::test::TestMonadPlus<hana::optional_tag>{eqs, predicates, eq_values};
+ hana::test::TestSearchable<hana::optional_tag>{eqs, eq_values};
+ hana::test::TestSearchable<hana::optional_tag>{
+ hana::make_tuple(
+ hana::just(hana::true_c),
+ hana::just(hana::false_c),
+ hana::nothing
+ ),
+ hana::make_tuple(hana::true_c, hana::false_c)
+ };
+ hana::test::TestFoldable<hana::optional_tag>{eqs};
+}
diff --git a/src/boost/libs/hana/test/optional/less.cpp b/src/boost/libs/hana/test/optional/less.cpp
new file mode 100644
index 00000000..05c5d8a7
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/less.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/greater.hpp>
+#include <boost/hana/greater_equal.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/less_equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_ord;
+
+
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::nothing < hana::just(undefined{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::just(ct_ord<3>{}) < hana::just(ct_ord<4>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::just(ct_ord<3>{}) <= hana::just(ct_ord<4>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::just(ct_ord<4>{}) > hana::just(ct_ord<3>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::just(ct_ord<4>{}) >= hana::just(ct_ord<3>{}));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ hana::nothing,
+ hana::just(undefined{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ hana::just(undefined{}),
+ hana::nothing
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ hana::nothing,
+ hana::nothing
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ hana::just(ct_ord<3>{}),
+ hana::just(ct_ord<4>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ hana::just(ct_ord<3>{}),
+ hana::just(ct_ord<3>{})
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ hana::just(ct_ord<4>{}),
+ hana::just(ct_ord<3>{})
+ )));
+}
diff --git a/src/boost/libs/hana/test/optional/lift.cpp b/src/boost/libs/hana/test/optional/lift.cpp
new file mode 100644
index 00000000..25641bee
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/lift.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/lift.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::lift<hana::optional_tag>(ct_eq<3>{}),
+ hana::just(ct_eq<3>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/make.cpp b/src/boost/libs/hana/test/optional/make.cpp
new file mode 100644
index 00000000..e436d6ce
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/make.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/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::optional_tag>(),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::optional_tag>(ct_eq<3>{}),
+ hana::just(ct_eq<3>{})
+ ));
+
+ // Check that make_optional == make<optional_tag>
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_optional(),
+ hana::make<hana::optional_tag>()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_optional(ct_eq<3>{}),
+ hana::make<hana::optional_tag>(ct_eq<3>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/maybe.cpp b/src/boost/libs/hana/test/optional/maybe.cpp
new file mode 100644
index 00000000..ca3d154e
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/maybe.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/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+struct undefined { };
+
+int main() {
+ hana::test::_injection<0> f{};
+ hana::test::ct_eq<2> x{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::maybe(x, undefined{}, hana::nothing),
+ x
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::maybe(undefined{}, f, hana::just(x)),
+ f(x)
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/nested_type.cpp b/src/boost/libs/hana/test/optional/nested_type.cpp
new file mode 100644
index 00000000..6e85c204
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/nested_type.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/optional.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// This test makes sure that an optional holding a hana::type has a
+// nested ::type alias.
+
+
+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
+{ };
+
+
+struct T;
+
+static_assert(std::is_same<decltype(hana::just(hana::type_c<T>))::type, T>{}, "");
+static_assert(!has_type<decltype(hana::nothing)>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/optional/operator_arrow.cpp b/src/boost/libs/hana/test/optional/operator_arrow.cpp
new file mode 100644
index 00000000..691d8981
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/operator_arrow.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/equal.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct object {
+ ct_eq<3> member;
+};
+
+int main() {
+ auto lvalue = hana::just(object{});
+ ct_eq<3>& ref = lvalue->member;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ ref,
+ ct_eq<3>{}
+ ));
+
+ auto const const_lvalue = hana::just(object{});
+ ct_eq<3> const& const_ref = const_lvalue->member;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ const_ref,
+ ct_eq<3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::just(object{})->member,
+ ct_eq<3>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/operator_deref.cpp b/src/boost/libs/hana/test/optional/operator_deref.cpp
new file mode 100644
index 00000000..271094b4
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/operator_deref.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/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto lvalue = hana::just(ct_eq<3>{});
+ ct_eq<3>& ref = *lvalue;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ ref,
+ ct_eq<3>{}
+ ));
+
+ auto const const_lvalue = hana::just(ct_eq<3>{});
+ ct_eq<3> const& const_ref = *const_lvalue;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ const_ref,
+ ct_eq<3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ *hana::just(ct_eq<3>{}),
+ ct_eq<3>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/representation.cpp b/src/boost/libs/hana/test/optional/representation.cpp
new file mode 100644
index 00000000..d7a719e3
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/representation.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/optional.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct Foo { };
+
+int main() {
+ auto just = hana::just(Foo{});
+ static_assert(std::is_same<decltype(just), hana::optional<Foo>>{}, "");
+
+ auto nothing = hana::nothing;
+ static_assert(std::is_same<decltype(nothing), hana::optional<>>{}, "");
+}
diff --git a/src/boost/libs/hana/test/optional/sfinae.cpp b/src/boost/libs/hana/test/optional/sfinae.cpp
new file mode 100644
index 00000000..e821c248
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/sfinae.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/assert.hpp>
+#include <boost/hana/chain.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <laws/base.hpp>
+#include <support/tracked.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct undefined { };
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sfinae(f)(),
+ hana::just(f())
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sfinae(f)(ct_eq<0>{}),
+ hana::just(f(ct_eq<0>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sfinae(f)(ct_eq<0>{}, ct_eq<1>{}),
+ hana::just(f(ct_eq<0>{}, ct_eq<1>{}))
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sfinae(undefined{})(),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sfinae(undefined{})(ct_eq<0>{}),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sfinae(undefined{})(ct_eq<0>{}, ct_eq<1>{}),
+ hana::nothing
+ ));
+
+ auto incr = hana::sfinae([](auto x) -> decltype(x + 1) {
+ return x + 1;
+ });
+
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ incr(1),
+ hana::just(2)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ incr(undefined{}),
+ hana::nothing
+ ));
+ BOOST_HANA_RUNTIME_CHECK(hana::equal(
+ hana::chain(hana::just(1), incr),
+ hana::just(2)
+ ));
+
+ // using `sfinae` with a non-pod argument used to fail
+ hana::sfinae(undefined{})(Tracked{1});
+ hana::sfinae([t = Tracked{1}](auto) { return 1; })(Tracked{1});
+}
diff --git a/src/boost/libs/hana/test/optional/transform.cpp b/src/boost/libs/hana/test/optional/transform.cpp
new file mode 100644
index 00000000..84f44dcf
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/transform.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/optional.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct undefined { };
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::nothing, undefined{}),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::just(ct_eq<3>{}), f),
+ hana::just(f(ct_eq<3>{}))
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/unpack.cpp b/src/boost/libs/hana/test/optional/unpack.cpp
new file mode 100644
index 00000000..5968d33a
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/unpack.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/equal.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::ct_eq<2> x{};
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::nothing, f),
+ f()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::just(x), f),
+ f(x)
+ ));
+
+ // Previously, there was a bug that would make this fail.
+ auto non_const_nothing = hana::nothing;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(non_const_nothing, f),
+ f()
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/value.cpp b/src/boost/libs/hana/test/optional/value.cpp
new file mode 100644
index 00000000..710d73c7
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/value.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/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto lvalue = hana::just(ct_eq<3>{});
+ ct_eq<3>& ref = lvalue.value();
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ ref,
+ ct_eq<3>{}
+ ));
+
+ auto const const_lvalue = hana::just(ct_eq<3>{});
+ ct_eq<3> const& const_ref = const_lvalue.value();
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ const_ref,
+ ct_eq<3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::just(ct_eq<3>{}).value(),
+ ct_eq<3>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/optional/value_or.cpp b/src/boost/libs/hana/test/optional/value_or.cpp
new file mode 100644
index 00000000..05fa784f
--- /dev/null
+++ b/src/boost/libs/hana/test/optional/value_or.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/optional.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct undefined { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::nothing.value_or(ct_eq<3>{}),
+ ct_eq<3>{}
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::just(ct_eq<4>{}).value_or(undefined{}),
+ ct_eq<4>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/orderable.cpp b/src/boost/libs/hana/test/orderable.cpp
new file mode 100644
index 00000000..8c6ce4f6
--- /dev/null
+++ b/src/boost/libs/hana/test/orderable.cpp
@@ -0,0 +1,126 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/orderable.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/greater_equal.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/less_equal.hpp>
+#include <boost/hana/max.hpp>
+#include <boost/hana/min.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/orderable.hpp>
+
+#include <string>
+#include <type_traits>
+namespace hana = boost::hana;
+using namespace std::literals;
+
+
+// Minimal LessThanComparable types
+struct ord1 { int value; };
+struct ord2 {
+ int value;
+ constexpr operator ord1() const { return {value}; }
+};
+
+template <typename T, typename U, typename = std::enable_if_t<
+ (std::is_same<T, ord1>{} || std::is_same<T, ord2>{}) &&
+ (std::is_same<U, ord1>{} || std::is_same<U, ord2>{})
+>>
+constexpr bool operator<(T a, U b)
+{ return a.value < b.value; }
+
+namespace boost { namespace hana {
+ template <typename T, typename U>
+ struct equal_impl<T, U, when<
+ (std::is_same<T, ord1>{} || std::is_same<T, ord2>{}) &&
+ (std::is_same<U, ord1>{} || std::is_same<U, ord2>{})
+ >> {
+ static constexpr bool apply(T a, U b)
+ { return a.value == b.value; }
+ };
+}}
+
+int main() {
+ // laws
+ hana::test::TestOrderable<int>{hana::make_tuple(0,1,2,3,4,5)};
+ hana::test::TestOrderable<unsigned int>{hana::make_tuple(0u,1u,2u,3u,4u,5u)};
+ hana::test::TestOrderable<long>{hana::make_tuple(0l,1l,2l,3l,4l,5l)};
+ hana::test::TestOrderable<unsigned long>{hana::make_tuple(0ul,1ul,2ul,3ul,4ul,5ul)};
+ hana::test::TestOrderable<ord1>{hana::make_tuple(ord1{0}, ord1{1}, ord1{2}, ord1{3}, ord1{4})};
+
+ // Orderable => Comparable
+ hana::test::TestComparable<ord1>{hana::make_tuple(ord1{0}, ord1{1}, ord1{2}, ord1{3}, ord1{4})};
+
+ // less
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::less(5, 6));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(6, 6)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(7, 6)));
+
+ // Provided model for LessThanComparable types
+ BOOST_HANA_CONSTEXPR_CHECK(hana::less(ord1{0}, ord1{1}));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord1{0}, ord1{0})));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord1{1}, ord1{0})));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::less(ord1{0}, ord2{1}));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord1{0}, ord2{0})));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord1{1}, ord2{0})));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::less(ord2{0}, ord1{1}));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord2{0}, ord1{0})));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord2{1}, ord1{0})));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::less("ab", "abc"s));
+ BOOST_HANA_RUNTIME_CHECK(hana::less("abc"s, "abcde"));
+ }
+
+ // greater
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater(5, 6)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater(6, 6)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::greater(7, 6));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::greater("abcd", "ab"s));
+ BOOST_HANA_RUNTIME_CHECK(hana::greater("abc"s, "abb"));
+ }
+
+ // less_equal
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::less_equal(5, 6));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::less_equal(6, 6));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less_equal(7, 6)));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::less_equal("ab", "abcd"s));
+ BOOST_HANA_RUNTIME_CHECK(hana::less_equal("abc"s, "abc"));
+ }
+
+ // greater_equal
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater_equal(5, 6)));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::greater_equal(6, 6));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::greater_equal(7, 6));
+
+ BOOST_HANA_RUNTIME_CHECK(hana::greater_equal("abcd", "ab"s));
+ BOOST_HANA_RUNTIME_CHECK(hana::greater_equal("abc"s, "abc"));
+ }
+
+ // min
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(hana::min(5, 6), 5));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(hana::min(6, 5), 5));
+ }
+
+ // max
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(hana::max(5, 6), 6));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(hana::max(6, 5), 6));
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/assign.copy.cpp b/src/boost/libs/hana/test/pair/assign.copy.cpp
new file mode 100644
index 00000000..ddcf97c3
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/assign.copy.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/config.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto in_constexpr_context(int a, short b) {
+ hana::pair<int, short> p1(a, b);
+ hana::pair<int, short> p2;
+ hana::pair<double, long> p3;
+ p2 = p1;
+ p3 = p2;
+ return p3;
+}
+
+int main() {
+ {
+ hana::pair<int, short> p1(3, 4);
+ hana::pair<double, long> p2;
+ p2 = p1;
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ // make sure that also works in a constexpr context
+ // (test fails under GCC <= 6 due to buggy constexpr)
+#if BOOST_HANA_CONFIG_GCC >= BOOST_HANA_CONFIG_VERSION(7, 0, 0)
+ {
+ constexpr auto p = in_constexpr_context(3, 4);
+ static_assert(hana::first(p) == 3, "");
+ static_assert(hana::second(p) == 4, "");
+ }
+#endif
+}
diff --git a/src/boost/libs/hana/test/pair/assign.move.cpp b/src/boost/libs/hana/test/pair/assign.move.cpp
new file mode 100644
index 00000000..5d3fd18d
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/assign.move.cpp
@@ -0,0 +1,70 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data = 1) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+};
+
+struct MoveOnlyDerived : MoveOnly {
+ MoveOnlyDerived(MoveOnlyDerived&&) = default;
+ MoveOnlyDerived(int data = 1) : MoveOnly(data) { }
+};
+
+constexpr auto in_constexpr_context(int a, short b) {
+ hana::pair<int, short> p1(a, b);
+ hana::pair<int, short> p2;
+ hana::pair<double, long> p3;
+ p2 = std::move(p1);
+ p3 = std::move(p2);
+ return p3;
+}
+
+int main() {
+ // from pair<T, U> to pair<T, U>
+ {
+ hana::pair<MoveOnly, short> p1(MoveOnly{3}, 4);
+ hana::pair<MoveOnly, short> p2;
+ p2 = std::move(p1);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ // from pair<T, U> to pair<V, W>
+ {
+ hana::pair<MoveOnlyDerived, short> p1(MoveOnlyDerived{3}, 4);
+ hana::pair<MoveOnly, long> p2;
+ p2 = std::move(p1);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ // make sure that also works in a constexpr context
+ // (test fails under GCC <= 6 due to buggy constexpr)
+#if BOOST_HANA_CONFIG_GCC >= BOOST_HANA_CONFIG_VERSION(7, 0, 0)
+ {
+ constexpr auto p = in_constexpr_context(3, 4);
+ static_assert(hana::first(p) == 3, "");
+ static_assert(hana::second(p) == 4, "");
+ }
+#endif
+}
diff --git a/src/boost/libs/hana/test/pair/cnstr.copy.cpp b/src/boost/libs/hana/test/pair/cnstr.copy.cpp
new file mode 100644
index 00000000..fcf46c4e
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/cnstr.copy.cpp
@@ -0,0 +1,94 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename Target>
+struct implicit_to {
+ constexpr operator Target() const { return Target{}; }
+};
+
+struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+};
+
+// Note: It is also useful to check with a non-empty class, because that
+// triggers different instantiations due to EBO.
+struct NoCopy_nonempty {
+ NoCopy_nonempty() = default;
+ NoCopy_nonempty(NoCopy_nonempty const&) = delete;
+ int i;
+};
+
+int main() {
+ {
+ typedef std::pair<int, short> P1;
+ hana::pair<int, short> p1(3, 4);
+ hana::pair<int, short> p2 = p1;
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ static_assert(std::is_trivially_copy_constructible<hana::pair<int, int>>{}, "");
+
+ // make sure it also works constexpr
+ {
+ constexpr hana::pair<int, short> p1(3, 4);
+ constexpr hana::pair<int, short> p2 = p1;
+ static_assert(hana::first(p2) == 3, "");
+ static_assert(hana::second(p2) == 4, "");
+ }
+
+ // Make sure it works across pair types (pair<T, U> -> pair<U, V>)
+ {
+ hana::pair<int, short> p1(3, 4);
+ hana::pair<double, long> p2 = p1;
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+ {
+ struct target1 { };
+ struct target2 { };
+ using Target = hana::pair<target1, target2>;
+
+ auto p1_ = hana::make_pair(target1{}, target2{});
+ Target p1(p1_); (void)p1;
+
+ auto p2_ = hana::make_pair(implicit_to<target1>{}, target2{});
+ Target p2(p2_); (void)p2;
+
+ auto p3_ = hana::make_pair(target1{}, implicit_to<target2>{});
+ Target p3(p3_); (void)p3;
+
+ auto p4_ = hana::make_pair(implicit_to<target1>{}, implicit_to<target2>{});
+ Target p4(p4_); (void)p4;
+ }
+
+ // And also constexpr across pair types
+ {
+ constexpr hana::pair<int, short> p1(3, 4);
+ constexpr hana::pair<double, long> p2 = p1;
+ static_assert(hana::first(p2) == 3, "");
+ static_assert(hana::second(p2) == 4, "");
+ }
+
+ // Make sure we don't define the copy constructor when it shouldn't be defined.
+ {
+ using Pair1 = hana::pair<NoCopy, NoCopy>;
+ Pair1 pair1; (void)pair1;
+ static_assert(!std::is_copy_constructible<Pair1>::value, "");
+
+ using Pair2 = hana::pair<NoCopy_nonempty, NoCopy_nonempty>;
+ Pair2 pair2; (void)pair2;
+ static_assert(!std::is_copy_constructible<Pair2>::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/cnstr.default.cpp b/src/boost/libs/hana/test/pair/cnstr.default.cpp
new file mode 100644
index 00000000..4bffb757
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/cnstr.default.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/assert.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct NoDefault {
+ NoDefault() = delete;
+ explicit constexpr NoDefault(int) { }
+};
+
+struct NoDefault_nonempty {
+ NoDefault_nonempty() = delete;
+ explicit constexpr NoDefault_nonempty(int k) : i(k) { }
+ int i;
+};
+
+struct DefaultOnly {
+ DefaultOnly() = default;
+ DefaultOnly(DefaultOnly const&) = delete;
+ DefaultOnly(DefaultOnly&&) = delete;
+};
+
+struct NonConstexprDefault {
+ NonConstexprDefault() { }
+};
+
+int main() {
+ {
+ hana::pair<float, short*> p;
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == 0.0f);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == nullptr);
+ }
+
+ // make sure it also works constexpr
+ {
+ constexpr hana::pair<float, short*> p;
+ static_assert(hana::first(p) == 0.0f, "");
+ static_assert(hana::second(p) == nullptr, "");
+ }
+
+ // make sure the default constructor is not instantiated when the
+ // members of the pair are not default-constructible
+ {
+ using Pair1 = hana::pair<NoDefault, NoDefault>;
+ Pair1 p1{NoDefault{1}, NoDefault{2}}; (void)p1;
+ static_assert(!std::is_default_constructible<Pair1>{}, "");
+
+ using Pair2 = hana::pair<NoDefault_nonempty, NoDefault_nonempty>;
+ Pair2 p2{NoDefault_nonempty{1}, NoDefault_nonempty{2}}; (void)p2;
+ static_assert(!std::is_default_constructible<Pair2>{}, "");
+ }
+
+ // make sure it works when only the default constructor is defined
+ {
+ hana::pair<DefaultOnly, DefaultOnly> p;
+ (void)p;
+ }
+
+ {
+ hana::pair<NonConstexprDefault, NonConstexprDefault> p;
+ (void)p;
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/cnstr.memberwise.cpp b/src/boost/libs/hana/test/pair/cnstr.memberwise.cpp
new file mode 100644
index 00000000..badede7c
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/cnstr.memberwise.cpp
@@ -0,0 +1,87 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/pair.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+};
+
+class FromInt {
+ int data_;
+public:
+ constexpr FromInt(int data) : data_(data) { }
+ constexpr bool operator==(const FromInt& x) const { return data_ == x.data_; }
+};
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // Check for the pair(T&&, U&&) constructor
+ //////////////////////////////////////////////////////////////////////////
+ {
+ hana::pair<MoveOnly, short*> p(MoveOnly{3}, nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == nullptr);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Check for the pair(First const&, Second const&) constructor
+ //////////////////////////////////////////////////////////////////////////
+ {
+ hana::pair<float, short*> p1(3.5f, 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p1) == 3.5f);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p1) == nullptr);
+
+ // brace init
+ hana::pair<float, short*> p2 = {3.5f, 0};
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3.5f);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == nullptr);
+ }
+ {
+ hana::pair<FromInt, int> p1(1, 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p1) == FromInt(1));
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p1) == 2);
+
+ // brace init
+ hana::pair<FromInt, int> p2 = {1, 2};
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == FromInt(1));
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 2);
+ }
+
+ // Make sure the above works constexpr too
+ {
+ constexpr hana::pair<float, short*> p1(3.5f, 0);
+ static_assert(hana::first(p1) == 3.5f, "");
+ static_assert(hana::second(p1) == nullptr, "");
+
+ // brace init
+ constexpr hana::pair<float, short*> p2 = {3.5f, 0};
+ static_assert(hana::first(p2) == 3.5f, "");
+ static_assert(hana::second(p2) == nullptr, "");
+ }
+ {
+ constexpr hana::pair<FromInt, int> p1(1, 2);
+ static_assert(hana::first(p1) == FromInt(1), "");
+ static_assert(hana::second(p1) == 2, "");
+
+ // brace init
+ constexpr hana::pair<FromInt, int> p2 = {1, 2};
+ static_assert(hana::first(p2) == FromInt(1), "");
+ static_assert(hana::second(p2) == 2, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/cnstr.move.cpp b/src/boost/libs/hana/test/pair/cnstr.move.cpp
new file mode 100644
index 00000000..cb13e724
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/cnstr.move.cpp
@@ -0,0 +1,97 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+};
+
+struct MoveOnlyDerived : MoveOnly {
+ MoveOnlyDerived(MoveOnlyDerived&&) = default;
+ MoveOnlyDerived(int data = 1) : MoveOnly(data) { }
+};
+
+template <typename Target>
+struct implicit_to {
+ constexpr operator Target() const { return Target{}; }
+};
+
+struct NoMove {
+ NoMove() = default;
+ NoMove(NoMove const&) = delete;
+ NoMove(NoMove&&) = delete;
+};
+
+// Note: It is also useful to check with a non-empty class, because that
+// triggers different instantiations due to EBO.
+struct NoMove_nonempty {
+ NoMove_nonempty() = default;
+ NoMove_nonempty(NoMove_nonempty const&) = delete;
+ NoMove_nonempty(NoMove_nonempty&&) = delete;
+ int i;
+};
+
+int main() {
+ {
+ hana::pair<MoveOnly, short> p1(MoveOnly{3}, 4);
+ hana::pair<MoveOnly, short> p2(std::move(p1));
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ // Make sure it works across pair types
+ {
+ hana::pair<MoveOnlyDerived, short> p1(MoveOnlyDerived{3}, 4);
+ hana::pair<MoveOnly, long> p2 = std::move(p1);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+ {
+ struct target1 {
+ target1() = default;
+ target1(target1 const&) = delete;
+ target1(target1&&) = default;
+ };
+
+ struct target2 {
+ target2() = default;
+ target2(target2 const&) = delete;
+ target2(target2&&) = default;
+ };
+ using Target = hana::pair<target1, target2>;
+ Target p1(hana::make_pair(target1{}, target2{})); (void)p1;
+ Target p2(hana::make_pair(implicit_to<target1>{}, target2{})); (void)p2;
+ Target p3(hana::make_pair(target1{}, implicit_to<target2>{})); (void)p3;
+ Target p4(hana::make_pair(implicit_to<target1>{}, implicit_to<target2>{})); (void)p4;
+ }
+
+ // Make sure we don't define the move constructor when it shouldn't be defined.
+ {
+ using Pair1 = hana::pair<NoMove, NoMove>;
+ Pair1 pair1; (void)pair1;
+ static_assert(!std::is_move_constructible<Pair1>::value, "");
+
+ using Pair2 = hana::pair<NoMove_nonempty, NoMove_nonempty>;
+ Pair2 pair2; (void)pair2;
+ static_assert(!std::is_move_constructible<Pair2>::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/comparable.cpp b/src/boost/libs/hana/test/pair/comparable.cpp
new file mode 100644
index 00000000..13537c9e
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/comparable.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/pair.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_eq<1>{}, ct_eq<2>{}) ==
+ hana::make_pair(ct_eq<1>{}, ct_eq<2>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_eq<1>{}, ct_eq<3>{}) !=
+ hana::make_pair(ct_eq<1>{}, ct_eq<2>{})
+ );
+
+ hana::test::TestComparable<hana::pair_tag>{hana::make_tuple(
+ hana::make_pair(ct_eq<3>{}, ct_eq<3>{})
+ , hana::make_pair(ct_eq<3>{}, ct_eq<4>{})
+ , hana::make_pair(ct_eq<4>{}, ct_eq<3>{})
+ , hana::make_pair(ct_eq<4>{}, ct_eq<4>{})
+ )};
+}
diff --git a/src/boost/libs/hana/test/pair/empty_storage.cpp b/src/boost/libs/hana/test/pair/empty_storage.cpp
new file mode 100644
index 00000000..00004148
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/empty_storage.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/pair.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct empty1 { };
+struct empty2 { };
+struct empty3 { };
+struct empty4 { };
+
+// Make sure the storage of a pair is compressed
+static_assert(sizeof(hana::pair<empty1, int>) == sizeof(int), "");
+static_assert(sizeof(hana::pair<int, empty1>) == sizeof(int), "");
+
+// Also make sure that a pair with only empty members is empty too. This is
+// important to ensure, for example, that a tuple of pairs of empty objects
+// will get the EBO.
+static_assert(std::is_empty<hana::pair<empty1, empty2>>{}, "");
+
+// Make sure that a pair of empty pairs is still empty.
+static_assert(std::is_empty<
+ hana::pair<hana::pair<empty1, empty2>, empty3>
+>{}, "");
+
+static_assert(std::is_empty<
+ hana::pair<hana::pair<empty1, empty2>, hana::pair<empty3, empty4>>
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/pair/foldable.cpp b/src/boost/libs/hana/test/pair/foldable.cpp
new file mode 100644
index 00000000..88dc6827
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/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/pair.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+#include <laws/foldable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_pair(ct_eq<1>{}, ct_eq<2>{}), f),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ hana::test::TestFoldable<hana::pair_tag>{hana::make_tuple(
+ hana::make_pair(ct_eq<3>{}, ct_eq<3>{})
+ , hana::make_pair(ct_eq<3>{}, ct_eq<4>{})
+ , hana::make_pair(ct_eq<4>{}, ct_eq<3>{})
+ , hana::make_pair(ct_eq<4>{}, ct_eq<4>{})
+ )};
+}
diff --git a/src/boost/libs/hana/test/pair/issue_90.cpp b/src/boost/libs/hana/test/pair/issue_90.cpp
new file mode 100644
index 00000000..a46623e8
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/issue_90.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/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <typename T>
+T const& cref(T& t) { return t; }
+
+// a non-movable, non-copyable type
+struct RefOnly {
+ RefOnly() = default;
+ RefOnly(RefOnly const&) = delete;
+ RefOnly(RefOnly&&) = delete;
+};
+
+int main() {
+ // This test makes sure that we return the proper reference types from
+ // `first` and `second`.
+ hana::pair<RefOnly, RefOnly> p;
+
+ {
+ RefOnly&& r1 = hana::first(std::move(p));
+ RefOnly& r2 = hana::first(p);
+ RefOnly const& r3 = hana::first(cref(p));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ {
+ RefOnly&& r1 = hana::second(std::move(p));
+ RefOnly& r2 = hana::second(p);
+ RefOnly const& r3 = hana::second(cref(p));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/make.cpp b/src/boost/libs/hana/test/pair/make.cpp
new file mode 100644
index 00000000..3db5030a
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/make.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/core/make.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+};
+
+int main() {
+ {
+ hana::pair<int, short> p = hana::make_pair(3, 4);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == 4);
+ }
+
+ {
+ hana::pair<MoveOnly, short> p = hana::make_pair(MoveOnly{3}, 4);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == 4);
+ }
+
+ {
+ hana::pair<MoveOnly, short> p = hana::make_pair(3, 4);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == 4);
+ }
+
+ {
+ constexpr hana::pair<int, short> p = hana::make_pair(3, 4);
+ static_assert(hana::first(p) == 3, "");
+ static_assert(hana::second(p) == 4, "");
+ }
+
+ // equivalence with make<pair_tag>
+ {
+ constexpr hana::pair<int, short> p = hana::make<hana::pair_tag>(3, 4);
+ static_assert(hana::first(p) == 3, "");
+ static_assert(hana::second(p) == 4, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/orderable.cpp b/src/boost/libs/hana/test/pair/orderable.cpp
new file mode 100644
index 00000000..fabd828d
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/orderable.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/assert.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/greater_equal.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/less_equal.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/orderable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_ord;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_ord<1>{}, ct_ord<2>{}) <
+ hana::make_pair(ct_ord<3>{}, ct_ord<2>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_ord<1>{}, ct_ord<2>{}) <=
+ hana::make_pair(ct_ord<3>{}, ct_ord<2>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_ord<3>{}, ct_ord<2>{}) >=
+ hana::make_pair(ct_ord<1>{}, ct_ord<2>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_ord<3>{}, ct_ord<2>{}) >
+ hana::make_pair(ct_ord<1>{}, ct_ord<2>{})
+ );
+
+ hana::test::TestOrderable<hana::pair_tag>{hana::make_tuple(
+ hana::make_pair(ct_ord<3>{}, ct_ord<3>{})
+ , hana::make_pair(ct_ord<3>{}, ct_ord<4>{})
+ , hana::make_pair(ct_ord<4>{}, ct_ord<3>{})
+ , hana::make_pair(ct_ord<4>{}, ct_ord<4>{})
+ )};
+}
diff --git a/src/boost/libs/hana/test/pair/product.cpp b/src/boost/libs/hana/test/pair/product.cpp
new file mode 100644
index 00000000..b87f06ac
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/product.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/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/product.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ // first, second
+ {
+ hana::pair<ct_eq<1>, ct_eq<2>> p;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::first(p), ct_eq<1>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::second(p), ct_eq<2>{}));
+ }
+
+ hana::test::TestProduct<hana::pair_tag>{hana::make_tuple(
+ ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}
+ )};
+}
diff --git a/src/boost/libs/hana/test/pair/tag_of.cpp b/src/boost/libs/hana/test/pair/tag_of.cpp
new file mode 100644
index 00000000..285b892e
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/tag_of.cpp
@@ -0,0 +1,36 @@
+// Copyright Louis Dionne 2013-2016
+// Distributed under the 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 <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/pair.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ struct T { }; struct U { };
+ static_assert(std::is_same<
+ hana::tag_of<hana::pair<T, U>>::type,
+ hana::pair_tag
+ >{}, "");
+ }
+
+ // Bug #1
+ {
+ using Pair = hana::pair<hana::integral_constant<int, 3>, int>;
+ using PairTag = hana::tag_of<Pair>::type;
+ using Tag = hana::tag_of<std::integral_constant<unsigned long, 0>>::type;
+ }
+
+ // Bug #2
+ {
+ using Pair = hana::pair<std::integral_constant<int, 3>, int>;
+ using PairTag = hana::tag_of<Pair>::type;
+ using Tag = hana::tag_of<std::integral_constant<unsigned long, 0>>::type;
+ }
+}
diff --git a/src/boost/libs/hana/test/range/at.cpp b/src/boost/libs/hana/test/range/at.cpp
new file mode 100644
index 00000000..b57c4de8
--- /dev/null
+++ b/src/boost/libs/hana/test/range/at.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/at.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;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_range(hana::int_c<0>, hana::int_c<10>)[hana::int_c<2>],
+ hana::int_c<2>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(hana::make_range(hana::int_c<0>, hana::int_c<1>), hana::int_c<0>),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(hana::make_range(hana::int_c<0>, hana::int_c<2>), hana::int_c<0>),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(hana::make_range(hana::int_c<0>, hana::int_c<2>), hana::int_c<1>),
+ hana::int_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(hana::make_range(hana::int_c<4>, hana::int_c<90>), hana::int_c<46>),
+ hana::int_c<50>
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/back.cpp b/src/boost/libs/hana/test/range/back.cpp
new file mode 100644
index 00000000..c6c666e6
--- /dev/null
+++ b/src/boost/libs/hana/test/range/back.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/back.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;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::back(hana::make_range(hana::int_c<0>, hana::int_c<1>)),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::back(hana::make_range(hana::int_c<0>, hana::int_c<2>)),
+ hana::int_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::back(hana::make_range(hana::int_c<0>, hana::int_c<3>)),
+ hana::int_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::back(hana::make_range(hana::int_c<3>, hana::int_c<6>)),
+ hana::int_c<5>
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/contains.cpp b/src/boost/libs/hana/test/range/contains.cpp
new file mode 100644
index 00000000..7a9c5082
--- /dev/null
+++ b/src/boost/libs/hana/test/range/contains.cpp
@@ -0,0 +1,56 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/make.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/range.hpp>
+
+#include <support/cnumeric.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_range(hana::int_c<0>, hana::int_c<0>),
+ cnumeric<int, 0>
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_range(hana::int_c<0>, hana::int_c<1>),
+ cnumeric<int, 0>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_range(hana::int_c<0>, hana::int_c<10>),
+ cnumeric<int, 3>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_range(hana::int_c<0>, hana::int_c<10>),
+ cnumeric<int, 9>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_range(hana::int_c<-10>, hana::int_c<10>),
+ cnumeric<int, -10>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::make_range(hana::int_c<-10>, hana::int_c<10>),
+ cnumeric<int, -5>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_range(hana::int_c<-10>, hana::int_c<0>),
+ cnumeric<int, 3>
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ hana::make_range(hana::int_c<0>, hana::int_c<10>),
+ cnumeric<int, 15>
+ )));
+}
diff --git a/src/boost/libs/hana/test/range/drop_front.cpp b/src/boost/libs/hana/test/range/drop_front.cpp
new file mode 100644
index 00000000..16c0e9ef
--- /dev/null
+++ b/src/boost/libs/hana/test/range/drop_front.cpp
@@ -0,0 +1,75 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/drop_front.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<0>), hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<0>), hana::int_c<1>),
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<0>), hana::int_c<2>),
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<1>), hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<1>), hana::int_c<1>),
+ hana::make_range(hana::int_c<1>, hana::int_c<1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<1>), hana::int_c<2>),
+ hana::make_range(hana::int_c<1>, hana::int_c<1>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<2>), hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<2>), hana::int_c<1>),
+ hana::make_range(hana::int_c<1>, hana::int_c<2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<2>), hana::int_c<2>),
+ hana::make_range(hana::int_c<2>, hana::int_c<2>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<3>), hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<3>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<3>), hana::int_c<1>),
+ hana::make_range(hana::int_c<1>, hana::int_c<3>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<3>), hana::int_c<2>),
+ hana::make_range(hana::int_c<2>, hana::int_c<3>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<0>, hana::int_c<3>), hana::int_c<3>),
+ hana::make_range(hana::int_c<3>, hana::int_c<3>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front(hana::make_range(hana::int_c<20>, hana::int_c<50>), hana::int_c<10>),
+ hana::make_range(hana::int_c<30>, hana::int_c<50>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/drop_front_exactly.cpp b/src/boost/libs/hana/test/range/drop_front_exactly.cpp
new file mode 100644
index 00000000..da964492
--- /dev/null
+++ b/src/boost/libs/hana/test/range/drop_front_exactly.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/core/make.hpp>
+#include <boost/hana/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<0>), hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<1>), hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<1>), hana::int_c<1>),
+ hana::make_range(hana::int_c<1>, hana::int_c<1>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<2>), hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<2>), hana::int_c<1>),
+ hana::make_range(hana::int_c<1>, hana::int_c<2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<2>), hana::int_c<2>),
+ hana::make_range(hana::int_c<2>, hana::int_c<2>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<3>), hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<3>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<3>), hana::int_c<1>),
+ hana::make_range(hana::int_c<1>, hana::int_c<3>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<3>), hana::int_c<2>),
+ hana::make_range(hana::int_c<2>, hana::int_c<3>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<0>, hana::int_c<3>), hana::int_c<3>),
+ hana::make_range(hana::int_c<3>, hana::int_c<3>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::make_range(hana::int_c<20>, hana::int_c<50>), hana::int_c<10>),
+ hana::make_range(hana::int_c<30>, hana::int_c<50>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/equal.cpp b/src/boost/libs/hana/test/range/equal.cpp
new file mode 100644
index 00000000..22babe50
--- /dev/null
+++ b/src/boost/libs/hana/test/range/equal.cpp
@@ -0,0 +1,65 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/not_equal.hpp> // for operator !=
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_range(hana::int_c<0>, hana::int_c<0>) ==
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_range(hana::int_c<0>, hana::int_c<4>) !=
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_range(hana::int_c<0>, hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_range(hana::int_c<0>, hana::int_c<0>),
+ hana::make_range(hana::int_c<0>, hana::int_c<1>)
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_range(hana::int_c<0>, hana::int_c<1>),
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_range(hana::int_c<0>, hana::int_c<1>),
+ hana::make_range(hana::int_c<0>, hana::int_c<1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::make_range(hana::int_c<0>, hana::int_c<2>),
+ hana::make_range(hana::int_c<0>, hana::int_c<1>)
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_range(hana::int_c<0>, hana::int_c<2>),
+ hana::make_range(hana::int_c<0>, hana::int_c<2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_range(hana::int_c<0>, hana::int_c<0>),
+ hana::make_range(hana::int_c<2>, hana::int_c<2>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_range(hana::int_c<2>, hana::int_c<4>),
+ hana::make_range(hana::int_c<2>, hana::int_c<4>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_range(hana::int_c<-4>, hana::int_c<-3>),
+ hana::make_range(hana::int_c<-4>, hana::int_c<-3>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_range(hana::int_c<-4>, hana::int_c<2>),
+ hana::make_range(hana::int_c<-4>, hana::int_c<2>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/find.cpp b/src/boost/libs/hana/test/range/find.cpp
new file mode 100644
index 00000000..29954e8a
--- /dev/null
+++ b/src/boost/libs/hana/test/range/find.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/core/make.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>
+
+#include <support/cnumeric.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(hana::make_range(hana::int_c<0>, hana::int_c<0>), cnumeric<int, 0>),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(hana::make_range(hana::int_c<0>, hana::int_c<1>), cnumeric<int, 0>),
+ hana::just(hana::int_c<0>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(hana::make_range(hana::int_c<0>, hana::int_c<10>), cnumeric<int, 3>),
+ hana::just(hana::int_c<3>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(hana::make_range(hana::int_c<0>, hana::int_c<10>), cnumeric<int, 9>),
+ hana::just(hana::int_c<9>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(hana::make_range(hana::int_c<-10>, hana::int_c<10>), cnumeric<int, -10>),
+ hana::just(hana::int_c<-10>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(hana::make_range(hana::int_c<-10>, hana::int_c<10>), cnumeric<int, -5>),
+ hana::just(hana::int_c<-5>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(hana::make_range(hana::int_c<-10>, hana::int_c<0>), cnumeric<int, 3>),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(hana::make_range(hana::int_c<0>, hana::int_c<10>), cnumeric<int, 15>),
+ hana::nothing
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/front.cpp b/src/boost/libs/hana/test/range/front.cpp
new file mode 100644
index 00000000..e3777a3b
--- /dev/null
+++ b/src/boost/libs/hana/test/range/front.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/make.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;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::make_range(hana::int_c<0>, hana::int_c<1>)),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::make_range(hana::int_c<0>, hana::int_c<2>)),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::make_range(hana::int_c<2>, hana::int_c<5>)),
+ hana::int_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::make_range(hana::int_c<5>, hana::int_c<6>)),
+ hana::int_c<5>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::make_range(hana::int_c<5>, hana::long_c<6>)),
+ hana::long_c<5>
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/is_empty.cpp b/src/boost/libs/hana/test/range/is_empty.cpp
new file mode 100644
index 00000000..5ad79137
--- /dev/null
+++ b/src/boost/libs/hana/test/range/is_empty.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/core/make.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;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ hana::make_range(hana::int_c<0>, hana::int_c<1>)
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(
+ hana::make_range(hana::int_c<0>, hana::int_c<2>)
+ )));
+}
diff --git a/src/boost/libs/hana/test/range/laws.cpp b/src/boost/libs/hana/test/range/laws.cpp
new file mode 100644
index 00000000..070913cb
--- /dev/null
+++ b/src/boost/libs/hana/test/range/laws.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/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/iterable.hpp>
+#include <laws/searchable.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ auto ranges = hana::make_tuple(
+ hana::make_range(hana::int_c<0>, hana::int_c<0>)
+ , hana::make_range(hana::int_c<0>, hana::int_c<1>)
+ , hana::make_range(hana::int_c<0>, hana::int_c<2>)
+ , hana::make_range(hana::int_c<1>, hana::int_c<1>)
+ , hana::make_range(hana::int_c<1>, hana::int_c<2>)
+ , hana::make_range(hana::int_c<1>, hana::int_c<3>)
+ , hana::make_range(hana::int_c<50>, hana::int_c<60>)
+
+ , hana::make_range(hana::int_c<50>, hana::long_c<60>)
+ , hana::make_range(hana::long_c<50>, hana::int_c<60>)
+ );
+
+ auto integers = hana::tuple_c<int, 0, 1, 900>;
+
+ hana::test::TestComparable<hana::range_tag>{ranges};
+ hana::test::TestFoldable<hana::range_tag>{ranges};
+ hana::test::TestIterable<hana::range_tag>{ranges};
+ hana::test::TestSearchable<hana::range_tag>{ranges, integers};
+}
diff --git a/src/boost/libs/hana/test/range/length.cpp b/src/boost/libs/hana/test/range/length.cpp
new file mode 100644
index 00000000..3eb9799f
--- /dev/null
+++ b/src/boost/libs/hana/test/range/length.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/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_range(hana::int_c<0>, hana::int_c<0>)),
+ hana::size_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_range(hana::int_c<0>, hana::int_c<1>)),
+ hana::size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_range(hana::int_c<0>, hana::int_c<2>)),
+ hana::size_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_range(hana::int_c<4>, hana::int_c<4>)),
+ hana::size_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(hana::make_range(hana::int_c<4>, hana::int_c<10>)),
+ hana::size_c<6>
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/make.cpp b/src/boost/libs/hana/test/range/make.cpp
new file mode 100644
index 00000000..cd9fe94c
--- /dev/null
+++ b/src/boost/libs/hana/test/range/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/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // make sure make<range_tag> works with arbitrary Constants
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::range_tag>(hana::test::_constant<1>{}, hana::test::_constant<4>{}),
+ hana::make_range(hana::integral_c<int, 1>, hana::integral_c<int, 4>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/maximum.cpp b/src/boost/libs/hana/test/range/maximum.cpp
new file mode 100644
index 00000000..ca98b16e
--- /dev/null
+++ b/src/boost/libs/hana/test/range/maximum.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/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/maximum.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::maximum(hana::make_range(hana::int_c<3>, hana::int_c<4>)),
+ hana::int_c<3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::maximum(hana::make_range(hana::int_c<3>, hana::int_c<5>)),
+ hana::int_c<4>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::maximum(hana::make_range(hana::int_c<-1>, hana::int_c<6>)),
+ hana::int_c<5>
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/minimum.cpp b/src/boost/libs/hana/test/range/minimum.cpp
new file mode 100644
index 00000000..3a5da38c
--- /dev/null
+++ b/src/boost/libs/hana/test/range/minimum.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/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minimum.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::minimum(hana::make_range(hana::int_c<3>, hana::int_c<4>)),
+ hana::int_c<3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::minimum(hana::make_range(hana::int_c<3>, hana::int_c<5>)),
+ hana::int_c<3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::minimum(hana::make_range(hana::int_c<-1>, hana::int_c<5>)),
+ hana::int_c<-1>
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/product.cpp b/src/boost/libs/hana/test/range/product.cpp
new file mode 100644
index 00000000..0a15a23c
--- /dev/null
+++ b/src/boost/libs/hana/test/range/product.cpp
@@ -0,0 +1,85 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/product.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<-3>, hana::int_c<-3>)),
+ hana::int_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<-3>, hana::int_c<-2>)),
+ hana::int_c<-3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<-3>, hana::int_c<-1>)),
+ hana::int_c<-3 * -2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<-3>, hana::int_c<0>)),
+ hana::int_c<-3 * -2 * -1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<-3>, hana::int_c<1>)),
+ hana::int_c<-3 * -2 * -1 * 0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<-3>, hana::int_c<2>)),
+ hana::int_c<-3 * -2 * -1 * 0 * 1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<-3>, hana::int_c<3>)),
+ hana::int_c<-3 * -2 * -1 * 0 * 1 * 2>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<1>, hana::int_c<1>)),
+ hana::int_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<1>, hana::int_c<2>)),
+ hana::int_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<1>, hana::int_c<3>)),
+ hana::int_c<1 * 2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<1>, hana::int_c<4>)),
+ hana::int_c<1 * 2 * 3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<1>, hana::int_c<5>)),
+ hana::int_c<1 * 2 * 3 * 4>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<3>, hana::int_c<3>)),
+ hana::int_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<3>, hana::int_c<4>)),
+ hana::int_c<3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<3>, hana::int_c<5>)),
+ hana::int_c<3 * 4>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<3>, hana::int_c<6>)),
+ hana::int_c<3 * 4 * 5>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::product<>(hana::make_range(hana::int_c<3>, hana::int_c<7>)),
+ hana::int_c<3 * 4 * 5 * 6>
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/range_c.cpp b/src/boost/libs/hana/test/range/range_c.cpp
new file mode 100644
index 00000000..9d384c2d
--- /dev/null
+++ b/src/boost/libs/hana/test/range/range_c.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/core/make.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ using T = int;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::range_c<T, 0, 0>,
+ hana::make_range(hana::integral_c<T, 0>, hana::integral_c<T, 0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::range_c<T, 0, 1>,
+ hana::make_range(hana::integral_c<T, 0>, hana::integral_c<T, 1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::range_c<T, 0, 2>,
+ hana::make_range(hana::integral_c<T, 0>, hana::integral_c<T, 2>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::range_c<T, 1, 1>,
+ hana::make_range(hana::integral_c<T, 1>, hana::integral_c<T, 1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::range_c<T, 1, 2>,
+ hana::make_range(hana::integral_c<T, 1>, hana::integral_c<T, 2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::range_c<T, 1, 3>,
+ hana::make_range(hana::integral_c<T, 1>, hana::integral_c<T, 3>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/sum.cpp b/src/boost/libs/hana/test/range/sum.cpp
new file mode 100644
index 00000000..3575c3c9
--- /dev/null
+++ b/src/boost/libs/hana/test/range/sum.cpp
@@ -0,0 +1,85 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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>
+#include <boost/hana/sum.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<-3>, hana::int_c<-3>)),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<-3>, hana::int_c<-2>)),
+ hana::int_c<-3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<-3>, hana::int_c<-1>)),
+ hana::int_c<-3 + -2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<-3>, hana::int_c<0>)),
+ hana::int_c<-3 + -2 + -1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<-3>, hana::int_c<1>)),
+ hana::int_c<-3 + -2 + -1 + 0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<-3>, hana::int_c<2>)),
+ hana::int_c<-3 + -2 + -1 + 0 + 1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<-3>, hana::int_c<3>)),
+ hana::int_c<-3 + -2 + -1 + 0 + 1 + 2>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<0>, hana::int_c<0>)),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<0>, hana::int_c<1>)),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<0>, hana::int_c<2>)),
+ hana::int_c<0 + 1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<0>, hana::int_c<3>)),
+ hana::int_c<0 + 1 + 2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<0>, hana::int_c<4>)),
+ hana::int_c<0 + 1 + 2 + 3>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<3>, hana::int_c<3>)),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<3>, hana::int_c<4>)),
+ hana::int_c<3>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<3>, hana::int_c<5>)),
+ hana::int_c<3 + 4>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<3>, hana::int_c<6>)),
+ hana::int_c<3 + 4 + 5>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sum<>(hana::make_range(hana::int_c<3>, hana::int_c<7>)),
+ hana::int_c<3 + 4 + 5 + 6>
+ ));
+}
diff --git a/src/boost/libs/hana/test/range/unpack.cpp b/src/boost/libs/hana/test/range/unpack.cpp
new file mode 100644
index 00000000..45b2e728
--- /dev/null
+++ b/src/boost/libs/hana/test/range/unpack.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/core/make.hpp>
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_range(hana::int_c<0>, hana::int_c<0>), f),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_range(hana::int_c<0>, hana::int_c<1>), f),
+ f(hana::int_c<0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_range(hana::int_c<0>, hana::int_c<2>), f),
+ f(hana::int_c<0>, hana::int_c<1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_range(hana::int_c<0>, hana::int_c<3>), f),
+ f(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>)
+ ));
+
+ // Previously, we would only unpack with `std::size_t`s. Make
+ // sure this does not happen.
+ hana::unpack(hana::make_range(hana::int_c<0>, hana::int_c<1>), [](auto x) {
+ using T = hana::tag_of_t<decltype(x)>;
+ static_assert(std::is_same<typename T::value_type, int>{}, "");
+ });
+}
diff --git a/src/boost/libs/hana/test/repeat.cpp b/src/boost/libs/hana/test/repeat.cpp
new file mode 100644
index 00000000..0d9e42ec
--- /dev/null
+++ b/src/boost/libs/hana/test/repeat.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/fwd/concept/integral_constant.hpp>
+#include <boost/hana/repeat.hpp>
+namespace hana = boost::hana;
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Define a simple model of IntegralConstant for use below
+template <int i>
+struct constant {
+ static constexpr int value = i;
+ using value_type = int;
+};
+
+namespace boost { namespace hana {
+ template <int i>
+ struct IntegralConstant<constant<i>> {
+ static constexpr bool value = true;
+ };
+
+ // definition of `to<>` omitted
+}}
+//////////////////////////////////////////////////////////////////////////////
+
+void function() { }
+
+int main() {
+ int counter = 0;
+ hana::repeat(constant<3>{}, [&] { ++counter; });
+ BOOST_HANA_RUNTIME_CHECK(counter == 3);
+
+ // Try with a normal function.
+ hana::repeat(constant<3>{}, function);
+
+ // Try with a function pointer.
+ hana::repeat(constant<3>{}, static_cast<void(*)()>(function));
+
+ // Make sure we don't read from a non-constexpr variable.
+ constant<3> three{};
+ hana::repeat(three, []{});
+}
diff --git a/src/boost/libs/hana/test/ring.cpp b/src/boost/libs/hana/test/ring.cpp
new file mode 100644
index 00000000..f1d3fd43
--- /dev/null
+++ b/src/boost/libs/hana/test/ring.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/concept/ring.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/one.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/ring.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::TestRing<int>{hana::make_tuple(0,1,2,3,4,5)};
+ hana::test::TestRing<long>{hana::make_tuple(0l,1l,2l,3l,4l,5l)};
+
+ // one
+ static_assert(hana::one<int>() == 1, "");
+
+ // mult
+ static_assert(hana::mult(6, 4) == 6 * 4, "");
+}
diff --git a/src/boost/libs/hana/test/searchable.cpp b/src/boost/libs/hana/test/searchable.cpp
new file mode 100644
index 00000000..379fa40d
--- /dev/null
+++ b/src/boost/libs/hana/test/searchable.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/bool.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <support/seq.hpp>
+
+#include <laws/base.hpp>
+#include <laws/searchable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // Laws with a minimal Searchable
+ //////////////////////////////////////////////////////////////////////////
+ {
+ auto eqs = hana::make_tuple(
+ ::seq()
+ , ::seq(ct_eq<0>{})
+ , ::seq(ct_eq<0>{}, ct_eq<1>{})
+ , ::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , ::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ );
+
+ auto eq_keys = hana::make_tuple(ct_eq<0>{}, ct_eq<3>{}, ct_eq<10>{});
+
+ hana::test::TestSearchable<::Seq>{eqs, eq_keys};
+
+ auto bools = hana::make_tuple(
+ ::seq(hana::true_c)
+ , ::seq(hana::false_c)
+ , ::seq(hana::true_c, hana::true_c)
+ , ::seq(hana::true_c, hana::false_c)
+ , ::seq(hana::false_c, hana::true_c)
+ , ::seq(hana::false_c, hana::false_c)
+ );
+ hana::test::TestSearchable<::Seq>{bools, hana::make_tuple(hana::true_c, hana::false_c)};
+ }
+}
diff --git a/src/boost/libs/hana/test/set/any_of.cpp b/src/boost/libs/hana/test/set/any_of.cpp
new file mode 100644
index 00000000..1f092cbe
--- /dev/null
+++ b/src/boost/libs/hana/test/set/any_of.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/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/set.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ hana::make_set(),
+ hana::equal.to(ct_eq<1>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ hana::make_set(ct_eq<1>{}),
+ hana::equal.to(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ hana::make_set(ct_eq<1>{}),
+ hana::equal.to(ct_eq<2>{})
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{}),
+ hana::equal.to(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{}),
+ hana::equal.to(ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{}),
+ hana::equal.to(ct_eq<3>{})
+ )));
+}
diff --git a/src/boost/libs/hana/test/set/cnstr.copy.cpp b/src/boost/libs/hana/test/set/cnstr.copy.cpp
new file mode 100644
index 00000000..a3fa2757
--- /dev/null
+++ b/src/boost/libs/hana/test/set/cnstr.copy.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/integral_constant.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ auto t0 = hana::make_set();
+ auto t_implicit = t0;
+ auto t_explicit(t0);
+
+ (void)t_explicit;
+ (void)t_implicit;
+ }
+ {
+ auto t0 = hana::make_set(hana::int_c<2>);
+ auto t_implicit = t0;
+ auto t_explicit(t0);
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_set(hana::int_c<2>, hana::int_c<3>);
+ auto t_implicit = t0;
+ auto t_explicit(t0);
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_set(hana::int_c<2>, hana::int_c<3>, hana::type_c<int>);
+ auto t_implicit = t0;
+ auto t_explicit(t0);
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ constexpr auto t0 = hana::make_set(hana::int_c<2>, hana::int_c<3>, hana::type_c<int>);
+ constexpr auto t_implicit = t0;
+ constexpr auto t_explicit(t0);
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+}
diff --git a/src/boost/libs/hana/test/set/cnstr.default.cpp b/src/boost/libs/hana/test/set/cnstr.default.cpp
new file mode 100644
index 00000000..bc5ee91d
--- /dev/null
+++ b/src/boost/libs/hana/test/set/cnstr.default.cpp
@@ -0,0 +1,77 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/fwd/hash.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <int i>
+struct NoDefault {
+ NoDefault() = delete;
+ NoDefault(NoDefault const&) = default;
+ constexpr explicit NoDefault(int) { }
+};
+
+template <int i, int j>
+auto operator==(NoDefault<i> const&, NoDefault<j> const&) { return hana::bool_<i == j>{}; }
+template <int i, int j>
+auto operator!=(NoDefault<i> const&, NoDefault<j> const&) { return hana::bool_<i != j>{}; }
+
+template <int i>
+struct Default {
+ Default() = default;
+ Default(Default const&) = default;
+ constexpr explicit Default(int) { }
+};
+
+template <int i, int j>
+auto operator==(Default<i> const&, Default<j> const&) { return hana::bool_<i == j>{}; }
+template <int i, int j>
+auto operator!=(Default<i> const&, Default<j> const&) { return hana::bool_<i != j>{}; }
+
+namespace boost { namespace hana {
+ template <int i>
+ struct hash_impl<NoDefault<i>> {
+ static constexpr auto apply(NoDefault<i> const&)
+ { return hana::type_c<NoDefault<i>>; };
+ };
+
+ template <int i>
+ struct hash_impl<Default<i>> {
+ static constexpr auto apply(Default<i> const&)
+ { return hana::type_c<Default<i>>; };
+ };
+}}
+
+int main() {
+ {
+ auto set0 = hana::make_set();
+ static_assert(std::is_default_constructible<decltype(set0)>{}, "");
+
+ auto set1 = hana::make_set(Default<0>(int{}));
+ static_assert(std::is_default_constructible<decltype(set1)>{}, "");
+
+ auto set2 = hana::make_set(Default<0>(int{}), Default<1>(int{}));
+ static_assert(std::is_default_constructible<decltype(set2)>{}, "");
+
+ auto set3 = hana::make_set(Default<0>(int{}), NoDefault<1>(int{}), Default<2>(int{}));
+ static_assert(!std::is_default_constructible<decltype(set3)>{}, "");
+ }
+
+ {
+ auto set1 = hana::make_set(NoDefault<0>(int{}));
+ static_assert(!std::is_default_constructible<decltype(set1)>{}, "");
+
+ auto set2 = hana::make_set(NoDefault<0>(int{}), NoDefault<1>(int{}));
+ static_assert(!std::is_default_constructible<decltype(set2)>{}, "");
+
+ auto set3 = hana::make_set(NoDefault<0>(int{}), NoDefault<1>(int{}), NoDefault<2>(int{}));
+ static_assert(!std::is_default_constructible<decltype(set3)>{}, "");
+ }
+} \ No newline at end of file
diff --git a/src/boost/libs/hana/test/set/cnstr.move.cpp b/src/boost/libs/hana/test/set/cnstr.move.cpp
new file mode 100644
index 00000000..e1a98511
--- /dev/null
+++ b/src/boost/libs/hana/test/set/cnstr.move.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/bool.hpp>
+#include <boost/hana/fwd/hash.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/type.hpp>
+
+#include <support/constexpr_move_only.hpp>
+#include <support/tracked_move_only.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+constexpr bool in_constexpr_context() {
+ auto t0 = hana::make_set(ConstexprMoveOnly<2>{}, ConstexprMoveOnly<3>{});
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_implicit;
+ (void)t_explicit;
+ return true;
+}
+
+static_assert(in_constexpr_context(), "");
+
+
+int main() {
+ {
+ auto t0 = hana::make_set();
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_explicit;
+ (void)t_implicit;
+ }
+ {
+ auto t0 = hana::make_set(TrackedMoveOnly<1>{});
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_set(TrackedMoveOnly<1>{}, TrackedMoveOnly<2>{});
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+ {
+ auto t0 = hana::make_set(TrackedMoveOnly<1>{}, TrackedMoveOnly<2>{}, TrackedMoveOnly<3>{});
+ auto t_implicit = std::move(t0);
+ auto t_explicit(std::move(t_implicit));
+
+ (void)t_implicit;
+ (void)t_explicit;
+ }
+}
diff --git a/src/boost/libs/hana/test/set/cnstr.trap.cpp b/src/boost/libs/hana/test/set/cnstr.trap.cpp
new file mode 100644
index 00000000..fd95b15e
--- /dev/null
+++ b/src/boost/libs/hana/test/set/cnstr.trap.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/bool.hpp>
+#include <boost/hana/detail/wrong.hpp>
+#include <boost/hana/fwd/hash.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/type.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+// This test makes sure that we do not instantiate rogue constructors when
+// doing copies and moves
+
+template <int i>
+struct Trap {
+ Trap() = default;
+ Trap(Trap const&) = default;
+#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
+ Trap(Trap&) = default;
+#endif
+ Trap(Trap&&) = default;
+
+ template <typename X>
+ Trap(X&&) {
+ static_assert(hana::detail::wrong<X>{},
+ "this constructor must not be instantiated");
+ }
+};
+
+template <int i, int j>
+constexpr auto operator==(Trap<i> const&, Trap<j> const&)
+{ return hana::bool_c<i == j>; }
+
+template <int i, int j>
+constexpr auto operator!=(Trap<i> const&, Trap<j> const&)
+{ return hana::bool_c<i != j>; }
+
+namespace boost { namespace hana {
+ template <int i>
+ struct hash_impl<Trap<i>> {
+ static constexpr auto apply(Trap<i> const&)
+ { return hana::type_c<Trap<i>>; };
+ };
+}}
+
+int main() {
+ {
+ auto expr = hana::make_set(Trap<0>{});
+ auto implicit_copy = expr;
+ decltype(expr) explicit_copy(expr);
+
+ (void)implicit_copy;
+ (void)explicit_copy;
+ }
+ {
+ auto expr = hana::make_set(Trap<0>{});
+ auto implicit_move = std::move(expr);
+ decltype(expr) explicit_move(std::move(implicit_move));
+
+ (void)implicit_move;
+ (void)explicit_move;
+ }
+}
diff --git a/src/boost/libs/hana/test/set/difference.cpp b/src/boost/libs/hana/test/set/difference.cpp
new file mode 100644
index 00000000..fdb7c91c
--- /dev/null
+++ b/src/boost/libs/hana/test/set/difference.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/difference.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/set.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_set(),
+ hana::make_set()
+ ),
+ hana::make_set()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set()
+ ),
+ hana::make_set(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_set()
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set()
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set(ct_eq<1>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<3>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<3>{}, ct_eq<2>{})
+ ),
+ hana::make_set(ct_eq<0>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/set/equal.cpp b/src/boost/libs/hana/test/set/equal.cpp
new file mode 100644
index 00000000..d0c35073
--- /dev/null
+++ b/src/boost/libs/hana/test/set/equal.cpp
@@ -0,0 +1,56 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/for_each.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/not_equal.hpp> // for operator !=
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto check = [](auto ...keys) {
+ auto keys_set = hana::make_set(keys...);
+ auto keys_tuple = hana::make_tuple(keys...);
+ auto possible_arrangements = hana::permutations(keys_tuple);
+
+ hana::for_each(possible_arrangements, [&](auto perm) {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_set(perm),
+ keys_set
+ ));
+ });
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ keys_set,
+ hana::make_set(keys..., ct_eq<999>{})
+ )));
+ };
+
+ check();
+ check(ct_eq<0>{});
+ check(ct_eq<0>{}, ct_eq<1>{});
+ check(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
+
+ // check operators
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_set(ct_eq<0>{})
+ ==
+ hana::make_set(ct_eq<0>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_set(ct_eq<0>{})
+ !=
+ hana::make_set(ct_eq<1>{})
+ );
+}
diff --git a/src/boost/libs/hana/test/set/erase_key.cpp b/src/boost/libs/hana/test/set/erase_key.cpp
new file mode 100644
index 00000000..4103144a
--- /dev/null
+++ b/src/boost/libs/hana/test/set/erase_key.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/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/erase_key.hpp>
+#include <boost/hana/set.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+struct undefined { };
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(), undefined{}),
+ hana::make_set()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(ct_eq<0>{}), ct_eq<0>{}),
+ hana::make_set()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(ct_eq<0>{}), ct_eq<99>{}),
+ hana::make_set(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(ct_eq<0>{}, ct_eq<1>{}), ct_eq<0>{}),
+ hana::make_set(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(ct_eq<0>{}, ct_eq<1>{}), ct_eq<1>{}),
+ hana::make_set(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(ct_eq<0>{}, ct_eq<1>{}), ct_eq<99>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), ct_eq<0>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), ct_eq<1>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), ct_eq<2>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::erase_key(hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), ct_eq<99>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/set/find_if.cpp b/src/boost/libs/hana/test/set/find_if.cpp
new file mode 100644
index 00000000..190d311e
--- /dev/null
+++ b/src/boost/libs/hana/test/set/find_if.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/assert.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/set.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_set(), hana::equal.to(ct_eq<1>{})),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_set(ct_eq<1>{}), hana::equal.to(ct_eq<1>{})),
+ hana::just(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_set(ct_eq<1>{}), hana::equal.to(ct_eq<2>{})),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_set(ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<1>{})),
+ hana::just(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_set(ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<2>{})),
+ hana::just(ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(hana::make_set(ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<3>{})),
+ hana::nothing
+ ));
+
+ // find with operators
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_set(ct_eq<1>{})[ct_eq<1>{}],
+ ct_eq<1>{}
+ ));
+}
diff --git a/src/boost/libs/hana/test/set/insert.cpp b/src/boost/libs/hana/test/set/insert.cpp
new file mode 100644
index 00000000..daa50be0
--- /dev/null
+++ b/src/boost/libs/hana/test/set/insert.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/insert.hpp>
+#include <boost/hana/set.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_set(), ct_eq<0>{}),
+ hana::make_set(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_set(ct_eq<0>{}), ct_eq<0>{}),
+ hana::make_set(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_set(ct_eq<0>{}), ct_eq<1>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_set(ct_eq<0>{}, ct_eq<1>{}), ct_eq<1>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_set(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::insert(hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), ct_eq<3>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/set/intersection.cpp b/src/boost/libs/hana/test/set/intersection.cpp
new file mode 100644
index 00000000..bb2a2d38
--- /dev/null
+++ b/src/boost/libs/hana/test/set/intersection.cpp
@@ -0,0 +1,90 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/set.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(),
+ hana::make_set()
+ ),
+ hana::make_set()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set()
+ ),
+ hana::make_set()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(),
+ hana::make_set(ct_eq<0>{})
+ ),
+ hana::make_set()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set(ct_eq<1>{})
+ ),
+ hana::make_set()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set(ct_eq<0>{})
+ ),
+ hana::make_set(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_set(ct_eq<2>{}, ct_eq<3>{})
+ ),
+ hana::make_set()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{})
+ ),
+ hana::make_set(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<0>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<0>{}, ct_eq<4>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::intersection(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<0>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<4>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/set/is_subset.cpp b/src/boost/libs/hana/test/set/is_subset.cpp
new file mode 100644
index 00000000..7db106aa
--- /dev/null
+++ b/src/boost/libs/hana/test/set/is_subset.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_subset.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/set.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_set(),
+ hana::make_set(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_subset(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_subset(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ )));
+}
diff --git a/src/boost/libs/hana/test/set/laws.cpp b/src/boost/libs/hana/test/set/laws.cpp
new file mode 100644
index 00000000..0741ad78
--- /dev/null
+++ b/src/boost/libs/hana/test/set/laws.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/set.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/searchable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto eqs = hana::make_tuple(
+ hana::make_set(),
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<0>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ );
+
+ auto keys = hana::make_tuple(
+ ct_eq<2>{},
+ ct_eq<3>{}
+ );
+
+ hana::test::TestComparable<hana::set_tag>{eqs};
+ hana::test::TestSearchable<hana::set_tag>{eqs, keys};
+ hana::test::TestFoldable<hana::set_tag>{eqs};
+}
diff --git a/src/boost/libs/hana/test/set/make.cpp b/src/boost/libs/hana/test/set/make.cpp
new file mode 100644
index 00000000..2ec86f7f
--- /dev/null
+++ b/src/boost/libs/hana/test/set/make.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/equal.hpp>
+#include <boost/hana/set.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::set_tag>(),
+ hana::make_set()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::set_tag>(ct_eq<0>{}),
+ hana::make_set(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::set_tag>(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::set_tag>(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/set/symmetric_difference.cpp b/src/boost/libs/hana/test/set/symmetric_difference.cpp
new file mode 100644
index 00000000..ac11ad2d
--- /dev/null
+++ b/src/boost/libs/hana/test/set/symmetric_difference.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/equal.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/symmetric_difference.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_set(),
+ hana::make_set()
+ ),
+ hana::make_set()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set()
+ ),
+ hana::make_set(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_set()
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set()
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set(ct_eq<1>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<3>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::symmetric_difference(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<3>{}, ct_eq<2>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<3>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/set/to.cpp b/src/boost/libs/hana/test/set/to.cpp
new file mode 100644
index 00000000..c2cc1a5d
--- /dev/null
+++ b/src/boost/libs/hana/test/set/to.cpp
@@ -0,0 +1,84 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/set.hpp>
+
+#include <laws/base.hpp>
+#include <support/seq.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto sequence = ::seq;
+ auto foldable = ::seq;
+ using S = ::Seq;
+
+ // Set -> Sequence
+ {
+ auto check = [=](auto ...xs) {
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ hana::permutations(sequence(xs...)),
+ hana::to<S>(hana::make_set(xs...))
+ ));
+ };
+ check();
+ check(ct_eq<1>{});
+ check(ct_eq<1>{}, ct_eq<2>{});
+ check(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{});
+ check(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{});
+ }
+
+ // Foldable -> Set
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::set_tag>(foldable()),
+ hana::make_set()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::set_tag>(foldable(ct_eq<1>{})),
+ hana::make_set(ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::set_tag>(foldable(ct_eq<1>{}, ct_eq<1>{})),
+ hana::make_set(ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::set_tag>(foldable(ct_eq<1>{}, ct_eq<2>{})),
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::set_tag>(foldable(ct_eq<1>{}, ct_eq<2>{}, ct_eq<1>{})),
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::set_tag>(foldable(ct_eq<1>{}, ct_eq<2>{}, ct_eq<2>{})),
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::set_tag>(foldable(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})),
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::set_tag>(foldable(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{})),
+ hana::make_set(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ ));
+ }
+
+ // to_set == to<set_tag>
+ {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to_set(foldable(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{})),
+ hana::to<hana::set_tag>(foldable(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}))
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/set/union.cpp b/src/boost/libs/hana/test/set/union.cpp
new file mode 100644
index 00000000..5316b1b2
--- /dev/null
+++ b/src/boost/libs/hana/test/set/union.cpp
@@ -0,0 +1,84 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/set.hpp>
+#include <boost/hana/union.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_set(),
+ hana::make_set()
+ ),
+ hana::make_set()
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set()
+ ),
+ hana::make_set(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_set(),
+ hana::make_set(ct_eq<0>{})
+ ),
+ hana::make_set(ct_eq<0>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set(ct_eq<0>{})
+ ),
+ hana::make_set(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set(ct_eq<1>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}),
+ hana::make_set(ct_eq<1>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_set(ct_eq<0>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<0>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_set(ct_eq<0>{}, ct_eq<2>{}),
+ hana::make_set(ct_eq<1>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::union_(
+ hana::make_set(ct_eq<0>{}, ct_eq<2>{}, ct_eq<5>{}),
+ hana::make_set(ct_eq<1>{}, ct_eq<3>{}, ct_eq<4>{})
+ ),
+ hana::make_set(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})
+ ));
+}
diff --git a/src/boost/libs/hana/test/set/unpack.cpp b/src/boost/libs/hana/test/set/unpack.cpp
new file mode 100644
index 00000000..4412dd96
--- /dev/null
+++ b/src/boost/libs/hana/test/set/unpack.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/contains.hpp>
+#include <boost/hana/permutations.hpp>
+#include <boost/hana/set.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ auto check = [=](auto ...xs) {
+ auto arg_perms = hana::permutations(hana::make_tuple(xs...));
+ auto possible_results = hana::transform(arg_perms, [=](auto args) {
+ return hana::unpack(args, f);
+ });
+
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ possible_results,
+ hana::unpack(hana::make_set(xs...), f)
+ ));
+ };
+
+ check();
+ check(ct_eq<1>{});
+ check(ct_eq<1>{}, ct_eq<2>{});
+ check(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{});
+ check(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{});
+}
diff --git a/src/boost/libs/hana/test/string/any_of.cpp b/src/boost/libs/hana/test/string/any_of.cpp
new file mode 100644
index 00000000..125a985d
--- /dev/null
+++ b/src/boost/libs/hana/test/string/any_of.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/any_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::any_of(
+ BOOST_HANA_STRING("abcd"),
+ hana::equal.to(hana::char_c<'b'>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ BOOST_HANA_STRING(""),
+ hana::always(hana::true_c)
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
+ BOOST_HANA_STRING("abcd"),
+ hana::equal.to(hana::char_c<'z'>)
+ )));
+}
diff --git a/src/boost/libs/hana/test/string/at.cpp b/src/boost/libs/hana/test/string/at.cpp
new file mode 100644
index 00000000..ea0c2423
--- /dev/null
+++ b/src/boost/libs/hana/test/string/at.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/at.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ BOOST_HANA_STRING("abcd")[hana::size_c<2>],
+ hana::char_c<'c'>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(BOOST_HANA_STRING("a"), hana::size_c<0>),
+ hana::char_c<'a'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(BOOST_HANA_STRING("ab"), hana::size_c<0>),
+ hana::char_c<'a'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(BOOST_HANA_STRING("abc"), hana::size_c<0>),
+ hana::char_c<'a'>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(BOOST_HANA_STRING("ab"), hana::size_c<1>),
+ hana::char_c<'b'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(BOOST_HANA_STRING("abc"), hana::size_c<1>),
+ hana::char_c<'b'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(BOOST_HANA_STRING("abcd"), hana::size_c<1>),
+ hana::char_c<'b'>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(BOOST_HANA_STRING("abc"), hana::size_c<2>),
+ hana::char_c<'c'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::at(BOOST_HANA_STRING("abcd"), hana::size_c<2>),
+ hana::char_c<'c'>
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/c_str.cpp b/src/boost/libs/hana/test/string/c_str.cpp
new file mode 100644
index 00000000..b773fc20
--- /dev/null
+++ b/src/boost/libs/hana/test/string/c_str.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/assert.hpp>
+#include <boost/hana/string.hpp>
+
+#include <cstring>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ BOOST_HANA_STRING("").c_str(),
+ ""
+ ) == 0);
+
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ BOOST_HANA_STRING("a").c_str(),
+ "a"
+ ) == 0);
+
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ BOOST_HANA_STRING("ab").c_str(),
+ "ab"
+ ) == 0);
+
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ BOOST_HANA_STRING("abc").c_str(),
+ "abc"
+ ) == 0);
+
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ BOOST_HANA_STRING("abcd").c_str(),
+ "abcd"
+ ) == 0);
+
+ // make sure we can turn a non-constexpr hana::string
+ // into a constexpr char const*
+ {
+ auto str = BOOST_HANA_STRING("abcdef");
+ constexpr char const* c_str = str.c_str();
+ (void)c_str;
+ }
+
+ // make sure c_str is actually a static member function
+ {
+ constexpr char const* c_str = hana::string<'f', 'o', 'o'>::c_str();
+ (void)c_str;
+ }
+}
diff --git a/src/boost/libs/hana/test/string/cnstr.c_str.cpp b/src/boost/libs/hana/test/string/cnstr.c_str.cpp
new file mode 100644
index 00000000..e118f04f
--- /dev/null
+++ b/src/boost/libs/hana/test/string/cnstr.c_str.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)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/string.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+constexpr char const empty[] = "";
+constexpr char const a[] = "a";
+constexpr char const ab[] = "ab";
+constexpr char const abc[] = "abc";
+constexpr char const abcd[] = "abcd";
+
+int main() {
+ {
+ auto string = hana::to<hana::string_tag>(hana::integral_constant<char const*, empty>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(string, hana::string_c<>));
+ }
+
+ {
+ auto string = hana::to<hana::string_tag>(hana::integral_constant<char const*, a>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(string, hana::string_c<'a'>));
+ }
+
+ {
+ auto string = hana::to<hana::string_tag>(hana::integral_constant<char const*, ab>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(string, hana::string_c<'a', 'b'>));
+ }
+
+ {
+ auto string = hana::to<hana::string_tag>(hana::integral_constant<char const*, abc>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(string, hana::string_c<'a', 'b', 'c'>));
+ }
+
+ {
+ auto string = hana::to<hana::string_tag>(hana::integral_constant<char const*, abcd>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(string, hana::string_c<'a', 'b', 'c', 'd'>));
+ }
+
+ // Make sure it also works with std::integral_constant, for example
+ {
+ auto string = hana::to<hana::string_tag>(std::integral_constant<char const*, abcd>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(string, hana::string_c<'a', 'b', 'c', 'd'>));
+ }
+
+ // Make sure the `to_string` shortcut works
+ {
+ auto string = hana::to_string(hana::integral_constant<char const*, abcd>{});
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(string, hana::string_c<'a', 'b', 'c', 'd'>));
+ }
+}
diff --git a/src/boost/libs/hana/test/string/cnstr.copy.cpp b/src/boost/libs/hana/test/string/cnstr.copy.cpp
new file mode 100644
index 00000000..08bda5b8
--- /dev/null
+++ b/src/boost/libs/hana/test/string/cnstr.copy.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/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ using Str = decltype(hana::string_c<'a', 'b', 'c', 'd'>);
+ Str s1{};
+ Str s2(s1);
+ Str s3 = s1;
+
+ (void)s2; (void)s3;
+}
diff --git a/src/boost/libs/hana/test/string/cnstr.default.cpp b/src/boost/libs/hana/test/string/cnstr.default.cpp
new file mode 100644
index 00000000..b482e072
--- /dev/null
+++ b/src/boost/libs/hana/test/string/cnstr.default.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/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ using Str = decltype(hana::string_c<'a', 'b', 'c', 'd'>);
+ Str s{};
+ (void)s;
+}
diff --git a/src/boost/libs/hana/test/string/contains.cpp b/src/boost/libs/hana/test/string/contains.cpp
new file mode 100644
index 00000000..18ba68f9
--- /dev/null
+++ b/src/boost/libs/hana/test/string/contains.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/contains.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+struct invalid { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ BOOST_HANA_STRING("abcd"),
+ hana::char_c<'a'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::contains(
+ BOOST_HANA_STRING("abcd"),
+ hana::char_c<'c'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ BOOST_HANA_STRING("abcd"),
+ hana::char_c<'e'>
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::contains(
+ BOOST_HANA_STRING("abcd"),
+ invalid{}
+ )));
+}
diff --git a/src/boost/libs/hana/test/string/drop_front_exactly.cpp b/src/boost/libs/hana/test/string/drop_front_exactly.cpp
new file mode 100644
index 00000000..fbcebe8e
--- /dev/null
+++ b/src/boost/libs/hana/test/string/drop_front_exactly.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/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(BOOST_HANA_STRING("a")),
+ BOOST_HANA_STRING("")
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(BOOST_HANA_STRING("ab")),
+ BOOST_HANA_STRING("b")
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(BOOST_HANA_STRING("abc")),
+ BOOST_HANA_STRING("bc")
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(BOOST_HANA_STRING("abcdefghijk")),
+ BOOST_HANA_STRING("bcdefghijk")
+ ));
+
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(BOOST_HANA_STRING("abc"), hana::size_c<2>),
+ BOOST_HANA_STRING("c")
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(BOOST_HANA_STRING("abcdefghijk"), hana::size_c<3>),
+ BOOST_HANA_STRING("defghijk")
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/equal.cpp b/src/boost/libs/hana/test/string/equal.cpp
new file mode 100644
index 00000000..0e4ea9d8
--- /dev/null
+++ b/src/boost/libs/hana/test/string/equal.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/not.hpp>
+#include <boost/hana/not_equal.hpp> // for operator !=
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // equal
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ BOOST_HANA_STRING("abcd"),
+ BOOST_HANA_STRING("abcd")
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ BOOST_HANA_STRING("abcd"),
+ BOOST_HANA_STRING("abcde")
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ BOOST_HANA_STRING("abcd"),
+ BOOST_HANA_STRING("")
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ BOOST_HANA_STRING(""),
+ BOOST_HANA_STRING("abcde")
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ BOOST_HANA_STRING(""),
+ BOOST_HANA_STRING("")
+ ));
+
+ // check operators
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abcd")
+ ==
+ BOOST_HANA_STRING("abcd")
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abcd")
+ !=
+ BOOST_HANA_STRING("abc")
+ );
+}
diff --git a/src/boost/libs/hana/test/string/find.cpp b/src/boost/libs/hana/test/string/find.cpp
new file mode 100644
index 00000000..b8148e5e
--- /dev/null
+++ b/src/boost/libs/hana/test/string/find.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/find.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+struct invalid { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(BOOST_HANA_STRING("abcd"), hana::char_c<'a'>),
+ hana::just(hana::char_c<'a'>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(BOOST_HANA_STRING("abcd"), hana::char_c<'c'>),
+ hana::just(hana::char_c<'c'>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find(BOOST_HANA_STRING("abcd"), invalid{}),
+ hana::nothing
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/find_if.cpp b/src/boost/libs/hana/test/string/find_if.cpp
new file mode 100644
index 00000000..05d5e98b
--- /dev/null
+++ b/src/boost/libs/hana/test/string/find_if.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/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/find_if.hpp>
+#include <boost/hana/functional/always.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::equal(
+ hana::find_if(BOOST_HANA_STRING(""), hana::always(hana::true_c)),
+ hana::nothing
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(BOOST_HANA_STRING("abcd"), hana::equal.to(hana::char_c<'a'>)),
+ hana::just(hana::char_c<'a'>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(BOOST_HANA_STRING("abcd"), hana::equal.to(hana::char_c<'c'>)),
+ hana::just(hana::char_c<'c'>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::find_if(BOOST_HANA_STRING("abcd"), hana::equal.to(hana::char_c<'d'>)),
+ hana::just(hana::char_c<'d'>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/front.cpp b/src/boost/libs/hana/test/string/front.cpp
new file mode 100644
index 00000000..c8659663
--- /dev/null
+++ b/src/boost/libs/hana/test/string/front.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/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(BOOST_HANA_STRING("a")),
+ hana::char_c<'a'>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(BOOST_HANA_STRING("ab")),
+ hana::char_c<'a'>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(BOOST_HANA_STRING("abc")),
+ hana::char_c<'a'>
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/hash.cpp b/src/boost/libs/hana/test/string/hash.cpp
new file mode 100644
index 00000000..c5995e16
--- /dev/null
+++ b/src/boost/libs/hana/test/string/hash.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/hash.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::hash(hana::string_c<>),
+ hana::type_c<hana::string<>>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::hash(hana::string_c<'a'>),
+ hana::type_c<hana::string<'a'>>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::hash(hana::string_c<'a', 'b'>),
+ hana::type_c<hana::string<'a', 'b'>>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::hash(hana::string_c<'a', 'b', 'c'>),
+ hana::type_c<hana::string<'a', 'b', 'c'>>
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/is_empty.cpp b/src/boost/libs/hana/test/string/is_empty.cpp
new file mode 100644
index 00000000..ab49d576
--- /dev/null
+++ b/src/boost/libs/hana/test/string/is_empty.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/integral_constant.hpp>
+#include <boost/hana/is_empty.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(BOOST_HANA_STRING("")));
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(hana::string_c<>));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(BOOST_HANA_STRING("a"))));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(BOOST_HANA_STRING("ab"))));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(BOOST_HANA_STRING("abc"))));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::string_c<'a'>)));
+}
diff --git a/src/boost/libs/hana/test/string/laws.cpp b/src/boost/libs/hana/test/string/laws.cpp
new file mode 100644
index 00000000..201c3f00
--- /dev/null
+++ b/src/boost/libs/hana/test/string/laws.cpp
@@ -0,0 +1,95 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/string.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/hashable.hpp>
+#include <laws/iterable.hpp>
+#include <laws/monoid.hpp>
+#include <laws/orderable.hpp>
+#include <laws/searchable.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // Comparable and Hashable
+ {
+ auto strings = hana::make_tuple(
+ BOOST_HANA_STRING(""),
+ BOOST_HANA_STRING("a"),
+ BOOST_HANA_STRING("ab"),
+ BOOST_HANA_STRING("abc"),
+ BOOST_HANA_STRING("abcd"),
+ BOOST_HANA_STRING("abcde"),
+ BOOST_HANA_STRING("ba")
+ );
+
+ hana::test::TestComparable<hana::string_tag>{strings};
+ hana::test::TestHashable<hana::string_tag>{strings};
+ }
+
+ // Monoid
+ {
+ auto strings = hana::make_tuple(
+ BOOST_HANA_STRING(""),
+ BOOST_HANA_STRING("a"),
+ BOOST_HANA_STRING("ab"),
+ BOOST_HANA_STRING("abc"),
+ BOOST_HANA_STRING("abcd"),
+ BOOST_HANA_STRING("abcde"),
+ BOOST_HANA_STRING("ba")
+ );
+
+ hana::test::TestMonoid<hana::string_tag>{strings};
+ }
+
+ // Foldable and Iterable
+ {
+ auto strings = hana::make_tuple(
+ BOOST_HANA_STRING(""),
+ BOOST_HANA_STRING("a"),
+ BOOST_HANA_STRING("ab"),
+ BOOST_HANA_STRING("abc"),
+ BOOST_HANA_STRING("abcd"),
+ BOOST_HANA_STRING("abcde"),
+ BOOST_HANA_STRING("ba"),
+ BOOST_HANA_STRING("afcd")
+ );
+
+ hana::test::TestFoldable<hana::string_tag>{strings};
+ hana::test::TestIterable<hana::string_tag>{strings};
+ }
+
+ // Orderable
+ {
+ auto strings = hana::make_tuple(
+ BOOST_HANA_STRING(""),
+ BOOST_HANA_STRING("a"),
+ BOOST_HANA_STRING("ab"),
+ BOOST_HANA_STRING("abc"),
+ BOOST_HANA_STRING("ba"),
+ BOOST_HANA_STRING("abd")
+ );
+
+ hana::test::TestOrderable<hana::string_tag>{strings};
+ }
+
+ // Searchable
+ {
+ auto keys = hana::tuple_c<char, 'a', 'f'>;
+ auto strings = hana::make_tuple(
+ BOOST_HANA_STRING(""),
+ BOOST_HANA_STRING("a"),
+ BOOST_HANA_STRING("ab"),
+ BOOST_HANA_STRING("abcd"),
+ BOOST_HANA_STRING("ba"),
+ BOOST_HANA_STRING("afcd")
+ );
+
+ hana::test::TestSearchable<hana::string_tag>{strings, keys};
+ }
+}
diff --git a/src/boost/libs/hana/test/string/length.cpp b/src/boost/libs/hana/test/string/length.cpp
new file mode 100644
index 00000000..02fd4718
--- /dev/null
+++ b/src/boost/libs/hana/test/string/length.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/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(BOOST_HANA_STRING("")),
+ hana::size_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(BOOST_HANA_STRING("a")),
+ hana::size_c<1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(BOOST_HANA_STRING("ab")),
+ hana::size_c<2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::length(BOOST_HANA_STRING("abc")),
+ hana::size_c<3>
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/less.cpp b/src/boost/libs/hana/test/string/less.cpp
new file mode 100644
index 00000000..53ca1f1c
--- /dev/null
+++ b/src/boost/libs/hana/test/string/less.cpp
@@ -0,0 +1,65 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/greater_equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/less_equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ BOOST_HANA_STRING(""),
+ BOOST_HANA_STRING("")
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ BOOST_HANA_STRING(""),
+ BOOST_HANA_STRING("a")
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ BOOST_HANA_STRING("a"),
+ BOOST_HANA_STRING("")
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ BOOST_HANA_STRING("a"),
+ BOOST_HANA_STRING("ab")
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
+ BOOST_HANA_STRING("ab"),
+ BOOST_HANA_STRING("ab")
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ BOOST_HANA_STRING("abc"),
+ BOOST_HANA_STRING("abcde")
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::less(
+ BOOST_HANA_STRING("abcde"),
+ BOOST_HANA_STRING("abfde")
+ ));
+
+ // check operators
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abc") < BOOST_HANA_STRING("abcd")
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abc") <= BOOST_HANA_STRING("abcd")
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abcd") > BOOST_HANA_STRING("abc")
+ );
+ BOOST_HANA_CONSTANT_CHECK(
+ BOOST_HANA_STRING("abcd") >= BOOST_HANA_STRING("abc")
+ );
+}
diff --git a/src/boost/libs/hana/test/string/macro.cpp b/src/boost/libs/hana/test/string/macro.cpp
new file mode 100644
index 00000000..d70e0515
--- /dev/null
+++ b/src/boost/libs/hana/test/string/macro.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/string.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ // make sure string_c and BOOST_HANA_STRING give the same result
+
+ {
+ auto const s1 = BOOST_HANA_STRING("");
+ auto const s2 = hana::string_c<>;
+ static_assert(std::is_same<decltype(s1), decltype(s2)>::value, "");
+ }
+ {
+ auto const s1 = BOOST_HANA_STRING("a");
+ auto const s2 = hana::string_c<'a'>;
+ static_assert(std::is_same<decltype(s1), decltype(s2)>::value, "");
+ }
+ {
+ auto const s1 = BOOST_HANA_STRING("abcd");
+ auto const s2 = hana::string_c<'a', 'b', 'c', 'd'>;
+ static_assert(std::is_same<decltype(s1), decltype(s2)>::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/string/make.cpp b/src/boost/libs/hana/test/string/make.cpp
new file mode 100644
index 00000000..03235eee
--- /dev/null
+++ b/src/boost/libs/hana/test/string/make.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/integral_constant.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::string_tag>(),
+ hana::string_c<>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::string_tag>(hana::char_c<'a'>),
+ hana::string_c<'a'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::string_tag>(hana::char_c<'a'>, hana::char_c<'b'>),
+ hana::string_c<'a', 'b'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::string_tag>(hana::char_c<'a'>, hana::char_c<'b'>, hana::char_c<'c'>),
+ hana::string_c<'a', 'b', 'c'>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::string_tag>(hana::char_c<'a'>, hana::char_c<'b'>, hana::char_c<'c'>, hana::char_c<'d'>),
+ hana::string_c<'a', 'b', 'c', 'd'>
+ ));
+
+ // make sure make_string == make<string_tag>
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_string(hana::char_c<'a'>, hana::char_c<'b'>, hana::char_c<'c'>),
+ hana::make<hana::string_tag>(hana::char_c<'a'>, hana::char_c<'b'>, hana::char_c<'c'>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/plus.cpp b/src/boost/libs/hana/test/string/plus.cpp
new file mode 100644
index 00000000..d256a555
--- /dev/null
+++ b/src/boost/libs/hana/test/string/plus.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/plus.hpp>
+#include <boost/hana/string.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::plus(BOOST_HANA_STRING(""), BOOST_HANA_STRING("")),
+ BOOST_HANA_STRING("")
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::plus(BOOST_HANA_STRING("abcd"), BOOST_HANA_STRING("")),
+ BOOST_HANA_STRING("abcd")
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::plus(BOOST_HANA_STRING(""), BOOST_HANA_STRING("abcd")),
+ BOOST_HANA_STRING("abcd")
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::plus(BOOST_HANA_STRING("abcd"), BOOST_HANA_STRING("efg")),
+ BOOST_HANA_STRING("abcdefg")
+ ));
+
+ // check operator
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ BOOST_HANA_STRING("abc") + BOOST_HANA_STRING("def"),
+ BOOST_HANA_STRING("abcdef")
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/to.cpp b/src/boost/libs/hana/test/string/to.cpp
new file mode 100644
index 00000000..68c3e00e
--- /dev/null
+++ b/src/boost/libs/hana/test/string/to.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/core/to.hpp>
+#include <boost/hana/string.hpp>
+
+#include <cstring>
+namespace hana = boost::hana;
+
+
+static_assert(hana::is_convertible<hana::string_tag, char const*>{}, "");
+static_assert(!hana::is_embedded<hana::string_tag, char const*>{}, "");
+
+int main() {
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ hana::to<char const*>(BOOST_HANA_STRING("")),
+ ""
+ ) == 0);
+
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ hana::to<char const*>(BOOST_HANA_STRING("a")),
+ "a"
+ ) == 0);
+
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ hana::to<char const*>(BOOST_HANA_STRING("ab")),
+ "ab"
+ ) == 0);
+
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ hana::to<char const*>(BOOST_HANA_STRING("abc")),
+ "abc"
+ ) == 0);
+
+ BOOST_HANA_RUNTIME_CHECK(std::strcmp(
+ hana::to<char const*>(BOOST_HANA_STRING("abcd")),
+ "abcd"
+ ) == 0);
+
+ // make sure we can turn a non-constexpr hana::string
+ // into a constexpr char const*
+ auto str = BOOST_HANA_STRING("abcdef");
+ constexpr char const* c_str = hana::to<char const*>(str);
+ (void)c_str;
+}
diff --git a/src/boost/libs/hana/test/string/udl.cpp b/src/boost/libs/hana/test/string/udl.cpp
new file mode 100644
index 00000000..899612b2
--- /dev/null
+++ b/src/boost/libs/hana/test/string/udl.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/config.hpp>
+#include <boost/hana/string.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ // Check the _s user-defined literal
+#ifdef BOOST_HANA_CONFIG_ENABLE_STRING_UDL
+
+ using namespace hana::literals;
+
+ constexpr auto s1 = "abcd"_s;
+ constexpr auto s2 = hana::string_c<'a', 'b', 'c', 'd'>;
+
+ static_assert(std::is_same<decltype(s1), decltype(s2)>::value, "");
+#endif
+}
diff --git a/src/boost/libs/hana/test/string/unpack.cpp b/src/boost/libs/hana/test/string/unpack.cpp
new file mode 100644
index 00000000..dea55db0
--- /dev/null
+++ b/src/boost/libs/hana/test/string/unpack.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/integral_constant.hpp>
+#include <boost/hana/string.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(BOOST_HANA_STRING(""), f),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(BOOST_HANA_STRING("a"), f),
+ f(hana::char_c<'a'>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(BOOST_HANA_STRING("ab"), f),
+ f(hana::char_c<'a'>, hana::char_c<'b'>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(BOOST_HANA_STRING("abc"), f),
+ f(hana::char_c<'a'>, hana::char_c<'b'>, hana::char_c<'c'>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(BOOST_HANA_STRING("abcd"), f),
+ f(hana::char_c<'a'>, hana::char_c<'b'>, hana::char_c<'c'>, hana::char_c<'d'>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(BOOST_HANA_STRING("abcde"), f),
+ f(hana::char_c<'a'>, hana::char_c<'b'>, hana::char_c<'c'>, hana::char_c<'d'>, hana::char_c<'e'>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/string/zero.cpp b/src/boost/libs/hana/test/string/zero.cpp
new file mode 100644
index 00000000..6cae8c07
--- /dev/null
+++ b/src/boost/libs/hana/test/string/zero.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/zero.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::zero<hana::string_tag>(),
+ BOOST_HANA_STRING("")
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/any_of.clang_ice.cpp b/src/boost/libs/hana/test/tuple/any_of.clang_ice.cpp
new file mode 100644
index 00000000..4e23874c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/any_of.clang_ice.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/any_of.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+// This used to trigger an ICE on Clang
+
+struct Car { std::string name; };
+
+int main() {
+ auto stuff = hana::make_tuple(Car{}, Car{}, Car{});
+ hana::any_of(stuff, [](auto&&) { return true; });
+}
diff --git a/src/boost/libs/hana/test/tuple/assign.convert_copy.cpp b/src/boost/libs/hana/test/tuple/assign.convert_copy.cpp
new file mode 100644
index 00000000..b4debb7a
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/assign.convert_copy.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)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct B {
+ int id_;
+ explicit B(int i = 0) : id_(i) { }
+};
+
+struct D : B {
+ explicit D(int i = 0) : B(i) { }
+};
+
+int main() {
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<int>;
+ T0 t0(2.5);
+ T1 t1;
+ t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char>;
+ using T1 = hana::tuple<int, int>;
+ T0 t0(2.5, 'a');
+ T1 t1;
+ t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ }
+ {
+ using T0 = hana::tuple<double, char, D>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', D(3));
+ T1 t1;
+ t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+ {
+ D d(3);
+ D d2(2);
+ using T0 = hana::tuple<double, char, D&>;
+ using T1 = hana::tuple<int, int, B&>;
+ T0 t0(2.5, 'a', d2);
+ T1 t1(1.5, 'b', d);
+ t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 2);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/assign.convert_move.cpp b/src/boost/libs/hana/test/tuple/assign.convert_move.cpp
new file mode 100644
index 00000000..6a7a7943
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/assign.convert_move.cpp
@@ -0,0 +1,73 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/tuple.hpp>
+
+#include <memory>
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct B {
+ int id_;
+ explicit B(int i = 0) : id_(i) {}
+ virtual ~B() {}
+};
+
+struct D : B {
+ explicit D(int i) : B(i) {}
+};
+
+int main() {
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<int>;
+ T0 t0(2.5);
+ T1 t1;
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char>;
+ using T1 = hana::tuple<int, int>;
+ T0 t0(2.5, 'a');
+ T1 t1;
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ }
+ {
+ using T0 = hana::tuple<double, char, D>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', D(3));
+ T1 t1;
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+ {
+ D d(3);
+ D d2(2);
+ using T0 = hana::tuple<double, char, D&>;
+ using T1 = hana::tuple<int, int, B&>;
+ T0 t0(2.5, 'a', d2);
+ T1 t1(1.5, 'b', d);
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char, std::unique_ptr<D>>;
+ using T1 = hana::tuple<int, int, std::unique_ptr<B>>;
+ T0 t0(2.5, 'a', std::unique_ptr<D>(new D(3)));
+ T1 t1;
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1)->id_ == 3);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/assign.copy.cpp b/src/boost/libs/hana/test/tuple/assign.copy.cpp
new file mode 100644
index 00000000..dedc276a
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/assign.copy.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/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ using T = hana::tuple<>;
+ T t0;
+ T t;
+ t = t0;
+ }
+ {
+ using T = hana::tuple<int>;
+ T t0(2);
+ T t;
+ t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ }
+ {
+ using T = hana::tuple<int, char>;
+ T t0(2, 'a');
+ T t;
+ t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ }
+ {
+ using T = hana::tuple<int, char, std::string>;
+ const T t0(2, 'a', "some text");
+ T t;
+ t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "some text");
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/assign.move.cpp b/src/boost/libs/hana/test/tuple/assign.move.cpp
new file mode 100644
index 00000000..6dd77612
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/assign.move.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/tuple.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data = 1) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ int get() const {return data_;}
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+ bool operator< (const MoveOnly& x) const { return data_ < x.data_; }
+};
+
+int main() {
+ {
+ using T = hana::tuple<>;
+ T t0;
+ T t;
+ t = std::move(t0);
+ }
+ {
+ using T = hana::tuple<MoveOnly>;
+ T t0(MoveOnly(0));
+ T t;
+ t = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ using T = hana::tuple<MoveOnly, MoveOnly>;
+ T t0(MoveOnly(0), MoveOnly(1));
+ T t;
+ t = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ }
+ {
+ using T = hana::tuple<MoveOnly, MoveOnly, MoveOnly>;
+ T t0(MoveOnly(0), MoveOnly(1), MoveOnly(2));
+ T t;
+ t = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/at.const.cpp b/src/boost/libs/hana/test/tuple/at.const.cpp
new file mode 100644
index 00000000..47d9b624
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/at.const.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/assert.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Empty { };
+
+int main() {
+ {
+ using T = hana::tuple<int>;
+ const T t(3);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 3);
+ }
+ {
+ using T = hana::tuple<std::string, int>;
+ const T t("high", 5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 5);
+ }
+ {
+ using T = hana::tuple<double, int>;
+ constexpr T t(2.718, 5);
+ static_assert(hana::at_c<0>(t) == 2.718, "");
+ static_assert(hana::at_c<1>(t) == 5, "");
+ }
+ {
+ using T = hana::tuple<Empty>;
+ constexpr T t{Empty()};
+ constexpr Empty e = hana::at_c<0>(t); (void)e;
+ }
+ {
+ using T = hana::tuple<double&, std::string, int>;
+ double d = 1.5;
+ const T t(d, "high", 5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1.5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 5);
+ hana::at_c<0>(t) = 2.5;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2.5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 5);
+ BOOST_HANA_RUNTIME_CHECK(d == 2.5);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/at.non_const.cpp b/src/boost/libs/hana/test/tuple/at.non_const.cpp
new file mode 100644
index 00000000..3e47c35d
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/at.non_const.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/assert.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Empty {};
+
+struct S {
+ constexpr S()
+ : a{1, Empty{}},
+ k(hana::at_c<0>(a)),
+ e(hana::at_c<1>(a))
+ { }
+
+ hana::tuple<int, Empty> a;
+ int k;
+ Empty e;
+};
+
+constexpr hana::tuple<int, int> getP () { return { 3, 4 }; }
+
+int main() {
+ {
+ using T = hana::tuple<int>;
+ T t(3);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 3);
+ hana::at_c<0>(t) = 2;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ }
+ {
+ using T = hana::tuple<std::string, int>;
+ T t("high", 5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 5);
+ hana::at_c<0>(t) = "four";
+ hana::at_c<1>(t) = 4;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == "four");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 4);
+ }
+ {
+ using T = hana::tuple<double&, std::string, int>;
+ double d = 1.5;
+ T t(d, "high", 5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1.5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 5);
+ hana::at_c<0>(t) = 2.5;
+ hana::at_c<1>(t) = "four";
+ hana::at_c<2>(t) = 4;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2.5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == "four");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 4);
+ BOOST_HANA_RUNTIME_CHECK(d == 2.5);
+ }
+ // get on a rvalue tuple
+ {
+ static_assert(hana::at_c<0>(hana::tuple<float, int, double, long>{0.0f, 1, 2.0, 3L}) == 0, "" );
+ static_assert(hana::at_c<1>(hana::tuple<float, int, double, long>{0.0f, 1, 2.0, 3L}) == 1, "" );
+ static_assert(hana::at_c<2>(hana::tuple<float, int, double, long>{0.0f, 1, 2.0, 3L}) == 2, "" );
+ static_assert(hana::at_c<3>(hana::tuple<float, int, double, long>{0.0f, 1, 2.0, 3L}) == 3, "" );
+ static_assert(S().k == 1, "");
+ static_assert(hana::at_c<1>(getP()) == 4, "");
+ }
+ {
+ // make sure get<> returns the right types
+ struct T { };
+ struct U { };
+ struct V { };
+
+ hana::tuple<T, U, V> xs{};
+ (void)static_cast<T>(hana::at_c<0>(xs));
+ (void)static_cast<U>(hana::at_c<1>(xs));
+ (void)static_cast<V>(hana::at_c<2>(xs));
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/at.rv.cpp b/src/boost/libs/hana/test/tuple/at.rv.cpp
new file mode 100644
index 00000000..e1591609
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/at.rv.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/tuple.hpp>
+
+#include <support/tracked.hpp>
+
+#include <utility>
+#include <memory>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ using T = hana::tuple<std::unique_ptr<int>>;
+ T t(std::unique_ptr<int>(new int(3)));
+ std::unique_ptr<int> p = hana::at_c<0>(std::move(t));
+ BOOST_HANA_RUNTIME_CHECK(*p == 3);
+ }
+ // make sure we don't double-move and do other weird stuff
+ {
+ hana::tuple<Tracked, Tracked, Tracked> xs{
+ Tracked{1}, Tracked{2}, Tracked{3}
+ };
+
+ Tracked a = hana::at_c<0>(std::move(xs)); (void)a;
+ Tracked b = hana::at_c<1>(std::move(xs)); (void)b;
+ Tracked c = hana::at_c<2>(std::move(xs)); (void)c;
+ }
+ // test with nested closures
+ {
+ using Inner = hana::tuple<Tracked, Tracked>;
+ hana::tuple<Inner> xs{Inner{Tracked{1}, Tracked{2}}};
+
+ Tracked a = hana::at_c<0>(hana::at_c<0>(std::move(xs))); (void)a;
+ Tracked b = hana::at_c<1>(hana::at_c<0>(std::move(xs))); (void)b;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/auto/_specs.hpp b/src/boost/libs/hana/test/tuple/auto/_specs.hpp
new file mode 100644
index 00000000..0b957f4c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/_specs.hpp
@@ -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)
+
+#ifndef BOOST_HANA_TEST_TUPLE_AUTO_SPECS_HPP
+#define BOOST_HANA_TEST_TUPLE_AUTO_SPECS_HPP
+
+#include <boost/hana/tuple.hpp>
+
+
+#define MAKE_TUPLE(...) ::boost::hana::make_tuple(__VA_ARGS__)
+#define TUPLE_TYPE(...) ::boost::hana::tuple<__VA_ARGS__>
+#define TUPLE_TAG ::boost::hana::tuple_tag
+
+#endif // !BOOST_HANA_TEST_TUPLE_AUTO_SPECS_HPP
diff --git a/src/boost/libs/hana/test/tuple/auto/all_of.cpp b/src/boost/libs/hana/test/tuple/auto/all_of.cpp
new file mode 100644
index 00000000..f3e974ff
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/all_of.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 "_specs.hpp"
+#include <auto/all_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/any_of.cpp b/src/boost/libs/hana/test/tuple/auto/any_of.cpp
new file mode 100644
index 00000000..3065d017
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/any_of.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 "_specs.hpp"
+#include <auto/any_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/ap.cpp b/src/boost/libs/hana/test/tuple/auto/ap.cpp
new file mode 100644
index 00000000..59c9cb75
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/ap.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 "_specs.hpp"
+#include <auto/ap.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/at.cpp b/src/boost/libs/hana/test/tuple/auto/at.cpp
new file mode 100644
index 00000000..60526533
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/at.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 "_specs.hpp"
+#include <auto/at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/cartesian_product.cpp b/src/boost/libs/hana/test/tuple/auto/cartesian_product.cpp
new file mode 100644
index 00000000..b0795e8d
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/cartesian_product.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 "_specs.hpp"
+#include <auto/cartesian_product.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/drop_back.cpp b/src/boost/libs/hana/test/tuple/auto/drop_back.cpp
new file mode 100644
index 00000000..b283844d
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/drop_back.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 "_specs.hpp"
+#include <auto/drop_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/drop_front.cpp b/src/boost/libs/hana/test/tuple/auto/drop_front.cpp
new file mode 100644
index 00000000..a39d6f45
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/drop_front.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 "_specs.hpp"
+#include <auto/drop_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/drop_while.cpp b/src/boost/libs/hana/test/tuple/auto/drop_while.cpp
new file mode 100644
index 00000000..18907f03
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/drop_while.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 "_specs.hpp"
+#include <auto/drop_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/for_each.cpp b/src/boost/libs/hana/test/tuple/auto/for_each.cpp
new file mode 100644
index 00000000..714fe03c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/for_each.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 "_specs.hpp"
+#include <auto/for_each.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/group.cpp b/src/boost/libs/hana/test/tuple/auto/group.cpp
new file mode 100644
index 00000000..0669b496
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/group.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 "_specs.hpp"
+#include <auto/group.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/index_if.cpp b/src/boost/libs/hana/test/tuple/auto/index_if.cpp
new file mode 100644
index 00000000..ef37fe65
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/index_if.cpp
@@ -0,0 +1,9 @@
+// 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 "_specs.hpp"
+#include <auto/index_if.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/insert.cpp b/src/boost/libs/hana/test/tuple/auto/insert.cpp
new file mode 100644
index 00000000..e8efc6dc
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/insert.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 "_specs.hpp"
+#include <auto/insert.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/insert_range.cpp b/src/boost/libs/hana/test/tuple/auto/insert_range.cpp
new file mode 100644
index 00000000..05ac5774
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/insert_range.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 "_specs.hpp"
+#include <auto/insert_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/intersperse.cpp b/src/boost/libs/hana/test/tuple/auto/intersperse.cpp
new file mode 100644
index 00000000..185c814a
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/intersperse.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 "_specs.hpp"
+#include <auto/intersperse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/is_empty.cpp b/src/boost/libs/hana/test/tuple/auto/is_empty.cpp
new file mode 100644
index 00000000..f175f7dd
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/is_empty.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 "_specs.hpp"
+#include <auto/is_empty.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/length.cpp b/src/boost/libs/hana/test/tuple/auto/length.cpp
new file mode 100644
index 00000000..55111dd6
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/length.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 "_specs.hpp"
+#include <auto/length.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/lexicographical_compare.cpp b/src/boost/libs/hana/test/tuple/auto/lexicographical_compare.cpp
new file mode 100644
index 00000000..4d2f3edf
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/lexicographical_compare.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 "_specs.hpp"
+#include <auto/lexicographical_compare.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/make.cpp b/src/boost/libs/hana/test/tuple/auto/make.cpp
new file mode 100644
index 00000000..f90514f1
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/make.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 "_specs.hpp"
+#include <auto/make.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/none_of.cpp b/src/boost/libs/hana/test/tuple/auto/none_of.cpp
new file mode 100644
index 00000000..b56a27b4
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/none_of.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 "_specs.hpp"
+#include <auto/none_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/partition.cpp b/src/boost/libs/hana/test/tuple/auto/partition.cpp
new file mode 100644
index 00000000..ba9621a6
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/partition.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 "_specs.hpp"
+#include <auto/partition.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/permutations.cpp b/src/boost/libs/hana/test/tuple/auto/permutations.cpp
new file mode 100644
index 00000000..3c1a6e85
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/permutations.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 "_specs.hpp"
+#include <auto/permutations.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/remove_at.cpp b/src/boost/libs/hana/test/tuple/auto/remove_at.cpp
new file mode 100644
index 00000000..5b7c5af4
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/remove_at.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 "_specs.hpp"
+#include <auto/remove_at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/remove_range.cpp b/src/boost/libs/hana/test/tuple/auto/remove_range.cpp
new file mode 100644
index 00000000..6d7c6e09
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/remove_range.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 "_specs.hpp"
+#include <auto/remove_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/reverse.cpp b/src/boost/libs/hana/test/tuple/auto/reverse.cpp
new file mode 100644
index 00000000..342278df
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/reverse.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 "_specs.hpp"
+#include <auto/reverse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/scans.cpp b/src/boost/libs/hana/test/tuple/auto/scans.cpp
new file mode 100644
index 00000000..36dd3243
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/scans.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 "_specs.hpp"
+#include <auto/scans.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/sequence.cpp b/src/boost/libs/hana/test/tuple/auto/sequence.cpp
new file mode 100644
index 00000000..4ed01e85
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/sequence.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 "_specs.hpp"
+#include <auto/sequence.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/slice.cpp b/src/boost/libs/hana/test/tuple/auto/slice.cpp
new file mode 100644
index 00000000..3e20df95
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/slice.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 "_specs.hpp"
+#include <auto/slice.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/sort.cpp b/src/boost/libs/hana/test/tuple/auto/sort.cpp
new file mode 100644
index 00000000..f639ddeb
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/sort.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 "_specs.hpp"
+#include <auto/sort.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/span.cpp b/src/boost/libs/hana/test/tuple/auto/span.cpp
new file mode 100644
index 00000000..297b7f17
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/span.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 "_specs.hpp"
+#include <auto/span.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/take_back.cpp b/src/boost/libs/hana/test/tuple/auto/take_back.cpp
new file mode 100644
index 00000000..2a91d7d4
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/take_back.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 "_specs.hpp"
+#include <auto/take_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/take_front.cpp b/src/boost/libs/hana/test/tuple/auto/take_front.cpp
new file mode 100644
index 00000000..9a48d2b8
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/take_front.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 "_specs.hpp"
+#include <auto/take_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/take_while.cpp b/src/boost/libs/hana/test/tuple/auto/take_while.cpp
new file mode 100644
index 00000000..e58c99ac
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/take_while.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 "_specs.hpp"
+#include <auto/take_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/transform.cpp b/src/boost/libs/hana/test/tuple/auto/transform.cpp
new file mode 100644
index 00000000..306c1bc3
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/transform.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 "_specs.hpp"
+#include <auto/transform.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/unfolds.cpp b/src/boost/libs/hana/test/tuple/auto/unfolds.cpp
new file mode 100644
index 00000000..f8bac9dd
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/unfolds.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 "_specs.hpp"
+#include <auto/unfolds.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/unique.cpp b/src/boost/libs/hana/test/tuple/auto/unique.cpp
new file mode 100644
index 00000000..9c1dc715
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/unique.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 "_specs.hpp"
+#include <auto/unique.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/zips.cpp b/src/boost/libs/hana/test/tuple/auto/zips.cpp
new file mode 100644
index 00000000..32ec5cc8
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/zips.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 "_specs.hpp"
+#include <auto/zips.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/cnstr.convert_copy.cpp b/src/boost/libs/hana/test/tuple/cnstr.convert_copy.cpp
new file mode 100644
index 00000000..f8cb0d8d
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.convert_copy.cpp
@@ -0,0 +1,93 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct A {
+ int id_;
+ constexpr A(int i) : id_(i) {}
+ friend constexpr bool operator==(const A& x, const A& y)
+ { return x.id_ == y.id_; }
+};
+
+struct B {
+ int id_;
+ explicit B(int i) : id_(i) {}
+};
+
+struct C {
+ int id_;
+ constexpr explicit C(int i) : id_(i) {}
+ friend constexpr bool operator==(const C& x, const C& y)
+ { return x.id_ == y.id_; }
+};
+
+struct D : B {
+ explicit D(int i) : B(i) {}
+};
+
+
+int main() {
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<int>;
+ T0 t0(2.5);
+ T1 t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ }
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<A>;
+ constexpr T0 t0(2.5);
+ constexpr T1 t1 = t0;
+ static_assert(hana::at_c<0>(t1) == 2, "");
+ }
+ {
+ using T0 = hana::tuple<int>;
+ using T1 = hana::tuple<C>;
+ constexpr T0 t0(2);
+ constexpr T1 t1{t0};
+ static_assert(hana::at_c<0>(t1) == C(2), "");
+ }
+ {
+ using T0 = hana::tuple<double, char>;
+ using T1 = hana::tuple<int, int>;
+ T0 t0(2.5, 'a');
+ T1 t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ }
+ {
+ using T0 = hana::tuple<double, char, D>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', D(3));
+ T1 t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+ {
+ D d(3);
+ using T0 = hana::tuple<double, char, D&>;
+ using T1 = hana::tuple<int, int, B&>;
+ T0 t0(2.5, 'a', d);
+ T1 t1 = t0;
+ d.id_ = 2;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char, int>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', 3);
+ T1 t1(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.convert_move.cpp b/src/boost/libs/hana/test/tuple/cnstr.convert_move.cpp
new file mode 100644
index 00000000..f8274429
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.convert_move.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/tuple.hpp>
+
+#include <string>
+#include <memory>
+namespace hana = boost::hana;
+
+
+struct B {
+ int id_;
+ explicit B(int i) : id_(i) {}
+ virtual ~B() {}
+};
+
+struct D : B {
+ explicit D(int i) : B(i) {}
+};
+
+int main() {
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<int>;
+ T0 t0(2.5);
+ T1 t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char>;
+ using T1 = hana::tuple<int, int>;
+ T0 t0(2.5, 'a');
+ T1 t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ }
+ {
+ using T0 = hana::tuple<double, char, D>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', D(3));
+ T1 t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+ {
+ D d(3);
+ using T0 = hana::tuple<double, char, D&>;
+ using T1 = hana::tuple<int, int, B&>;
+ T0 t0(2.5, 'a', d);
+ T1 t1 = std::move(t0);
+ d.id_ = 2;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char, std::unique_ptr<D>>;
+ using T1 = hana::tuple<int, int, std::unique_ptr<B>>;
+ T0 t0(2.5, 'a', std::unique_ptr<D>(new D(3)));
+ T1 t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1)->id_ == 3);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.copy.cpp b/src/boost/libs/hana/test/tuple/cnstr.copy.cpp
new file mode 100644
index 00000000..e0d8638f
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.copy.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/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Empty { };
+
+int main() {
+ {
+ using T = hana::tuple<>;
+ T t0;
+ T t_implicit = t0;
+ T t_explicit(t0);
+
+ (void)t_explicit;
+ (void)t_implicit;
+ }
+ {
+ using T = hana::tuple<int>;
+ T t0(2);
+ T t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ }
+ {
+ using T = hana::tuple<int, char>;
+ T t0(2, 'a');
+ T t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ }
+ {
+ using T = hana::tuple<int, char, std::string>;
+ const T t0(2, 'a', "some text");
+ T t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "some text");
+ }
+ {
+ using T = hana::tuple<int>;
+ constexpr T t0(2);
+ constexpr T t = t0;
+ static_assert(hana::at_c<0>(t) == 2, "");
+ }
+ {
+ using T = hana::tuple<Empty>;
+ constexpr T t0;
+ constexpr T t = t0;
+ constexpr Empty e = hana::at_c<0>(t); (void)e;
+ }
+ {
+ struct T { };
+ struct U { };
+
+ constexpr hana::tuple<T, U> binary{};
+ constexpr hana::tuple<T, U> copy_implicit = binary;
+ constexpr hana::tuple<T, U> copy_explicit(binary);
+
+ (void)copy_implicit;
+ (void)copy_explicit;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.default.cpp b/src/boost/libs/hana/test/tuple/cnstr.default.cpp
new file mode 100644
index 00000000..5d9af67a
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.default.cpp
@@ -0,0 +1,138 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/tuple.hpp>
+
+#include <string>
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct DefaultOnly {
+ int data_;
+ DefaultOnly(DefaultOnly const&) = delete;
+ DefaultOnly& operator=(DefaultOnly const&) = delete;
+
+ static int count;
+
+ DefaultOnly() : data_(-1) { ++count; }
+ ~DefaultOnly() { data_ = 0; --count; }
+
+ friend bool operator==(DefaultOnly const& x, DefaultOnly const& y)
+ { return x.data_ == y.data_; }
+
+ friend bool operator< (DefaultOnly const& x, DefaultOnly const& y)
+ { return x.data_ < y.data_; }
+};
+
+int DefaultOnly::count = 0;
+
+struct NoDefault {
+ NoDefault() = delete;
+ explicit NoDefault(int) { }
+};
+
+struct IllFormedDefault {
+ IllFormedDefault(int x) : value(x) {}
+ template <bool Pred = false>
+ constexpr IllFormedDefault() {
+ static_assert(Pred,
+ "The default constructor should not be instantiated");
+ }
+ int value;
+};
+
+int main() {
+ {
+ hana::tuple<> t; (void)t;
+ }
+ {
+ hana::tuple<int> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ hana::tuple<int, char*> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ }
+ {
+ hana::tuple<int, char*, std::string> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
+ }
+ {
+ hana::tuple<int, char*, std::string, DefaultOnly> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == DefaultOnly());
+ }
+ {
+ // See LLVM bug #21157.
+ static_assert(!std::is_default_constructible<
+ hana::tuple<NoDefault>
+ >(), "");
+ static_assert(!std::is_default_constructible<
+ hana::tuple<DefaultOnly, NoDefault>
+ >(), "");
+ static_assert(!std::is_default_constructible<
+ hana::tuple<NoDefault, DefaultOnly, NoDefault>
+ >(), "");
+ }
+ {
+ struct T { };
+ struct U { };
+ struct V { };
+
+ constexpr hana::tuple<> z0; (void)z0;
+ constexpr hana::tuple<T> z1; (void)z1;
+ constexpr hana::tuple<T, U> z2; (void)z2;
+ constexpr hana::tuple<T, U, V> z3; (void)z3;
+ }
+ {
+ constexpr hana::tuple<int> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ constexpr hana::tuple<int, char*> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ }
+
+ // Make sure we can hold non default-constructible elements, and that
+ // it does not trigger an error in the default constructor.
+ {
+ {
+ IllFormedDefault v(0);
+ hana::tuple<IllFormedDefault> t1(v);
+ hana::tuple<IllFormedDefault> t2{v};
+ hana::tuple<IllFormedDefault> t3 = {v};
+ (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
+ }
+ {
+ hana::tuple<NoDefault> t1(0);
+ hana::tuple<NoDefault> t2{0};
+ hana::tuple<NoDefault> t3 = {0};
+ (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
+ }
+ {
+ NoDefault v(0);
+ hana::tuple<NoDefault> t1(v);
+ hana::tuple<NoDefault> t2{v};
+ hana::tuple<NoDefault> t3 = {v};
+ (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
+ }
+ }
+
+ // Make sure a tuple_t can be default-constructed
+ {
+ struct T;
+ struct U;
+
+ using Types = decltype(hana::tuple_t<T, U>);
+ Types t{}; (void)t;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.move.cpp b/src/boost/libs/hana/test/tuple/cnstr.move.cpp
new file mode 100644
index 00000000..c9644cba
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.move.cpp
@@ -0,0 +1,73 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/tuple.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data = 1) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ int get() const {return data_;}
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+ bool operator< (const MoveOnly& x) const { return data_ < x.data_; }
+};
+
+int main() {
+ {
+ using T = hana::tuple<>;
+ T t0;
+ T t = std::move(t0); (void)t;
+ }
+ {
+ using T = hana::tuple<MoveOnly>;
+ T t0(MoveOnly(0));
+ T t = std::move(t0); (void)t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ using T = hana::tuple<MoveOnly, MoveOnly>;
+ T t0(MoveOnly(0), MoveOnly(1));
+ T t = std::move(t0); (void)t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ }
+ {
+ using T = hana::tuple<MoveOnly, MoveOnly, MoveOnly>;
+ T t0(MoveOnly(0), MoveOnly(1), MoveOnly(2));
+ T t = std::move(t0); (void)t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ }
+ {
+ // Check for SFINAE-friendliness
+ static_assert(!std::is_constructible<
+ hana::tuple<MoveOnly>, MoveOnly const&
+ >{}, "");
+
+ static_assert(!std::is_constructible<
+ hana::tuple<MoveOnly>, MoveOnly&
+ >{}, "");
+
+ static_assert(std::is_constructible<
+ hana::tuple<MoveOnly>, MoveOnly
+ >{}, "");
+
+ static_assert(std::is_constructible<
+ hana::tuple<MoveOnly>, MoveOnly&&
+ >{}, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.nested.cpp b/src/boost/libs/hana/test/tuple/cnstr.nested.cpp
new file mode 100644
index 00000000..7cbdb5da
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.nested.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/tuple.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// See this bug: https://llvm.org/bugs/show_bug.cgi?id=24173
+
+template <typename ...Xs>
+constexpr hana::tuple<std::decay_t<Xs>...> f(Xs&& ...xs)
+{ return hana::tuple<std::decay_t<Xs>...>{static_cast<Xs&&>(xs)...}; }
+
+int main() {
+ f(f(f(f(f(f(f(f(f(f(f(f(1))))))))))));
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.trap.cpp b/src/boost/libs/hana/test/tuple/cnstr.trap.cpp
new file mode 100644
index 00000000..a088b946
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.trap.cpp
@@ -0,0 +1,120 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/tuple.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+// Make sure that the tuple(Yn&&...) is not preferred over copy constructors
+// in single-element cases and other similar cases.
+
+struct Trap1 {
+ Trap1() = default;
+ Trap1(Trap1 const&) = default;
+#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
+ Trap1(Trap1&) = default;
+#endif
+ Trap1(Trap1&&) = default;
+
+ template <typename X>
+ Trap1(X&&) {
+ static_assert(sizeof(X) && false,
+ "this constructor must not be instantiated");
+ }
+};
+
+struct Trap2 {
+ Trap2() = default;
+ Trap2(Trap2 const&) = default;
+#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
+ Trap2(Trap2&) = default;
+#endif
+ Trap2(Trap2&&) = default;
+
+ template <typename X>
+ Trap2(X) { // not by reference
+ static_assert(sizeof(X) && false,
+ "this constructor must not be instantiated");
+ }
+};
+
+struct Trap3 {
+ Trap3() = default;
+ Trap3(Trap3 const&) = default;
+#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
+ Trap3(Trap3&) = default;
+#endif
+ Trap3(Trap3&&) = default;
+
+ template <typename X>
+ constexpr explicit Trap3(X&&) { // explicit, and constexpr
+ static_assert(sizeof(X) && false,
+ "this constructor must not be instantiated");
+ }
+};
+
+struct Trap4 {
+ Trap4() = default;
+ template <typename Args>
+ constexpr explicit Trap4(Args&&) {
+ static_assert(sizeof(Args) && false, "must never be instantiated");
+ }
+
+ Trap4(Trap4 const&) = default;
+ Trap4(Trap4&&) = default;
+};
+
+int main() {
+ {
+ hana::tuple<Trap1> tuple{};
+ hana::tuple<Trap1> implicit_copy = tuple;
+ hana::tuple<Trap1> explicit_copy(tuple);
+ hana::tuple<Trap1> implicit_move = std::move(tuple);
+ hana::tuple<Trap1> explicit_move(std::move(tuple));
+
+ (void)implicit_copy;
+ (void)explicit_copy;
+ (void)implicit_move;
+ (void)explicit_move;
+ }
+
+ {
+ hana::tuple<Trap2> tuple{};
+ hana::tuple<Trap2> implicit_copy = tuple;
+ hana::tuple<Trap2> explicit_copy(tuple);
+ hana::tuple<Trap2> implicit_move = std::move(tuple);
+ hana::tuple<Trap2> explicit_move(std::move(tuple));
+
+ (void)implicit_copy;
+ (void)explicit_copy;
+ (void)implicit_move;
+ (void)explicit_move;
+ }
+
+ {
+ hana::tuple<Trap3> tuple{};
+ hana::tuple<Trap3> implicit_copy = tuple;
+ hana::tuple<Trap3> explicit_copy(tuple);
+ hana::tuple<Trap3> implicit_move = std::move(tuple);
+ hana::tuple<Trap3> explicit_move(std::move(tuple));
+
+ (void)implicit_copy;
+ (void)explicit_copy;
+ (void)implicit_move;
+ (void)explicit_move;
+ }
+
+ // Just defining the structure used to cause a failure, because of the
+ // explicitly defaulted copy-constructor.
+ {
+ struct Foo {
+ Foo() = default;
+ Foo(Foo const&) = default;
+ Foo(Foo&&) = default;
+ hana::tuple<Trap4> t;
+ };
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.variadic_array.cpp b/src/boost/libs/hana/test/tuple/cnstr.variadic_array.cpp
new file mode 100644
index 00000000..02338b95
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.variadic_array.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/tuple.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+//
+// This test checks that we can NOT construct a tuple holding array members,
+// per the standard.
+//
+
+int main() {
+ static_assert(!std::is_constructible<hana::tuple<int[3]>, int[3]>{}, "");
+ static_assert(!std::is_constructible<hana::tuple<int[3], float[4]>, int[3], float[4]>{}, "");
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.variadic_copy.cpp b/src/boost/libs/hana/test/tuple/cnstr.variadic_copy.cpp
new file mode 100644
index 00000000..44f9f4b8
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.variadic_copy.cpp
@@ -0,0 +1,125 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct never { static constexpr bool value = false; };
+
+struct NoValueCtor {
+ NoValueCtor() : id(++count) {}
+ NoValueCtor(NoValueCtor const & other) : id(other.id) { ++count; }
+
+ // The constexpr is required to make is_constructible instantiate this
+ // template. The explicit is needed to test-around a similar bug with
+ // is_convertible.
+ template <typename T>
+ constexpr explicit NoValueCtor(T)
+ { static_assert(never<T>::value, "This should not be instantiated"); }
+
+ static int count;
+ int id;
+};
+
+int NoValueCtor::count = 0;
+
+
+struct NoValueCtorEmpty {
+ NoValueCtorEmpty() {}
+ NoValueCtorEmpty(NoValueCtorEmpty const &) {}
+
+ template <typename T>
+ constexpr explicit NoValueCtorEmpty(T)
+ { static_assert(never<T>::value, "This should not be instantiated"); }
+};
+
+int main() {
+ {
+ hana::tuple<int> t(2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ }
+ {
+ constexpr hana::tuple<int> t(2);
+ static_assert(hana::at_c<0>(t) == 2, "");
+ }
+ {
+ constexpr hana::tuple<int> t;
+ static_assert(hana::at_c<0>(t) == 0, "");
+ }
+ {
+ constexpr hana::tuple<int, char*> t(2, nullptr);
+ static_assert(hana::at_c<0>(t) == 2, "");
+ static_assert(hana::at_c<1>(t) == nullptr, "");
+ }
+ {
+ hana::tuple<int, char*> t(2, nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ }
+ {
+ hana::tuple<int, char*, std::string> t(2, nullptr, "text");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "text");
+ }
+ {
+ hana::tuple<int, NoValueCtor, int, int> t(1, NoValueCtor(), 2, 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t).id == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == 3);
+ }
+ {
+ hana::tuple<int, NoValueCtorEmpty, int, int> t(1, NoValueCtorEmpty(), 2, 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == 3);
+ }
+ {
+ struct T { };
+ struct U { };
+ struct V { };
+
+ constexpr T t{};
+ constexpr U u{};
+ constexpr V v{};
+
+ constexpr hana::tuple<T> x1{t}; (void)x1;
+ constexpr hana::tuple<T, U> x2{t, u}; (void)x2;
+ constexpr hana::tuple<T, U, V> x3{t, u, v}; (void)x3;
+ }
+ {
+ struct T { };
+ struct U { };
+ struct V { };
+
+ // Check for SFINAE-friendliness
+ static_assert(!std::is_constructible<
+ hana::tuple<T, U>, T
+ >{}, "");
+
+ static_assert(!std::is_constructible<
+ hana::tuple<T, U>, U, T
+ >{}, "");
+
+ static_assert(!std::is_constructible<
+ hana::tuple<T, U>, T, U, V
+ >{}, "");
+ }
+
+ // Make sure we can initialize elements with the brace-init syntax.
+ {
+ struct Member { };
+ struct Element { Member member; };
+
+ hana::tuple<Element, Element> xs{{Member()}, {Member()}};
+ hana::tuple<Element, Element> ys = {{Member()}, {Member()}};
+ (void)xs; (void)ys;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.variadic_forward.cpp b/src/boost/libs/hana/test/tuple/cnstr.variadic_forward.cpp
new file mode 100644
index 00000000..dc69ba73
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.variadic_forward.cpp
@@ -0,0 +1,114 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/tuple.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data = 1) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ int get() const {return data_;}
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+ bool operator< (const MoveOnly& x) const { return data_ < x.data_; }
+};
+
+struct Empty { };
+struct A {
+ int id_;
+ explicit constexpr A(int i) : id_(i) {}
+};
+
+struct NoDefault { NoDefault() = delete; };
+
+int main() {
+ {
+ hana::tuple<MoveOnly> t(MoveOnly(0));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ hana::tuple<MoveOnly, MoveOnly> t(MoveOnly(0), MoveOnly(1));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ }
+ {
+ hana::tuple<MoveOnly, MoveOnly, MoveOnly> t(
+ MoveOnly(0), MoveOnly(1), MoveOnly(2)
+ );
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ }
+ {
+ constexpr hana::tuple<Empty> t0{Empty()}; (void)t0;
+ }
+ {
+ constexpr hana::tuple<A, A> t(3, 2);
+ static_assert(hana::at_c<0>(t).id_ == 3, "");
+ }
+ {
+ typedef hana::tuple<MoveOnly, NoDefault> Tuple;
+
+ static_assert(!std::is_constructible<
+ Tuple,
+ MoveOnly
+ >::value, "");
+
+ static_assert(std::is_constructible<
+ Tuple,
+ MoveOnly, NoDefault
+ >::value, "");
+ }
+ {
+ typedef hana::tuple<MoveOnly, MoveOnly, NoDefault> Tuple;
+
+ static_assert(!std::is_constructible<
+ Tuple,
+ MoveOnly, MoveOnly
+ >::value, "");
+
+ static_assert(std::is_constructible<
+ Tuple,
+ MoveOnly, MoveOnly, NoDefault
+ >::value, "");
+ }
+ {
+ typedef hana::tuple<MoveOnly, NoDefault> Tuple;
+ typedef hana::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
+
+ static_assert(!std::is_constructible<
+ NestedTuple,
+ MoveOnly, MoveOnly, MoveOnly, MoveOnly
+ >::value, "");
+
+ static_assert(std::is_constructible<
+ NestedTuple,
+ MoveOnly, Tuple, MoveOnly, MoveOnly
+ >::value, "");
+ }
+ {
+ typedef hana::tuple<MoveOnly, int> Tuple;
+ typedef hana::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
+
+ static_assert(!std::is_constructible<
+ NestedTuple,
+ MoveOnly, MoveOnly, MoveOnly, MoveOnly
+ >::value, "");
+
+ static_assert(std::is_constructible<
+ NestedTuple,
+ MoveOnly, Tuple, MoveOnly, MoveOnly
+ >::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/empty_member.cpp b/src/boost/libs/hana/test/tuple/empty_member.cpp
new file mode 100644
index 00000000..1bab8318
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/empty_member.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/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct A { };
+struct B { };
+
+int main() {
+ {
+ using T = hana::tuple<int, A>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+ {
+ using T = hana::tuple<A, int>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+ {
+ using T = hana::tuple<A, int, B>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+ {
+ using T = hana::tuple<A, B, int>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+ {
+ using T = hana::tuple<int, A, B>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/hold_refs.cpp b/src/boost/libs/hana/test/tuple/hold_refs.cpp
new file mode 100644
index 00000000..fb900194
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/hold_refs.cpp
@@ -0,0 +1,78 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/tuple.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+// a non-movable, non-copyable type
+struct RefOnly {
+ RefOnly() = default;
+ RefOnly(RefOnly const&) = delete;
+ RefOnly(RefOnly&&) = delete;
+};
+
+struct Empty { };
+
+int main() {
+ // Make sure we can create a tuple of rvalue references
+ {
+ RefOnly e{};
+ hana::tuple<RefOnly&&> xs{std::move(e)};
+ hana::tuple<RefOnly&&, RefOnly&&> ys{std::move(e), std::move(e)};
+ (void)xs; (void)ys;
+
+ hana::tuple<RefOnly&&> xs2 = {std::move(e)};
+ hana::tuple<RefOnly&&, RefOnly&&> ys2 = {std::move(e), std::move(e)};
+ (void)xs2; (void)ys2;
+ }
+
+ // Make sure we can create a tuple of non-const lvalue references
+ {
+ RefOnly e{};
+ hana::tuple<RefOnly&> xs{e};
+ hana::tuple<RefOnly&, RefOnly&> ys{e, e};
+ (void)xs; (void)ys;
+
+ hana::tuple<RefOnly&> xs2 = {e};
+ hana::tuple<RefOnly&, RefOnly&> ys2 = {e, e};
+ (void)xs2; (void)ys2;
+ }
+
+ // Make sure we can create a tuple of const lvalue references
+ {
+ RefOnly const e{};
+ hana::tuple<RefOnly const&> xs{e};
+ hana::tuple<RefOnly const&, RefOnly const&> ys{e, e};
+ (void)xs; (void)ys;
+
+ hana::tuple<RefOnly const&> xs2 = {e};
+ hana::tuple<RefOnly const&, RefOnly const&> ys2 = {e, e};
+ (void)xs2; (void)ys2;
+ }
+
+ // Try to construct tuples with mixed references and non-reference members.
+ {
+ RefOnly r{};
+ Empty e{};
+
+ {
+ hana::tuple<RefOnly const&, Empty> xs{r, e};
+ hana::tuple<RefOnly const&, Empty> ys = {r, e};
+ (void)xs; (void)ys;
+ }
+ {
+ hana::tuple<RefOnly&, Empty> xs{r, e};
+ hana::tuple<RefOnly&, Empty> ys = {r, e};
+ (void)xs; (void)ys;
+ }
+ {
+ hana::tuple<RefOnly&&, Empty> xs{std::move(r), e};
+ hana::tuple<RefOnly&&, Empty> ys = {std::move(r), e};
+ (void)xs; (void)ys;
+ }
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/issue_90.cpp b/src/boost/libs/hana/test/tuple/issue_90.cpp
new file mode 100644
index 00000000..ab78440d
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/issue_90.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/at.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <typename T>
+T const& cref(T& t) { return t; }
+
+// a non-movable, non-copyable type
+struct RefOnly {
+ RefOnly() = default;
+ RefOnly(RefOnly const&) = delete;
+ RefOnly(RefOnly&&) = delete;
+};
+
+template <int i>
+struct RefOnly_i : hana::int_<i> {
+ RefOnly_i() = default;
+ RefOnly_i(RefOnly_i const&) = delete;
+ RefOnly_i(RefOnly_i&&) = delete;
+};
+
+int main() {
+ hana::tuple<RefOnly> t;
+
+ // Make sure that we return the proper reference types from `at`.
+ {
+ RefOnly&& r1 = hana::at_c<0>(std::move(t));
+ RefOnly& r2 = hana::at_c<0>(t);
+ RefOnly const& r3 = hana::at_c<0>(cref(t));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ // Make sure we return the proper reference types from `front`.
+ {
+ RefOnly&& r1 = hana::front(std::move(t));
+ RefOnly& r2 = hana::front(t);
+ RefOnly const& r3 = hana::front(cref(t));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ // Make sure we return the proper reference types from `back`.
+ {
+ RefOnly&& r1 = hana::back(std::move(t));
+ RefOnly& r2 = hana::back(t);
+ RefOnly const& r3 = hana::back(cref(t));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ // Make sure we return the proper reference types from `at_key`.
+ {
+ hana::tuple<RefOnly_i<3>> t{};
+ RefOnly_i<3>& r1 = hana::at_key(t, RefOnly_i<3>{});
+ RefOnly_i<3> const& r2 = hana::at_key(cref(t), RefOnly_i<3>{});
+ RefOnly_i<3>&& r3 = hana::at_key(std::move(t), RefOnly_i<3>{});
+
+ (void)r1; (void)r2; (void)r3;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/laws.cpp b/src/boost/libs/hana/test/tuple/laws.cpp
new file mode 100644
index 00000000..fc79fe9a
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/laws.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/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/iterable.hpp>
+#include <laws/orderable.hpp>
+#include <laws/sequence.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+using hana::test::ct_ord;
+
+
+int main() {
+ auto eq_tuples = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(ct_eq<0>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})
+ );
+
+ auto ord_tuples = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(ct_ord<0>{})
+ , hana::make_tuple(ct_ord<0>{}, ct_ord<1>{})
+ , hana::make_tuple(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{})
+ , hana::make_tuple(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, ct_ord<3>{})
+ , hana::make_tuple(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, ct_ord<3>{}, ct_ord<4>{})
+ );
+
+ hana::test::TestComparable<hana::tuple_tag>{eq_tuples};
+ hana::test::TestOrderable<hana::tuple_tag>{ord_tuples};
+ hana::test::TestFoldable<hana::tuple_tag>{eq_tuples};
+ hana::test::TestIterable<hana::tuple_tag>{eq_tuples};
+ hana::test::TestSequence<hana::tuple_tag>{};
+}
diff --git a/src/boost/libs/hana/test/tuple/laws.functor.cpp b/src/boost/libs/hana/test/tuple/laws.functor.cpp
new file mode 100644
index 00000000..7a72d2d5
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/laws.functor.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/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/applicative.hpp>
+#include <laws/base.hpp>
+#include <laws/functor.hpp>
+#include <laws/monad.hpp>
+#include <laws/monad_plus.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto eq_tuples = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(ct_eq<0>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})
+ );
+
+ auto eq_values = hana::make_tuple(
+ ct_eq<0>{},
+ ct_eq<2>{},
+ ct_eq<4>{}
+ );
+
+ auto predicates = hana::make_tuple(
+ hana::equal.to(ct_eq<0>{}),
+ hana::equal.to(ct_eq<2>{}),
+ hana::equal.to(ct_eq<4>{}),
+ hana::always(hana::true_c),
+ hana::always(hana::false_c)
+ );
+
+ auto nested_eqs = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(
+ hana::make_tuple(ct_eq<0>{})
+ )
+ , hana::make_tuple(
+ hana::make_tuple(ct_eq<0>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{})
+ )
+ , hana::make_tuple(
+ hana::make_tuple(ct_eq<0>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_tuple(ct_eq<3>{}, ct_eq<4>{})
+ )
+ );
+
+ hana::test::TestFunctor<hana::tuple_tag>{eq_tuples, eq_values};
+ hana::test::TestApplicative<hana::tuple_tag>{eq_tuples};
+ hana::test::TestMonad<hana::tuple_tag>{eq_tuples, nested_eqs};
+ hana::test::TestMonadPlus<hana::tuple_tag>{eq_tuples, predicates, eq_values};
+}
diff --git a/src/boost/libs/hana/test/tuple/laws.searchable.cpp b/src/boost/libs/hana/test/tuple/laws.searchable.cpp
new file mode 100644
index 00000000..6aa09689
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/laws.searchable.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/bool.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/searchable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto eq_tuples = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(ct_eq<0>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ );
+ hana::test::TestSearchable<hana::tuple_tag>{
+ eq_tuples,
+ hana::make_tuple(ct_eq<3>{}, ct_eq<5>{})
+ };
+
+ auto bool_tuples = hana::make_tuple(
+ hana::make_tuple(hana::true_c)
+ , hana::make_tuple(hana::false_c)
+ , hana::make_tuple(hana::true_c, hana::true_c)
+ , hana::make_tuple(hana::true_c, hana::false_c)
+ , hana::make_tuple(hana::false_c, hana::true_c)
+ , hana::make_tuple(hana::false_c, hana::false_c)
+ );
+ hana::test::TestSearchable<hana::tuple_tag>{
+ bool_tuples,
+ hana::make_tuple(hana::true_c, hana::false_c)
+ };
+}
diff --git a/src/boost/libs/hana/test/tuple/move_only.cpp b/src/boost/libs/hana/test/tuple/move_only.cpp
new file mode 100644
index 00000000..3f78316c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/move_only.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/at.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+// This test checks for move-only friendliness and reference semantics.
+
+struct MoveOnly {
+ MoveOnly() = default;
+ MoveOnly(MoveOnly&&) = default;
+ MoveOnly& operator=(MoveOnly&&) = default;
+
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+};
+
+int main() {
+ {
+ auto xs = hana::make_tuple(MoveOnly{});
+ auto by_val = [](auto) { };
+
+ by_val(std::move(xs));
+ by_val(hana::front(std::move(xs)));
+ by_val(hana::at_c<0>(std::move(xs)));
+ by_val(hana::back(std::move(xs)));
+ }
+
+ {
+ auto const& xs = hana::make_tuple(MoveOnly{});
+ auto by_const_ref = [](auto const&) { };
+
+ by_const_ref(xs);
+ by_const_ref(hana::front(xs));
+ by_const_ref(hana::at_c<0>(xs));
+ by_const_ref(hana::back(xs));
+ }
+
+ {
+ auto xs = hana::make_tuple(MoveOnly{});
+ auto by_ref = [](auto&) { };
+
+ by_ref(xs);
+ by_ref(hana::front(xs));
+ by_ref(hana::at_c<0>(xs));
+ by_ref(hana::back(xs));
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/pair_interop.cpp b/src/boost/libs/hana/test/tuple/pair_interop.cpp
new file mode 100644
index 00000000..1e079f43
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/pair_interop.cpp
@@ -0,0 +1,75 @@
+// Copyright Louis Dionne 2013-2016
+// Distributed under the 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/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+// This test makes sure that tuples containing pairs behave properly. It is
+// useful to test this specific case because tuple and pair (may) share a lot
+// of implementation details (for EBO), and that can easily lead to subtle bugs.
+// For example, if both pair and tuple inherit from similar base classes for
+// EBO, accessing a tuple of pairs or a pair of tuples (which requires some
+// base class casting magic) can lead to ambiguous overloads.
+
+int main() {
+ struct empty1 { };
+ struct empty2 { };
+
+ {
+ hana::tuple<hana::pair<empty1, empty2>> t{};
+ hana::first(hana::at_c<0>(t));
+ hana::second(hana::at_c<0>(t));
+ }
+ {
+ hana::tuple<hana::pair<int, empty2>> t{};
+ hana::first(hana::at_c<0>(t));
+ hana::second(hana::at_c<0>(t));
+ }
+ {
+ hana::tuple<hana::pair<int, int>> t{};
+ hana::first(hana::at_c<0>(t));
+ hana::second(hana::at_c<0>(t));
+ }
+ {
+ hana::tuple<hana::pair<empty1, int>> t{};
+ hana::first(hana::at_c<0>(t));
+ hana::second(hana::at_c<0>(t));
+ }
+
+ {
+ hana::pair<hana::tuple<>, hana::tuple<>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<int>, hana::tuple<int>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<>, hana::tuple<int>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<empty1>, hana::tuple<empty2>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<empty1, empty2>, hana::tuple<empty2>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<empty1, empty2>, hana::tuple<empty1, empty2>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/smart_ptr.cpp b/src/boost/libs/hana/test/tuple/smart_ptr.cpp
new file mode 100644
index 00000000..aea7dc85
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/smart_ptr.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/tuple.hpp>
+
+#include <memory>
+namespace hana = boost::hana;
+
+
+// Tuples of smart pointers; based on LLVM bug #18350
+int main() {
+ {
+ hana::tuple<std::unique_ptr<char>> up;
+ hana::tuple<std::shared_ptr<char>> sp;
+ hana::tuple<std::weak_ptr <char>> wp;
+ }
+ {
+ hana::tuple<std::unique_ptr<char[]>> up;
+ hana::tuple<std::shared_ptr<char[]>> sp;
+ hana::tuple<std::weak_ptr <char[]>> wp;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/special.drop_front_exactly.cpp b/src/boost/libs/hana/test/tuple/special.drop_front_exactly.cpp
new file mode 100644
index 00000000..1092c521
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.drop_front_exactly.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/assert.hpp>
+#include <boost/hana/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct x0;
+struct x1;
+struct x2;
+
+int main() {
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_t<x0>),
+ hana::tuple_t<>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_t<x0, x1>),
+ hana::tuple_t<x1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_t<x0, x1, x2>),
+ hana::tuple_t<x1, x2>
+ ));
+
+ // tuple_c
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_c<int, 0>),
+ hana::tuple_c<int>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_c<int, 0, 1>),
+ hana::tuple_c<int, 1>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_c<int, 0, 1, 2>),
+ hana::tuple_c<int, 1, 2>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.empty.cpp b/src/boost/libs/hana/test/tuple/special.empty.cpp
new file mode 100644
index 00000000..2cbb36d3
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.empty.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/empty.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::empty<hana::tuple_tag>(),
+ hana::tuple_c<int>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::empty<hana::tuple_tag>(),
+ hana::tuple_c<long>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::empty<hana::tuple_tag>(),
+ hana::tuple_c<void>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.equal.cpp b/src/boost/libs/hana/test/tuple/special.equal.cpp
new file mode 100644
index 00000000..27694f2b
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.equal.cpp
@@ -0,0 +1,76 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct x0;
+struct x1;
+struct x2;
+
+int main() {
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_t<>,
+ hana::tuple_t<>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_t<x0>,
+ hana::tuple_t<>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_t<>,
+ hana::tuple_t<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_t<x0>,
+ hana::tuple_t<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_t<x0, x1>,
+ hana::tuple_t<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_t<x0>,
+ hana::tuple_t<x0, x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_t<x0, x1>,
+ hana::tuple_t<x0, x1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_t<x0, x1, x2>,
+ hana::tuple_t<x0, x1, x2>
+ ));
+
+ // tuple_c
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_c<int>,
+ hana::tuple_c<int>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_c<int, 0>,
+ hana::tuple_c<int>
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_c<int, 0>,
+ hana::tuple_c<int, 0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_c<int, 0, 1>,
+ hana::tuple_c<int, 0>
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_c<int, 0, 1>,
+ hana::tuple_c<int, 0, 1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_c<int, 0, 1, 2>,
+ hana::tuple_c<int, 0, 1, 2>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.fill.cpp b/src/boost/libs/hana/test/tuple/special.fill.cpp
new file mode 100644
index 00000000..d764083f
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.fill.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/fill.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct x1;
+struct x2;
+struct x3;
+struct z;
+
+int main() {
+ // fill a tuple_t with a hana::type
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fill(hana::tuple_t<>, hana::type_c<z>),
+ hana::tuple_t<>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fill(hana::tuple_t<x1>, hana::type_c<z>),
+ hana::tuple_t<z>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fill(hana::tuple_t<x1, x2>, hana::type_c<z>),
+ hana::tuple_t<z, z>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fill(hana::tuple_t<x1, x2, x3>, hana::type_c<z>),
+ hana::tuple_t<z, z, z>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.fold_left.cpp b/src/boost/libs/hana/test/tuple/special.fold_left.cpp
new file mode 100644
index 00000000..cf121ebb
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.fold_left.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/equal.hpp>
+#include <boost/hana/fold_left.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct F { struct type; };
+
+struct x0;
+struct x1;
+struct x2;
+struct x3;
+
+int main() {
+ // tuple_t and initial state
+ {
+ auto f = hana::metafunction<F>;
+ auto s = hana::type_c<struct initial_state>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<>, s, f),
+ s
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0>, s, f),
+ f(s, hana::type_c<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1>, s, f),
+ f(f(s, hana::type_c<x0>), hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1, x2>, s, f),
+ f(f(f(s, hana::type_c<x0>), hana::type_c<x1>), hana::type_c<x2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1, x2, x3>, s, f),
+ f(f(f(f(s, hana::type_c<x0>), hana::type_c<x1>), hana::type_c<x2>), hana::type_c<x3>)
+ ));
+ }
+
+ // tuple_t and no initial state
+ {
+ auto f = hana::metafunction<F>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0>, f),
+ hana::type_c<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1, x2>, f),
+ f(f(hana::type_c<x0>, hana::type_c<x1>), hana::type_c<x2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1, x2, x3>, f),
+ f(f(f(hana::type_c<x0>, hana::type_c<x1>), hana::type_c<x2>), hana::type_c<x3>)
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/special.fold_right.cpp b/src/boost/libs/hana/test/tuple/special.fold_right.cpp
new file mode 100644
index 00000000..a78d40ed
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.fold_right.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/equal.hpp>
+#include <boost/hana/fold_right.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct F { struct type; };
+
+struct x0;
+struct x1;
+struct x2;
+struct x3;
+
+int main() {
+ // tuple_t and an initial state
+ {
+ auto f = hana::metafunction<F>;
+ auto s = hana::type_c<struct initial_state>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<>, s, f),
+ s
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0>, s, f),
+ f(hana::type_c<x0>, s)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1>, s, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, s))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1, x2>, s, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, f(hana::type_c<x2>, s)))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1, x2, x3>, s, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, f(hana::type_c<x2>, f(hana::type_c<x3>, s))))
+ ));
+ }
+
+ // tuple_t and no initial state
+ {
+ auto f = hana::metafunction<F>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0>, f),
+ hana::type_c<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1, x2>, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, hana::type_c<x2>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1, x2, x3>, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, f(hana::type_c<x2>, hana::type_c<x3>)))
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/special.front.cpp b/src/boost/libs/hana/test/tuple/special.front.cpp
new file mode 100644
index 00000000..9dc712d5
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.front.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/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct x0;
+struct x1;
+struct x2;
+
+int main() {
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_t<x0>),
+ hana::type_c<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_t<x0, x1>),
+ hana::type_c<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_t<x0, x1, x2>),
+ hana::type_c<x0>
+ ));
+
+ // tuple_c
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_c<int, 0>),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_c<int, 0, 1>),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_c<int, 0, 1, 2>),
+ hana::int_c<0>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.is_empty.cpp b/src/boost/libs/hana/test/tuple/special.is_empty.cpp
new file mode 100644
index 00000000..3bf0cf78
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.is_empty.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/is_empty.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct x0;
+struct x1;
+struct x2;
+
+int main() {
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(hana::tuple_t<>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_t<x0>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_t<x0, x1>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_t<x0, x1, x2>)));
+
+ // tuple_c
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(hana::tuple_c<int>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_c<int, 0>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_c<int, 0, 1>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_c<int, 0, 1, 2>)));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.prepend.cpp b/src/boost/libs/hana/test/tuple/special.prepend.cpp
new file mode 100644
index 00000000..267f7dd4
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.prepend.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/integral_constant.hpp>
+#include <boost/hana/prepend.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::prepend(hana::tuple_c<long>, hana::long_c<0>),
+ hana::tuple_c<long, 0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::prepend(hana::tuple_c<unsigned int, 1>, hana::uint_c<0>),
+ hana::tuple_c<unsigned int, 0, 1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::prepend(hana::tuple_c<long long, 1, 2>, hana::llong_c<0>),
+ hana::tuple_c<long long, 0, 1, 2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::prepend(hana::tuple_c<unsigned long, 1, 2, 3>, hana::ulong_c<0>),
+ hana::tuple_c<unsigned long, 0, 1, 2, 3>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.transform.cpp b/src/boost/libs/hana/test/tuple/special.transform.cpp
new file mode 100644
index 00000000..86d141c6
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.transform.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/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct F { struct type; };
+
+struct x1;
+struct x2;
+struct x3;
+struct x4;
+
+int main() {
+ // transform with tuple_t and a metafunction
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<>, hana::metafunction<F>),
+ hana::tuple_t<>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1>, hana::metafunction<F>),
+ hana::tuple_t<F<x1>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1, x2>, hana::metafunction<F>),
+ hana::tuple_t<F<x1>::type, F<x2>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1, x2, x3>, hana::metafunction<F>),
+ hana::tuple_t<F<x1>::type, F<x2>::type, F<x3>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1, x2, x3, x4>, hana::metafunction<F>),
+ hana::tuple_t<F<x1>::type, F<x2>::type, F<x3>::type, F<x4>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1, x2, x3, x4>, hana::template_<F>),
+ hana::tuple_t<F<x1>, F<x2>, F<x3>, F<x4>>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/to.cpp b/src/boost/libs/hana/test/tuple/to.cpp
new file mode 100644
index 00000000..d0862c3c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/to.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/core/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // make sure to_tuple == to<tuple_tag>
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::tuple_tag>(hana::tuple_t<int, char, void, int(float)>),
+ hana::to_tuple(hana::tuple_t<int, char, void, int(float)>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/unpack.cpp b/src/boost/libs/hana/test/tuple/unpack.cpp
new file mode 100644
index 00000000..3838ea29
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/unpack.cpp
@@ -0,0 +1,89 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/tuple.hpp>
+#include <boost/hana/type.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+template <typename ...>
+struct F { struct type; };
+
+struct x0;
+struct x1;
+struct x2;
+struct x3;
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ // tuple
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_tuple(), f),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_tuple(ct_eq<0>{}), f),
+ f(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}), f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), f),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<>, f),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0>, f),
+ f(hana::type_c<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1, x2>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>, hana::type_c<x2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1, x2, x3>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>, hana::type_c<x2>, hana::type_c<x3>)
+ ));
+
+ // tuple_t with metafunction
+ auto g = hana::metafunction<F>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<>, g),
+ g()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0>, g),
+ g(hana::type_c<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1>, g),
+ g(hana::type_c<x0>, hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1, x2>, g),
+ g(hana::type_c<x0>, hana::type_c<x1>, hana::type_c<x2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1, x2, x3>, g),
+ g(hana::type_c<x0>, hana::type_c<x1>, hana::type_c<x2>, hana::type_c<x3>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/usability_of_types.cpp b/src/boost/libs/hana/test/tuple/usability_of_types.cpp
new file mode 100644
index 00000000..261b47ad
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/usability_of_types.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/at.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// The fact that a reference to a `type<...>` is returned from `front(types)`
+// and friends used to break the `decltype(front(types))::type` pattern,
+// because we would be trying to fetch `::type` inside a reference. To work
+// around this, a unary `operator+` turning a lvalue `type` into a rvalue
+// `type` was added.
+
+struct T; struct U; struct V;
+
+int main() {
+ auto check = [](auto types) {
+ static_assert(std::is_same<
+ typename decltype(+hana::front(types))::type, T
+ >{}, "");
+
+ static_assert(std::is_same<
+ typename decltype(+hana::at(types, hana::size_c<1>))::type, U
+ >{}, "");
+
+ static_assert(std::is_same<
+ typename decltype(+hana::back(types))::type, V
+ >{}, "");
+ };
+
+ check(hana::make_tuple(hana::type_c<T>, hana::type_c<U>, hana::type_c<V>));
+ check(hana::tuple_t<T, U, V>);
+}
diff --git a/src/boost/libs/hana/test/type/adl.cpp b/src/boost/libs/hana/test/type/adl.cpp
new file mode 100644
index 00000000..35a75c20
--- /dev/null
+++ b/src/boost/libs/hana/test/type/adl.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/type.hpp>
+namespace hana = boost::hana;
+
+
+template <bool b = false>
+struct invalid { static_assert(b, "invalid must not be instantiated"); };
+
+template <typename T> void adl(T) { }
+template <typename T> void adl_pattern(hana::basic_type<T>) { }
+
+
+int main() {
+ // ADL kicks in but `invalid<>` must not instantiated
+ adl(hana::type_c<invalid<>>);
+ adl_pattern(hana::type_c<invalid<>>);
+
+ // ADL instantiates the types recursively, make sure that works too
+ adl(hana::typeid_(hana::type_c<invalid<>>));
+ adl_pattern(hana::typeid_(hana::type_c<invalid<>>));
+}
diff --git a/src/boost/libs/hana/test/type/alignof.cpp b/src/boost/libs/hana/test/type/alignof.cpp
new file mode 100644
index 00000000..6b8203b2
--- /dev/null
+++ b/src/boost/libs/hana/test/type/alignof.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/integral_constant.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct T { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::alignof_(T{}),
+ hana::size_c<alignof(T)>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::alignof_(hana::type_c<T>),
+ hana::size_c<alignof(T)>
+ ));
+
+ // make sure we don't read from non-constexpr variables
+ {
+ auto t = hana::type_c<T>;
+ auto x = 1;
+ constexpr auto r1 = hana::alignof_(t); (void)r1;
+ constexpr auto r2 = hana::alignof_(x); (void)r2;
+ }
+}
diff --git a/src/boost/libs/hana/test/type/decltype.cpp b/src/boost/libs/hana/test/type/decltype.cpp
new file mode 100644
index 00000000..b956c324
--- /dev/null
+++ b/src/boost/libs/hana/test/type/decltype.cpp
@@ -0,0 +1,182 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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;
+
+
+using Function = void();
+void function() { }
+
+int main() {
+ {
+ struct T { };
+ T t;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(T{}),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(t),
+ hana::type_c<T>
+ ));
+ }
+
+ // [cv-qualified] reference types
+ {
+ struct T { };
+ T t;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(static_cast<T&>(t)),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(static_cast<T const&>(t)),
+ hana::type_c<T const>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(static_cast<T volatile&>(t)),
+ hana::type_c<T volatile>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(static_cast<T const volatile&>(t)),
+ hana::type_c<T const volatile>
+ ));
+ }
+
+ // [cv-qualified] rvalue reference types
+ {
+ struct T { };
+ T t;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(static_cast<T&&>(t)),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(static_cast<T const &&>(t)),
+ hana::type_c<T const>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(static_cast<T volatile&&>(t)),
+ hana::type_c<T volatile>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(static_cast<T const volatile&&>(t)),
+ hana::type_c<T const volatile>
+ ));
+ }
+
+ // decltype_(type_c<T>) is the identity function
+ {
+ struct T;
+ auto const type_const = hana::type_c<T>;
+ auto const& type_const_ref = hana::type_c<T>;
+ auto& type_ref = hana::type_c<T>;
+ auto&& type_ref_ref = static_cast<decltype(type_ref)&&>(type_ref);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(hana::type_c<T>),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(type_const),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(type_const_ref),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(type_ref),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(type_ref_ref),
+ hana::type_c<T>
+ ));
+ }
+
+ // make sure we don't read from non-constexpr variables
+ {
+ struct T;
+ auto t = hana::type_c<T>;
+ auto x = 1;
+ constexpr auto r1 = hana::decltype_(t); (void)r1;
+ constexpr auto r2 = hana::decltype_(x); (void)r2;
+ }
+
+ // decltype_ with builtin arrays, function pointers and other weirdos
+ {
+ struct T { };
+ using A = T[3];
+ A a;
+ A& a_ref = a;
+ A const& a_const_ref = a;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(a),
+ hana::type_c<A>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(a_ref),
+ hana::type_c<A>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(a_const_ref),
+ hana::type_c<A const>
+ ));
+ }
+ {
+ using Fptr = int(*)();
+ Fptr f;
+ Fptr& f_ref = f;
+ Fptr const& f_const_ref = f;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(f),
+ hana::type_c<Fptr>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(f_ref),
+ hana::type_c<Fptr>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(f_const_ref),
+ hana::type_c<Fptr const>
+ ));
+ }
+ {
+ Function& function_ref = function;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(function),
+ hana::type_c<Function>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::decltype_(function_ref),
+ hana::type_c<Function>
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/type/equal.cpp b/src/boost/libs/hana/test/type/equal.cpp
new file mode 100644
index 00000000..4d5a18a8
--- /dev/null
+++ b/src/boost/libs/hana/test/type/equal.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/not.hpp>
+#include <boost/hana/not_equal.hpp> // for operator !=
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct T;
+struct U;
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::type_c<T>, hana::type_c<T>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(hana::type_c<T>, hana::type_c<U>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(hana::type_c<void>, hana::type_c<U>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(hana::type_c<T>, hana::type_c<void>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::type_c<void>, hana::type_c<void>));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::type_c<T&>, hana::type_c<T&>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(hana::type_c<T&>, hana::type_c<T&&>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(hana::type_c<T const>, hana::type_c<T>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::type_c<T const>, hana::type_c<T const>));
+
+ // make sure we don't read from a non-constexpr variable in hana::equal
+ auto t = hana::type_c<T>;
+ static_assert(hana::equal(t, hana::type_c<T>), "");
+
+ // check operators
+ BOOST_HANA_CONSTANT_CHECK(hana::type_c<T> == hana::type_c<T>);
+ BOOST_HANA_CONSTANT_CHECK(hana::type_c<T> != hana::type_c<U>);
+}
diff --git a/src/boost/libs/hana/test/type/hash.cpp b/src/boost/libs/hana/test/type/hash.cpp
new file mode 100644
index 00000000..88bcf335
--- /dev/null
+++ b/src/boost/libs/hana/test/type/hash.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/hash.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct T;
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::hash(hana::type_c<T>),
+ hana::type_c<T>
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::hash(hana::basic_type<T>{}),
+ hana::type_c<T>
+));
+
+int main() { }
diff --git a/src/boost/libs/hana/test/type/inherit_basic_type.cpp b/src/boost/libs/hana/test/type/inherit_basic_type.cpp
new file mode 100644
index 00000000..e42e8280
--- /dev/null
+++ b/src/boost/libs/hana/test/type/inherit_basic_type.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/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// `hana::type<T>` should inherit `hana::basic_type<T>`.
+
+struct T;
+static_assert(std::is_base_of<hana::basic_type<T>, decltype(hana::type_c<T>)>{}, "");
+static_assert(std::is_base_of<hana::basic_type<T>, hana::type<T>>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/type/integral.cpp b/src/boost/libs/hana/test/type/integral.cpp
new file mode 100644
index 00000000..e3159bbc
--- /dev/null
+++ b/src/boost/libs/hana/test/type/integral.cpp
@@ -0,0 +1,83 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/metafunction.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct x1; struct x2; struct x3;
+struct y1 { }; struct y2 { }; struct y3 { };
+
+template <typename ...> struct mf { struct type { }; };
+struct mfc { template <typename ...> struct apply { struct type { }; }; };
+template <typename ...> struct tpl { };
+
+// make sure `integral(f)(...)` returns the right type
+static_assert(std::is_same<
+ decltype(hana::integral(hana::metafunction<mf>)()),
+ mf<>::type
+>{}, "");
+static_assert(std::is_same<
+ decltype(hana::integral(hana::metafunction<mf>)(hana::type_c<x1>)),
+ mf<x1>::type
+>{}, "");
+static_assert(std::is_same<
+ decltype(hana::integral(hana::metafunction<mf>)(hana::type_c<x1>, hana::type_c<x2>)),
+ mf<x1, x2>::type
+>{}, "");
+
+static_assert(std::is_same<
+ decltype(hana::integral(hana::template_<tpl>)()),
+ tpl<>
+>{}, "");
+static_assert(std::is_same<
+ decltype(hana::integral(hana::template_<tpl>)(hana::type_c<x1>)),
+ tpl<x1>
+>{}, "");
+static_assert(std::is_same<
+ decltype(hana::integral(hana::template_<tpl>)(hana::type_c<x1>, hana::type_c<x2>)),
+ tpl<x1, x2>
+>{}, "");
+
+static_assert(std::is_same<
+ decltype(hana::integral(hana::metafunction_class<mfc>)()),
+ mfc::apply<>::type
+>{}, "");
+static_assert(std::is_same<
+ decltype(hana::integral(hana::metafunction_class<mfc>)(hana::type_c<x1>)),
+ mfc::apply<x1>::type
+>{}, "");
+static_assert(std::is_same<
+ decltype(hana::integral(hana::metafunction_class<mfc>)(hana::type_c<x1>, hana::type_c<x2>)),
+ mfc::apply<x1, x2>::type
+>{}, "");
+
+// Make sure integral is SFINAE-friendly
+struct invalid_hana_metafunction {
+ template <typename ...> struct apply { /* missing type alias */ };
+};
+auto invalid_integral = hana::integral(invalid_hana_metafunction{});
+BOOST_HANA_CONSTANT_CHECK(hana::not_(
+ hana::is_valid(invalid_integral)(hana::type_c<void>, hana::type_c<void>)
+));
+
+
+int main() {
+ // Make sure we can perform the call; we already made sure the return type was correct
+ constexpr auto a = hana::integral(hana::metafunction<mf>)(); (void)a;
+ constexpr auto b = hana::integral(hana::metafunction<mf>)(hana::type_c<x1>); (void)b;
+ constexpr auto c = hana::integral(hana::metafunction<mf>)(hana::type_c<x1>, hana::type_c<x2>); (void)c;
+ constexpr auto d = hana::integral(hana::metafunction<mf>)(hana::type_c<x1>, hana::type_c<x2>, hana::type_c<x3>); (void)d;
+
+ // Make sure we don't read from a non-constexpr variable
+ auto t = hana::type_c<x1>;
+ constexpr auto r = hana::integral(hana::metafunction<mf>)(t);
+ (void)r;
+}
diff --git a/src/boost/libs/hana/test/type/is_valid.cpp b/src/boost/libs/hana/test/type/is_valid.cpp
new file mode 100644
index 00000000..2f2abcd3
--- /dev/null
+++ b/src/boost/libs/hana/test/type/is_valid.cpp
@@ -0,0 +1,206 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/traits.hpp>
+#include <boost/hana/type.hpp>
+
+#include <support/tracked.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct undefined { };
+
+struct static_nested_member { static const int member = 1; };
+struct static_nested_member_array { static int member[3]; };
+struct nested_template_struct { template <typename ...> struct nested; };
+struct nested_template_alias { template <typename ...> using nested = void; };
+
+int main() {
+ // Check for a non-static member
+ {
+ struct yes { int member; };
+ struct no { };
+
+ auto from_type = hana::is_valid([](auto t) -> decltype(
+ hana::traits::declval(t).member
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_type(hana::type_c<yes>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_type(hana::type_c<no>)));
+
+ auto from_object = hana::is_valid([](auto&& t) -> decltype(
+ t.member
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_object(yes{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_object(no{})));
+ }
+
+ // Check for a non-static member function
+ {
+ struct yes { int member() const; };
+ struct no { };
+
+ auto from_type = hana::is_valid([](auto t) -> decltype(
+ hana::traits::declval(t).member()
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_type(hana::type_c<yes>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_type(hana::type_c<no>)));
+
+ auto from_object = hana::is_valid([](auto&& t) -> decltype(
+ t.member()
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_object(yes{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_object(no{})));
+ }
+
+ // Check for a static member
+ {
+ using yes = static_nested_member;
+ struct no { };
+
+ auto from_type = hana::is_valid([](auto t) -> decltype(
+ decltype(t)::type::member
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_type(hana::type_c<yes>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_type(hana::type_c<no>)));
+
+ auto from_object = hana::is_valid([](auto&& t) -> decltype(
+ std::remove_reference_t<decltype(t)>::member
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_object(yes{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_object(no{})));
+ }
+
+ // Check for a nested type
+ {
+ struct yes { using nested = void; };
+ struct no { };
+
+ auto from_type = hana::is_valid([](auto t) -> decltype(hana::type_c<
+ typename decltype(t)::type::nested
+ >) { });
+ BOOST_HANA_CONSTANT_CHECK(from_type(hana::type_c<yes>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_type(hana::type_c<no>)));
+
+ auto from_object = hana::is_valid([](auto&& t) -> decltype(hana::type_c<
+ typename std::remove_reference_t<decltype(t)>::nested
+ >) { });
+ BOOST_HANA_CONSTANT_CHECK(from_object(yes{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_object(no{})));
+ }
+
+ // Check for a nested template
+ {
+ { // template struct
+ using yes = nested_template_struct;
+ struct no { };
+
+ auto from_type = hana::is_valid([](auto t) -> decltype(hana::template_<
+ decltype(t)::type::template nested
+ >) { });
+ BOOST_HANA_CONSTANT_CHECK(from_type(hana::type_c<yes>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_type(hana::type_c<no>)));
+
+ auto from_object = hana::is_valid([](auto&& t) -> decltype(hana::template_<
+ std::remove_reference_t<decltype(t)>::template nested
+ >) { });
+ BOOST_HANA_CONSTANT_CHECK(from_object(yes{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_object(no{})));
+ }
+
+ { // template alias
+ using yes = nested_template_alias;
+ struct no { };
+
+ auto from_type = hana::is_valid([](auto t) -> decltype(hana::template_<
+ decltype(t)::type::template nested
+ >) { });
+ BOOST_HANA_CONSTANT_CHECK(from_type(hana::type_c<yes>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_type(hana::type_c<no>)));
+
+ auto from_object = hana::is_valid([](auto&& t) -> decltype(hana::template_<
+ std::remove_reference_t<decltype(t)>::template nested
+ >) { });
+ BOOST_HANA_CONSTANT_CHECK(from_object(yes{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_object(no{})));
+ }
+ }
+
+ // Make sure that checking for a nested static or non-static member
+ // works even when the type of that member is an array type or
+ // something that can't be returned from a function.
+ {
+ { // non-static member
+ struct yes { int member[3]; };
+ struct no { };
+
+ auto from_type = hana::is_valid([](auto t) -> decltype(
+ (void)hana::traits::declval(t).member
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_type(hana::type_c<yes>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_type(hana::type_c<no>)));
+
+ auto from_object = hana::is_valid([](auto&& t) -> decltype(
+ (void)t.member
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_object(yes{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_object(no{})));
+ }
+
+ { // static member
+ using yes = static_nested_member_array;
+ struct no { };
+
+ auto from_type = hana::is_valid([](auto t) -> decltype(
+ (void)decltype(t)::type::member
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_type(hana::type_c<yes>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_type(hana::type_c<no>)));
+
+ auto from_object = hana::is_valid([](auto&& t) -> decltype(
+ (void)std::remove_reference_t<decltype(t)>::member
+ ) { });
+ BOOST_HANA_CONSTANT_CHECK(from_object(yes{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(from_object(no{})));
+ }
+ }
+
+ // Make sure the result of a `is_valid` function is constexpr
+ // even when called on non-constexpr arguments.
+ {
+ int i;
+ auto f = hana::is_valid([](auto) { });
+ constexpr auto result = f(i);
+ (void)result;
+ }
+
+ // Make sure `is_valid` works with non-PODs.
+ {
+ hana::is_valid(undefined{})(Tracked{1});
+ hana::is_valid([t = Tracked{1}](auto) { return 1; })(Tracked{1});
+ }
+
+ // Check `is_valid` with a nullary function.
+ {
+ auto f = [](auto ...x) { (void)sizeof...(x); /* -Wunused-param */ };
+ auto g = [](auto ...x) -> char(*)[sizeof...(x)] { };
+ BOOST_HANA_CONSTANT_CHECK(hana::is_valid(f)());
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_valid(g)()));
+ }
+
+ // Call `is_valid` in the non-curried form.
+ {
+ struct yes { int member; };
+ struct no { };
+
+ auto f = [](auto&& t) -> decltype(t.member) { };
+
+ BOOST_HANA_CONSTANT_CHECK(hana::is_valid(f, yes{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_valid(f, no{})));
+ }
+}
diff --git a/src/boost/libs/hana/test/type/laws.cpp b/src/boost/libs/hana/test/type/laws.cpp
new file mode 100644
index 00000000..622840f9
--- /dev/null
+++ b/src/boost/libs/hana/test/type/laws.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/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <laws/comparable.hpp>
+#include <laws/hashable.hpp>
+namespace hana = boost::hana;
+
+
+struct T;
+
+int main() {
+ auto types = hana::make_tuple(
+ hana::type_c<T>,
+ hana::type_c<T*>,
+ hana::type_c<T&>,
+ hana::type_c<T&&>,
+ hana::type_c<T const>,
+ hana::type_c<T volatile>,
+ hana::type_c<T const volatile>
+ );
+
+ hana::test::TestComparable<hana::type_tag>{types};
+ hana::test::TestHashable<hana::type_tag>{types};
+}
diff --git a/src/boost/libs/hana/test/type/make.cpp b/src/boost/libs/hana/test/type/make.cpp
new file mode 100644
index 00000000..68a6a983
--- /dev/null
+++ b/src/boost/libs/hana/test/type/make.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/equal.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct T { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::type_tag>(T{}),
+ hana::decltype_(T{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make<hana::type_tag>(hana::type_c<T>),
+ hana::decltype_(hana::type_c<T>)
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_type(T{}),
+ hana::make<hana::type_tag>(T{})
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::make_type(hana::type_c<T>),
+ hana::make<hana::type_tag>(hana::type_c<T>)
+ ));
+
+ // make sure we don't read from non-constexpr variables
+ {
+ auto t = hana::type_c<T>;
+ auto x = 1;
+ constexpr auto r1 = hana::make<hana::type_tag>(t); (void)r1;
+ constexpr auto r2 = hana::make<hana::type_tag>(x); (void)r2;
+ }
+}
diff --git a/src/boost/libs/hana/test/type/metafunction.cpp b/src/boost/libs/hana/test/type/metafunction.cpp
new file mode 100644
index 00000000..aa52c1f3
--- /dev/null
+++ b/src/boost/libs/hana/test/type/metafunction.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/concept/metafunction.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct x1; struct x2; struct x3;
+struct y1 { }; struct y2 { }; struct y3 { };
+template <typename ...> struct f { struct type; };
+
+template <typename F, typename ...T>
+constexpr auto valid_call(F f, T ...t) -> decltype(((void)f(t...)), true)
+{ return true; }
+constexpr auto valid_call(...)
+{ return false; }
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::metafunction<f>(),
+ hana::type_c<f<>::type>
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::metafunction<f>(hana::type_c<x1>),
+ hana::type_c<f<x1>::type>
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::metafunction<f>(hana::type_c<x1>, hana::type_c<x2>),
+ hana::type_c<f<x1, x2>::type>
+));
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::metafunction<f>(hana::type_c<x1>, hana::type_c<x2>, hana::type_c<x3>),
+ hana::type_c<f<x1, x2, x3>::type>
+));
+
+using F = decltype(hana::metafunction<f>);
+static_assert(std::is_same<F::apply<>, f<>>::value, "");
+static_assert(std::is_same<F::apply<x1>, f<x1>>::value, "");
+static_assert(std::is_same<F::apply<x1, x2>, f<x1, x2>>::value, "");
+static_assert(std::is_same<F::apply<x1, x2, x3>, f<x1, x2, x3>>::value, "");
+
+// Make sure we're SFINAE-friendly
+template <typename ...T> struct no_type { };
+static_assert(!valid_call(hana::metafunction<no_type>), "");
+static_assert(!valid_call(hana::metafunction<no_type>, hana::type_c<x1>), "");
+
+// Make sure we model the Metafunction concept
+static_assert(hana::Metafunction<decltype(hana::metafunction<f>)>::value, "");
+static_assert(hana::Metafunction<decltype(hana::metafunction<f>)&>::value, "");
+
+// Make sure metafunction is SFINAE-friendly
+template <typename T> struct not_a_metafunction { };
+BOOST_HANA_CONSTANT_CHECK(hana::not_(
+ hana::is_valid(hana::metafunction<not_a_metafunction>)(hana::type_c<void>)
+));
+
+
+// Make sure we don't read from a non-constexpr variable
+int main() {
+ auto t = hana::type_c<x1>;
+ constexpr auto r = hana::metafunction<f>(t);
+ (void)r;
+}
diff --git a/src/boost/libs/hana/test/type/metafunction_class.cpp b/src/boost/libs/hana/test/type/metafunction_class.cpp
new file mode 100644
index 00000000..b0123708
--- /dev/null
+++ b/src/boost/libs/hana/test/type/metafunction_class.cpp
@@ -0,0 +1,73 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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/metafunction.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct x1; struct x2; struct x3;
+struct y1 { }; struct y2 { }; struct y3 { };
+struct f { template <typename ...> struct apply { struct type; }; };
+
+template <typename F, typename ...T>
+constexpr auto valid_call(F f, T ...t) -> decltype(((void)f(t...)), true)
+{ return true; }
+constexpr auto valid_call(...)
+{ return false; }
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::metafunction_class<f>(),
+ hana::type_c<f::apply<>::type>
+));
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::metafunction_class<f>(hana::type_c<x1>),
+ hana::type_c<f::apply<x1>::type>
+));
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::metafunction_class<f>(hana::type_c<x1>, hana::type_c<x2>),
+ hana::type_c<f::apply<x1, x2>::type>
+));
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::metafunction_class<f>(hana::type_c<x1>, hana::type_c<x2>, hana::type_c<x3>),
+ hana::type_c<f::apply<x1, x2, x3>::type>
+));
+
+using F = decltype(hana::metafunction_class<f>);
+static_assert(std::is_same<F::apply<>, f::apply<>>{}, "");
+static_assert(std::is_same<F::apply<x1>, f::apply<x1>>{}, "");
+static_assert(std::is_same<F::apply<x1, x2>, f::apply<x1, x2>>{}, "");
+static_assert(std::is_same<F::apply<x1, x2, x3>, f::apply<x1, x2, x3>>{}, "");
+
+// Make sure we're SFINAE-friendly
+struct no_type { template <typename ...> struct apply { }; };
+static_assert(!valid_call(hana::metafunction_class<no_type>), "");
+static_assert(!valid_call(hana::metafunction_class<no_type>, hana::type_c<x1>), "");
+
+// Make sure we model the Metafunction concept
+static_assert(hana::Metafunction<decltype(hana::metafunction_class<f>)>::value, "");
+static_assert(hana::Metafunction<decltype(hana::metafunction_class<f>)&>::value, "");
+
+// Make sure metafunction_class is SFINAE-friendly
+struct not_a_mfc1 { template <typename ...> struct apply { }; };
+struct not_a_mfc2 { };
+BOOST_HANA_CONSTANT_CHECK(hana::not_(
+ hana::is_valid(hana::metafunction_class<not_a_mfc1>)(hana::type_c<void>)
+));
+BOOST_HANA_CONSTANT_CHECK(hana::not_(
+ hana::is_valid(hana::metafunction_class<not_a_mfc2>)(hana::type_c<void>)
+));
+
+
+// Make sure we don't read from a non-constexpr variable
+int main() {
+ auto t = hana::type_c<x1>;
+ constexpr auto r = hana::metafunction_class<f>(t);
+ (void)r;
+}
diff --git a/src/boost/libs/hana/test/type/nested_type.cpp b/src/boost/libs/hana/test/type/nested_type.cpp
new file mode 100644
index 00000000..6e0410df
--- /dev/null
+++ b/src/boost/libs/hana/test/type/nested_type.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/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// Makes sure that `hana::type`s have a nested ::type alias
+
+struct T;
+
+static_assert(std::is_same<decltype(hana::type_c<T>)::type, T>{}, "");
+static_assert(std::is_same<hana::type<T>::type, T>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/type/sizeof.cpp b/src/boost/libs/hana/test/type/sizeof.cpp
new file mode 100644
index 00000000..85110d29
--- /dev/null
+++ b/src/boost/libs/hana/test/type/sizeof.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/integral_constant.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct T { };
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sizeof_(T{}),
+ hana::size_c<sizeof(T)>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::sizeof_(hana::type_c<T>),
+ hana::size_c<sizeof(T)>
+ ));
+
+ // make sure we don't read from non-constexpr variables
+ {
+ auto t = hana::type_c<T>;
+ auto x = 1;
+ constexpr auto r1 = hana::sizeof_(t); (void)r1;
+ constexpr auto r2 = hana::sizeof_(x); (void)r2;
+ }
+}
diff --git a/src/boost/libs/hana/test/type/template.cpp b/src/boost/libs/hana/test/type/template.cpp
new file mode 100644
index 00000000..6b35d35e
--- /dev/null
+++ b/src/boost/libs/hana/test/type/template.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/concept/metafunction.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct x1; struct x2; struct x3;
+struct y1 { }; struct y2 { }; struct y3 { };
+template <typename ...> struct f;
+
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::template_<f>(),
+ hana::type_c<f<>>
+));
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::template_<f>(hana::type_c<x1>),
+ hana::type_c<f<x1>>
+));
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::template_<f>(hana::type_c<x1>, hana::type_c<x2>),
+ hana::type_c<f<x1, x2>>
+));
+BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::template_<f>(hana::type_c<x1>, hana::type_c<x2>, hana::type_c<x3>),
+ hana::type_c<f<x1, x2, x3>>
+));
+
+using F = decltype(hana::template_<f>);
+static_assert(std::is_same<F::apply<>::type, f<>>{}, "");
+static_assert(std::is_same<F::apply<x1>::type, f<x1>>{}, "");
+static_assert(std::is_same<F::apply<x1, x2>::type, f<x1, x2>>{}, "");
+static_assert(std::is_same<F::apply<x1, x2, x3>::type, f<x1, x2, x3>>{}, "");
+
+// Make sure we model the Metafunction concept
+static_assert(hana::Metafunction<decltype(hana::template_<f>)>::value, "");
+static_assert(hana::Metafunction<decltype(hana::template_<f>)&>::value, "");
+
+// Make sure we can use aliases
+template <typename T> using alias = T;
+static_assert(hana::template_<alias>(hana::type_c<x1>) == hana::type_c<x1>, "");
+
+// Make sure template_ is SFINAE-friendly
+template <typename T> struct unary;
+BOOST_HANA_CONSTANT_CHECK(hana::not_(
+ hana::is_valid(hana::template_<unary>)(hana::type_c<void>, hana::type_c<void>)
+));
+
+// Make sure we don't read from a non-constexpr variable
+int main() {
+ auto t = hana::type_c<x1>;
+ constexpr auto r = hana::template_<f>(t);
+ (void)r;
+}
diff --git a/src/boost/libs/hana/test/type/traits.cpp b/src/boost/libs/hana/test/type/traits.cpp
new file mode 100644
index 00000000..dd2e3d7e
--- /dev/null
+++ b/src/boost/libs/hana/test/type/traits.cpp
@@ -0,0 +1,154 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/traits.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+enum Enumeration { };
+struct Structure { };
+constexpr auto e = hana::type_c<Enumeration>;
+constexpr auto s = hana::type_c<Structure>;
+
+int main() {
+ // We just make sure that they compile. If the forwarding to `std::` is
+ // well done, it is the job of `std::` to return the right thing.
+
+ ///////////////////////
+ // Type properties
+ ///////////////////////
+ // Primary type categories
+ static_assert(!hana::traits::is_void(s), "the traits should be compile-time checkable");
+ hana::traits::is_null_pointer(s);
+ hana::traits::is_integral(s);
+ hana::traits::is_floating_point(s);
+ hana::traits::is_array(s);
+ hana::traits::is_enum(s);
+ hana::traits::is_union(s);
+ hana::traits::is_class(s);
+ hana::traits::is_function(s);
+ hana::traits::is_pointer(s);
+ hana::traits::is_lvalue_reference(s);
+ hana::traits::is_rvalue_reference(s);
+ hana::traits::is_member_object_pointer(s);
+ hana::traits::is_member_function_pointer(s);
+
+ // Composite type categories
+ hana::traits::is_fundamental(s);
+ hana::traits::is_arithmetic(s);
+ hana::traits::is_scalar(s);
+ hana::traits::is_object(s);
+ hana::traits::is_compound(s);
+ hana::traits::is_reference(s);
+ hana::traits::is_member_pointer(s);
+
+ // Type properties
+ hana::traits::is_const(s);
+ hana::traits::is_volatile(s);
+ hana::traits::is_trivial(s);
+ hana::traits::is_trivially_copyable(s);
+ hana::traits::is_standard_layout(s);
+ hana::traits::is_pod(s);
+ hana::traits::is_literal_type(s);
+ hana::traits::is_empty(s);
+ hana::traits::is_polymorphic(s);
+ hana::traits::is_abstract(s);
+ hana::traits::is_signed(s);
+ hana::traits::is_unsigned(s);
+
+ // Supported operations
+ hana::traits::is_constructible(s, s);
+ hana::traits::is_trivially_constructible(s, s);
+ hana::traits::is_nothrow_constructible(s, s);
+
+ hana::traits::is_default_constructible(s);
+ hana::traits::is_trivially_default_constructible(s);
+ hana::traits::is_nothrow_default_constructible(s);
+
+ hana::traits::is_copy_constructible(s);
+ hana::traits::is_trivially_copy_constructible(s);
+ hana::traits::is_nothrow_copy_constructible(s);
+
+ hana::traits::is_move_constructible(s);
+ hana::traits::is_trivially_move_constructible(s);
+ hana::traits::is_nothrow_move_constructible(s);
+
+ hana::traits::is_assignable(s, s);
+ hana::traits::is_trivially_assignable(s, s);
+ hana::traits::is_nothrow_assignable(s, s);
+
+ hana::traits::is_copy_assignable(s);
+ hana::traits::is_trivially_copy_assignable(s);
+ hana::traits::is_nothrow_copy_assignable(s);
+
+ hana::traits::is_move_assignable(s);
+ hana::traits::is_trivially_move_assignable(s);
+ hana::traits::is_nothrow_move_assignable(s);
+
+ hana::traits::is_destructible(s);
+ hana::traits::is_trivially_destructible(s);
+ hana::traits::is_nothrow_destructible(s);
+
+ hana::traits::has_virtual_destructor(s);
+
+ // Property queries
+ hana::traits::alignment_of(s);
+ hana::traits::rank(s);
+ hana::traits::extent(s);
+ hana::traits::extent(hana::type_c<int[2][3]>, hana::uint_c<1>);
+
+ // Type relationships
+ hana::traits::is_same(s, s);
+ hana::traits::is_base_of(s, s);
+ hana::traits::is_convertible(s, s);
+
+ ///////////////////////
+ // Type modifications
+ ///////////////////////
+ // Const-volatility specifiers
+ hana::traits::remove_cv(s);
+ hana::traits::remove_const(s);
+ hana::traits::remove_volatile(s);
+
+ hana::traits::add_cv(s);
+ hana::traits::add_const(s);
+ hana::traits::add_volatile(s);
+
+ // References
+ hana::traits::remove_reference(s);
+ hana::traits::add_lvalue_reference(s);
+ hana::traits::add_rvalue_reference(s);
+
+ // Pointers
+ hana::traits::remove_pointer(s);
+ hana::traits::add_pointer(s);
+
+ // Sign modifiers
+ hana::traits::make_signed(hana::type_c<unsigned>);
+ hana::traits::make_unsigned(hana::type_c<signed>);
+
+ // Arrays
+ hana::traits::remove_extent(s);
+ hana::traits::remove_all_extents(s);
+
+ // Miscellaneous transformations
+ hana::traits::aligned_storage(hana::size_c<1>);
+ hana::traits::aligned_storage(hana::size_c<1>, hana::size_c<1>);
+ hana::traits::aligned_union(hana::size_c<0>, s);
+ hana::traits::decay(s);
+
+ hana::traits::common_type(s, s);
+ hana::traits::underlying_type(e);
+ using FunctionPointer = void(*)();
+ hana::traits::result_of(hana::type_c<FunctionPointer(void)>);
+
+ ///////////////////////
+ // Utilities
+ ///////////////////////
+ using Z = decltype(hana::traits::declval(hana::type_c<Structure>));
+}
diff --git a/src/boost/libs/hana/test/type/typeid.cpp b/src/boost/libs/hana/test/type/typeid.cpp
new file mode 100644
index 00000000..44b7c3a4
--- /dev/null
+++ b/src/boost/libs/hana/test/type/typeid.cpp
@@ -0,0 +1,182 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the 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;
+
+
+using Function = void();
+void function() { }
+
+int main() {
+ {
+ struct T { };
+ T t;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(T{}),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(t),
+ hana::type_c<T>
+ ));
+ }
+
+ // [cv-qualified] reference types
+ {
+ struct T { };
+ T t;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(static_cast<T&>(t)),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(static_cast<T const&>(t)),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(static_cast<T volatile&>(t)),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(static_cast<T const volatile&>(t)),
+ hana::type_c<T>
+ ));
+ }
+
+ // [cv-qualified] rvalue reference types
+ {
+ struct T { };
+ T t;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(static_cast<T&&>(t)),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(static_cast<T const &&>(t)),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(static_cast<T volatile&&>(t)),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(static_cast<T const volatile&&>(t)),
+ hana::type_c<T>
+ ));
+ }
+
+ // typeid_(type_c<T>) is the identity function
+ {
+ struct T;
+ auto const type_const = hana::type_c<T>;
+ auto const& type_const_ref = hana::type_c<T>;
+ auto& type_ref = hana::type_c<T>;
+ auto&& type_ref_ref = static_cast<decltype(type_ref)&&>(type_ref);
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(hana::type_c<T>),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(type_const),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(type_const_ref),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(type_ref),
+ hana::type_c<T>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(type_ref_ref),
+ hana::type_c<T>
+ ));
+ }
+
+ // make sure we don't read from non-constexpr variables
+ {
+ struct T;
+ auto t = hana::type_c<T>;
+ auto x = 1;
+ constexpr auto r1 = hana::typeid_(t); (void)r1;
+ constexpr auto r2 = hana::typeid_(x); (void)r2;
+ }
+
+ // typeid_ with builtin arrays, function pointers and other weirdos
+ {
+ struct T { };
+ using A = T[3];
+ A a;
+ A& a_ref = a;
+ A const& a_const_ref = a;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(a),
+ hana::type_c<A>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(a_ref),
+ hana::type_c<A>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(a_const_ref),
+ hana::type_c<A>
+ ));
+ }
+ {
+ using Fptr = int(*)();
+ Fptr f;
+ Fptr& f_ref = f;
+ Fptr const& f_const_ref = f;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(f),
+ hana::type_c<Fptr>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(f_ref),
+ hana::type_c<Fptr>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(f_const_ref),
+ hana::type_c<Fptr>
+ ));
+ }
+ {
+ Function& function_ref = function;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(function),
+ hana::type_c<Function>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::typeid_(function_ref),
+ hana::type_c<Function>
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/type/unary_plus.cpp b/src/boost/libs/hana/test/type/unary_plus.cpp
new file mode 100644
index 00000000..b9aa8feb
--- /dev/null
+++ b/src/boost/libs/hana/test/type/unary_plus.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/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// This test checks that the unary + operator on types works as expected.
+// The unary + operator is supposed to turn a reference to a hana::type
+// object into an equivalent prvalue.
+
+struct T;
+
+int main() {
+ auto& ref = hana::type_c<T>;
+ auto const& cref = hana::type_c<T>;
+ auto&& rref = hana::type_c<T>;
+ auto val = hana::type_c<T>;
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(val, +val));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(val, +ref));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(val, +cref));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(val, +rref));
+
+ static_assert(!std::is_reference<decltype(+val)>{}, "");
+ static_assert(!std::is_reference<decltype(+ref)>{}, "");
+ static_assert(!std::is_reference<decltype(+cref)>{}, "");
+ static_assert(!std::is_reference<decltype(+rref)>{}, "");
+
+ using T1 = decltype(+val)::type;
+ using T2 = decltype(+ref)::type;
+ using T3 = decltype(+cref)::type;
+ using T4 = decltype(+rref)::type;
+}