summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/test/type
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/test/type')
-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
18 files changed, 1303 insertions, 0 deletions
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 000000000..35a75c20c
--- /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 000000000..6b8203b21
--- /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 000000000..b956c324e
--- /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 000000000..4d5a18a84
--- /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 000000000..88bcf3352
--- /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 000000000..e42e82801
--- /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 000000000..e3159bbc3
--- /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 000000000..2f2abcd35
--- /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 000000000..622840f9b
--- /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 000000000..68a6a9839
--- /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 000000000..aa52c1f38
--- /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 000000000..b0123708b
--- /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 000000000..6e0410dff
--- /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 000000000..85110d295
--- /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 000000000..6b35d35e7
--- /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 000000000..dd2e3d7e0
--- /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 000000000..44b7c3a49
--- /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 000000000..b9aa8feba
--- /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;
+}