1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
15 // constexpr EXPLICIT optional(U&& u);
18 #include <type_traits>
21 #include "test_macros.h"
22 #include "archetypes.hpp"
23 #include "test_convertible.hpp"
30 constexpr ImplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
35 constexpr explicit ExplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
40 constexpr ImplicitAny(U&&) {}
44 template <class To, class From>
45 constexpr bool implicit_conversion(optional<To>&& opt, const From& v)
47 using O = optional<To>;
48 static_assert(test_convertible<O, From>(), "");
49 static_assert(!test_convertible<O, void*>(), "");
50 static_assert(!test_convertible<O, From, int>(), "");
51 return opt && *opt == static_cast<To>(v);
54 template <class To, class Input, class Expect>
55 constexpr bool explicit_conversion(Input&& in, const Expect& v)
57 using O = optional<To>;
58 static_assert(std::is_constructible<O, Input>::value, "");
59 static_assert(!std::is_convertible<Input, O>::value, "");
60 static_assert(!std::is_constructible<O, void*>::value, "");
61 static_assert(!std::is_constructible<O, Input, int>::value, "");
62 optional<To> opt(std::forward<Input>(in));
63 return opt && *opt == static_cast<To>(v);
69 static_assert(implicit_conversion<long long>(42, 42), "");
72 static_assert(implicit_conversion<long double>(3.14, 3.14), "");
76 optional<void* const> o(&x);
80 using T = TrivialTestTypes::TestType;
81 static_assert(implicit_conversion<T>(42, 42), "");
84 using T = TestTypes::TestType;
85 assert(implicit_conversion<T>(3, T(3)));
88 using O = optional<ImplicitAny>;
89 static_assert(!test_convertible<O, std::in_place_t>(), "");
90 static_assert(!test_convertible<O, std::in_place_t&>(), "");
91 static_assert(!test_convertible<O, const std::in_place_t&>(), "");
92 static_assert(!test_convertible<O, std::in_place_t&&>(), "");
93 static_assert(!test_convertible<O, const std::in_place_t&&>(), "");
96 #ifndef TEST_HAS_NO_EXCEPTIONS
99 using T = ImplicitThrow;
109 void test_explicit() {
111 using T = ExplicitTrivialTestTypes::TestType;
112 static_assert(explicit_conversion<T>(42, 42), "");
115 using T = ExplicitConstexprTestTypes::TestType;
116 static_assert(explicit_conversion<T>(42, 42), "");
117 static_assert(!std::is_convertible<int, T>::value, "");
120 using T = ExplicitTestTypes::TestType;
123 assert(explicit_conversion<T>(42, 42));
124 assert(T::alive == 0);
129 assert(T::alive == 1);
130 assert(T::value_constructed == 1);
131 assert(T::move_constructed == 0);
132 assert(T::copy_constructed == 0);
133 assert(t.value().value == 42);
135 assert(T::alive == 0);
137 #ifndef TEST_HAS_NO_EXCEPTIONS
140 using T = ExplicitThrow;