summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/test/type/is_valid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/test/type/is_valid.cpp')
-rw-r--r--src/boost/libs/hana/test/type/is_valid.cpp206
1 files changed, 206 insertions, 0 deletions
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{})));
+ }
+}