summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities/variant/variant.variant/variant.ctor
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/test/std/utilities/variant/variant.variant/variant.ctor')
-rw-r--r--libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp112
-rw-r--r--libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp137
-rw-r--r--libcxx/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp112
-rw-r--r--libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp103
-rw-r--r--libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp103
-rw-r--r--libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp113
-rw-r--r--libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp110
-rw-r--r--libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp174
8 files changed, 964 insertions, 0 deletions
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
new file mode 100644
index 00000000000..b9ea61046b4
--- /dev/null
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <class T> constexpr variant(T&&) noexcept(see below);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+struct Dummy {
+ Dummy() = default;
+};
+
+struct ThrowsT {
+ ThrowsT(int) noexcept(false) {}
+};
+
+struct NoThrowT {
+ NoThrowT(int) noexcept(true) {}
+};
+
+void test_T_ctor_noexcept() {
+ {
+ using V = std::variant<Dummy, NoThrowT>;
+ static_assert(std::is_nothrow_constructible<V, int>::value, "");
+ }
+ {
+ using V = std::variant<Dummy, ThrowsT>;
+ static_assert(!std::is_nothrow_constructible<V, int>::value, "");
+ }
+}
+
+void test_T_ctor_sfinae() {
+ {
+ using V = std::variant<long, unsigned>;
+ static_assert(!std::is_constructible<V, int>::value, "ambiguous");
+ }
+ {
+ using V = std::variant<std::string, std::string>;
+ static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
+ }
+ {
+ using V = std::variant<std::string, void *>;
+ static_assert(!std::is_constructible<V, int>::value,
+ "no matching constructor");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int, int &&>;
+ static_assert(!std::is_constructible<V, int>::value, "ambiguous");
+ }
+ {
+ using V = std::variant<int, int const &>;
+ static_assert(!std::is_constructible<V, int>::value, "ambiguous");
+ }
+#endif
+}
+
+void test_T_ctor_basic() {
+ {
+ constexpr std::variant<int> v(42);
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, long> v(42l);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int const &, int &&, long>;
+ static_assert(std::is_convertible<int &, V>::value, "must be implicit");
+ int x = 42;
+ V v(x);
+ assert(v.index() == 0);
+ assert(&std::get<0>(v) == &x);
+ }
+ {
+ using V = std::variant<int const &, int &&, long>;
+ static_assert(std::is_convertible<int, V>::value, "must be implicit");
+ int x = 42;
+ V v(std::move(x));
+ assert(v.index() == 1);
+ assert(&std::get<1>(v) == &x);
+ }
+#endif
+}
+
+int main() {
+ test_T_ctor_basic();
+ test_T_ctor_noexcept();
+ test_T_ctor_sfinae();
+}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
new file mode 100644
index 00000000000..90f4f2c5655
--- /dev/null
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
@@ -0,0 +1,137 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// variant(variant const&);
+
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+
+struct NonT {
+ NonT(int v) : value(v) {}
+ NonT(NonT const &o) : value(o.value) {}
+ int value;
+};
+static_assert(!std::is_trivially_copy_constructible<NonT>::value, "");
+
+struct NoCopy {
+ NoCopy(NoCopy const &) = delete;
+};
+
+struct MoveOnly {
+ MoveOnly(MoveOnly const &) = delete;
+ MoveOnly(MoveOnly &&) = default;
+};
+
+struct MoveOnlyNT {
+ MoveOnlyNT(MoveOnlyNT const &) = delete;
+ MoveOnlyNT(MoveOnlyNT &&) {}
+};
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct MakeEmptyT {
+ static int alive;
+ MakeEmptyT() { ++alive; }
+ MakeEmptyT(MakeEmptyT const &) {
+ ++alive;
+ // Don't throw from the copy constructor since variant's assignment
+ // operator performs a copy before committing to the assignment.
+ }
+ MakeEmptyT(MakeEmptyT &&) { throw 42; }
+ MakeEmptyT &operator=(MakeEmptyT const &) { throw 42; }
+ MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
+ ~MakeEmptyT() { --alive; }
+};
+
+int MakeEmptyT::alive = 0;
+
+template <class Variant> void makeEmpty(Variant &v) {
+ Variant v2(std::in_place_type<MakeEmptyT>);
+ try {
+ v = v2;
+ assert(false);
+ } catch (...) {
+ assert(v.valueless_by_exception());
+ }
+}
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+void test_copy_ctor_sfinae() {
+ {
+ using V = std::variant<int, long>;
+ static_assert(std::is_copy_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, NoCopy>;
+ static_assert(!std::is_copy_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnly>;
+ static_assert(!std::is_copy_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnlyNT>;
+ static_assert(!std::is_copy_constructible<V>::value, "");
+ }
+}
+
+void test_copy_ctor_basic() {
+ {
+ std::variant<int> v(std::in_place_index<0>, 42);
+ std::variant<int> v2 = v;
+ assert(v2.index() == 0);
+ assert(std::get<0>(v2) == 42);
+ }
+ {
+ std::variant<int, long> v(std::in_place_index<1>, 42);
+ std::variant<int, long> v2 = v;
+ assert(v2.index() == 1);
+ assert(std::get<1>(v2) == 42);
+ }
+ {
+ std::variant<NonT> v(std::in_place_index<0>, 42);
+ assert(v.index() == 0);
+ std::variant<NonT> v2(v);
+ assert(v2.index() == 0);
+ assert(std::get<0>(v2).value == 42);
+ }
+ {
+ std::variant<int, NonT> v(std::in_place_index<1>, 42);
+ assert(v.index() == 1);
+ std::variant<int, NonT> v2(v);
+ assert(v2.index() == 1);
+ assert(std::get<1>(v2).value == 42);
+ }
+}
+
+void test_copy_ctor_valueless_by_exception() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ makeEmpty(v1);
+ V const &cv1 = v1;
+ V v(cv1);
+ assert(v.valueless_by_exception());
+#endif
+}
+
+int main() {
+ test_copy_ctor_basic();
+ test_copy_ctor_valueless_by_exception();
+ test_copy_ctor_sfinae();
+}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp
new file mode 100644
index 00000000000..124260bfcbf
--- /dev/null
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// constexpr variant() noexcept(see below);
+
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+struct NonDefaultConstructible {
+ NonDefaultConstructible(int) {}
+};
+
+struct NotNoexcept {
+ NotNoexcept() noexcept(false) {}
+};
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct DefaultCtorThrows {
+ DefaultCtorThrows() { throw 42; }
+};
+#endif
+
+void test_default_ctor_sfinae() {
+ {
+ using V = std::variant<std::monostate, int>;
+ static_assert(std::is_default_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<NonDefaultConstructible, int>;
+ static_assert(!std::is_default_constructible<V>::value, "");
+ }
+#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
+ {
+ using V = std::variant<int &, int>;
+ static_assert(!std::is_default_constructible<V>::value, "");
+ }
+#endif
+}
+
+void test_default_ctor_noexcept() {
+ {
+ using V = std::variant<int>;
+ static_assert(std::is_nothrow_default_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<NotNoexcept>;
+ static_assert(!std::is_nothrow_default_constructible<V>::value, "");
+ }
+}
+
+void test_default_ctor_throws() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using V = std::variant<DefaultCtorThrows, int>;
+ try {
+ V v;
+ assert(false);
+ } catch (int const &ex) {
+ assert(ex == 42);
+ } catch (...) {
+ assert(false);
+ }
+#endif
+}
+
+void test_default_ctor_basic() {
+ {
+ std::variant<int> v;
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == 0);
+ }
+ {
+ std::variant<int, long> v;
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == 0);
+ }
+ {
+ using V = std::variant<int, long>;
+ constexpr V v;
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 0, "");
+ }
+ {
+ using V = std::variant<int, long>;
+ constexpr V v;
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 0, "");
+ }
+}
+
+int main() {
+ test_default_ctor_basic();
+ test_default_ctor_sfinae();
+ test_default_ctor_noexcept();
+ test_default_ctor_throws();
+}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp
new file mode 100644
index 00000000000..18115722f8d
--- /dev/null
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_args.pass.cpp
@@ -0,0 +1,103 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <size_t I, class ...Args>
+// constexpr explicit variant(in_place_index_t<I>, Args&&...);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+void test_ctor_sfinae() {
+ {
+ using V = std::variant<int>;
+ static_assert(
+ std::is_constructible<V, std::in_place_index_t<0>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<0>, int>(), "");
+ }
+ {
+ using V = std::variant<int, long, long long>;
+ static_assert(
+ std::is_constructible<V, std::in_place_index_t<1>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<1>, int>(), "");
+ }
+ {
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ std::is_constructible<V, std::in_place_index_t<2>, int *>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<2>, int *>(), "");
+ }
+ { // args not convertible to type
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<0>, int *>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<0>, int *>(), "");
+ }
+ { // index not in variant
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<3>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<3>, int>(), "");
+ }
+}
+
+void test_ctor_basic() {
+ {
+ constexpr std::variant<int> v(std::in_place_index<0>, 42);
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, long, long> v(std::in_place_index<1>, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, const int, long> v(std::in_place_index<1>, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_index<0>, x);
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == x);
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_index<1>, x);
+ assert(v.index() == 1);
+ assert(std::get<1>(v) == x);
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_index<2>, x);
+ assert(v.index() == 2);
+ assert(std::get<2>(v) == x);
+ }
+}
+
+int main() {
+ test_ctor_basic();
+ test_ctor_sfinae();
+}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp
new file mode 100644
index 00000000000..608cdf9d6ef
--- /dev/null
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_index_init_list_args.pass.cpp
@@ -0,0 +1,103 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <size_t I, class Up, class ...Args>
+// constexpr explicit
+// variant(in_place_index_t<I>, initializer_list<Up>, Args&&...);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+struct InitList {
+ std::size_t size;
+ constexpr InitList(std::initializer_list<int> il) : size(il.size()) {}
+};
+
+struct InitListArg {
+ std::size_t size;
+ int value;
+ constexpr InitListArg(std::initializer_list<int> il, int v)
+ : size(il.size()), value(v) {}
+};
+
+void test_ctor_sfinae() {
+ using IL = std::initializer_list<int>;
+ { // just init list
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(std::is_constructible<V, std::in_place_index_t<0>, IL>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_index_t<0>, IL>(), "");
+ }
+ { // too many arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<0>, IL, int>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_index_t<0>, IL, int>(),
+ "");
+ }
+ { // too few arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<1>, IL>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<1>, IL>(), "");
+ }
+ { // init list and arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ std::is_constructible<V, std::in_place_index_t<1>, IL, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<1>, IL, int>(),
+ "");
+ }
+ { // not constructible from arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_index_t<2>, IL>::value, "");
+ static_assert(!test_convertible<V, std::in_place_index_t<2>, IL>(), "");
+ }
+}
+
+void test_ctor_basic() {
+ {
+ constexpr std::variant<InitList, InitListArg, InitList> v(
+ std::in_place_index<0>, {1, 2, 3});
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v).size == 3, "");
+ }
+ {
+ constexpr std::variant<InitList, InitListArg, InitList> v(
+ std::in_place_index<2>, {1, 2, 3});
+ static_assert(v.index() == 2, "");
+ static_assert(std::get<2>(v).size == 3, "");
+ }
+ {
+ constexpr std::variant<InitList, InitListArg, InitListArg> v(
+ std::in_place_index<1>, {1, 2, 3, 4}, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v).size == 4, "");
+ static_assert(std::get<1>(v).value == 42, "");
+ }
+}
+
+int main() {
+ test_ctor_basic();
+ test_ctor_sfinae();
+}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp
new file mode 100644
index 00000000000..a023f02bad6
--- /dev/null
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_args.pass.cpp
@@ -0,0 +1,113 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <class Tp, class ...Args>
+// constexpr explicit variant(in_place_type_t<Tp>, Args&&...);
+
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+void test_ctor_sfinae() {
+ {
+ using V = std::variant<int>;
+ static_assert(
+ std::is_constructible<V, std::in_place_type_t<int>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int>, int>(), "");
+ }
+ {
+ using V = std::variant<int, long, long long>;
+ static_assert(
+ std::is_constructible<V, std::in_place_type_t<long>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<long>, int>(), "");
+ }
+ {
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ std::is_constructible<V, std::in_place_type_t<int *>, int *>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int *>, int *>(),
+ "");
+ }
+ { // duplicate type
+ using V = std::variant<int, long, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<int>, int>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int>, int>(), "");
+ }
+ { // args not convertible to type
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<int>, int *>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int>, int *>(), "");
+ }
+ { // type not in variant
+ using V = std::variant<int, long, int *>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<long long>, int>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_type_t<long long>, int>(),
+ "");
+ }
+}
+
+void test_ctor_basic() {
+ {
+ constexpr std::variant<int> v(std::in_place_type<int>, 42);
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, long> v(std::in_place_type<long>, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+ {
+ constexpr std::variant<int, const int, long> v(
+ std::in_place_type<const int>, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v) == 42, "");
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_type<const int>, x);
+ assert(v.index() == 0);
+ assert(std::get<0>(v) == x);
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_type<volatile int>, x);
+ assert(v.index() == 1);
+ assert(std::get<1>(v) == x);
+ }
+ {
+ using V = std::variant<const int, volatile int, int>;
+ int x = 42;
+ V v(std::in_place_type<int>, x);
+ assert(v.index() == 2);
+ assert(std::get<2>(v) == x);
+ }
+}
+
+int main() {
+ test_ctor_basic();
+ test_ctor_sfinae();
+}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp
new file mode 100644
index 00000000000..e151572c466
--- /dev/null
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/in_place_type_init_list_args.pass.cpp
@@ -0,0 +1,110 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// template <class Tp, class Up, class ...Args>
+// constexpr explicit
+// variant(in_place_type_t<Tp>, initializer_list<Up>, Args&&...);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_convertible.hpp"
+#include "test_macros.h"
+
+struct InitList {
+ std::size_t size;
+ constexpr InitList(std::initializer_list<int> il) : size(il.size()) {}
+};
+
+struct InitListArg {
+ std::size_t size;
+ int value;
+ constexpr InitListArg(std::initializer_list<int> il, int v)
+ : size(il.size()), value(v) {}
+};
+
+void test_ctor_sfinae() {
+ using IL = std::initializer_list<int>;
+ { // just init list
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ std::is_constructible<V, std::in_place_type_t<InitList>, IL>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_type_t<InitList>, IL>(),
+ "");
+ }
+ { // too many arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(!std::is_constructible<V, std::in_place_type_t<InitList>, IL,
+ int>::value,
+ "");
+ static_assert(
+ !test_convertible<V, std::in_place_type_t<InitList>, IL, int>(), "");
+ }
+ { // too few arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<InitListArg>, IL>::value,
+ "");
+ static_assert(!test_convertible<V, std::in_place_type_t<InitListArg>, IL>(),
+ "");
+ }
+ { // init list and arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(std::is_constructible<V, std::in_place_type_t<InitListArg>,
+ IL, int>::value,
+ "");
+ static_assert(
+ !test_convertible<V, std::in_place_type_t<InitListArg>, IL, int>(), "");
+ }
+ { // not constructible from arguments
+ using V = std::variant<InitList, InitListArg, int>;
+ static_assert(
+ !std::is_constructible<V, std::in_place_type_t<int>, IL>::value, "");
+ static_assert(!test_convertible<V, std::in_place_type_t<int>, IL>(), "");
+ }
+ { // duplicate types in variant
+ using V = std::variant<InitListArg, InitListArg, int>;
+ static_assert(!std::is_constructible<V, std::in_place_type_t<InitListArg>,
+ IL, int>::value,
+ "");
+ static_assert(
+ !test_convertible<V, std::in_place_type_t<InitListArg>, IL, int>(), "");
+ }
+}
+
+void test_ctor_basic() {
+ {
+ constexpr std::variant<InitList, InitListArg> v(
+ std::in_place_type<InitList>, {1, 2, 3});
+ static_assert(v.index() == 0, "");
+ static_assert(std::get<0>(v).size == 3, "");
+ }
+ {
+ constexpr std::variant<InitList, InitListArg> v(
+ std::in_place_type<InitListArg>, {1, 2, 3, 4}, 42);
+ static_assert(v.index() == 1, "");
+ static_assert(std::get<1>(v).size == 4, "");
+ static_assert(std::get<1>(v).value == 42, "");
+ }
+}
+
+int main() {
+ test_ctor_basic();
+ test_ctor_sfinae();
+}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
new file mode 100644
index 00000000000..dcc973f074f
--- /dev/null
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
@@ -0,0 +1,174 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+// variant(variant&&) noexcept(see below);
+
+#include <cassert>
+#include <string>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+
+struct ThrowsMove {
+ ThrowsMove(ThrowsMove &&) noexcept(false) {}
+};
+
+struct NoCopy {
+ NoCopy(NoCopy const &) = delete;
+};
+
+struct MoveOnly {
+ int value;
+ MoveOnly(int v) : value(v) {}
+ MoveOnly(MoveOnly const &) = delete;
+ MoveOnly(MoveOnly &&) = default;
+};
+
+struct MoveOnlyNT {
+ int value;
+ MoveOnlyNT(int v) : value(v) {}
+ MoveOnlyNT(MoveOnlyNT const &) = delete;
+ MoveOnlyNT(MoveOnlyNT &&other) : value(other.value) { other.value = -1; }
+};
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct MakeEmptyT {
+ static int alive;
+ MakeEmptyT() { ++alive; }
+ MakeEmptyT(MakeEmptyT const &) {
+ ++alive;
+ // Don't throw from the copy constructor since variant's assignment
+ // operator performs a copy before committing to the assignment.
+ }
+ MakeEmptyT(MakeEmptyT &&) { throw 42; }
+ MakeEmptyT &operator=(MakeEmptyT const &) { throw 42; }
+ MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
+ ~MakeEmptyT() { --alive; }
+};
+
+int MakeEmptyT::alive = 0;
+
+template <class Variant> void makeEmpty(Variant &v) {
+ Variant v2(std::in_place_type<MakeEmptyT>);
+ try {
+ v = v2;
+ assert(false);
+ } catch (...) {
+ assert(v.valueless_by_exception());
+ }
+}
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+void test_move_noexcept() {
+ {
+ using V = std::variant<int, long>;
+ static_assert(std::is_nothrow_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnly>;
+ static_assert(std::is_nothrow_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnlyNT>;
+ static_assert(!std::is_nothrow_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, ThrowsMove>;
+ static_assert(!std::is_nothrow_move_constructible<V>::value, "");
+ }
+}
+
+void test_move_ctor_sfinae() {
+ {
+ using V = std::variant<int, long>;
+ static_assert(std::is_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnly>;
+ static_assert(std::is_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, MoveOnlyNT>;
+ static_assert(std::is_move_constructible<V>::value, "");
+ }
+ {
+ using V = std::variant<int, NoCopy>;
+ static_assert(!std::is_move_constructible<V>::value, "");
+ }
+}
+
+void test_move_ctor_basic() {
+ {
+ std::variant<int> v(std::in_place_index<0>, 42);
+ std::variant<int> v2 = std::move(v);
+ assert(v2.index() == 0);
+ assert(std::get<0>(v2) == 42);
+ }
+ {
+ std::variant<int, long> v(std::in_place_index<1>, 42);
+ std::variant<int, long> v2 = std::move(v);
+ assert(v2.index() == 1);
+ assert(std::get<1>(v2) == 42);
+ }
+ {
+ std::variant<MoveOnly> v(std::in_place_index<0>, 42);
+ assert(v.index() == 0);
+ std::variant<MoveOnly> v2(std::move(v));
+ assert(v2.index() == 0);
+ assert(std::get<0>(v2).value == 42);
+ }
+ {
+ std::variant<int, MoveOnly> v(std::in_place_index<1>, 42);
+ assert(v.index() == 1);
+ std::variant<int, MoveOnly> v2(std::move(v));
+ assert(v2.index() == 1);
+ assert(std::get<1>(v2).value == 42);
+ }
+ {
+ std::variant<MoveOnlyNT> v(std::in_place_index<0>, 42);
+ assert(v.index() == 0);
+ std::variant<MoveOnlyNT> v2(std::move(v));
+ assert(v2.index() == 0);
+ assert(std::get<0>(v).value == -1);
+ assert(std::get<0>(v2).value == 42);
+ }
+ {
+ std::variant<int, MoveOnlyNT> v(std::in_place_index<1>, 42);
+ assert(v.index() == 1);
+ std::variant<int, MoveOnlyNT> v2(std::move(v));
+ assert(v2.index() == 1);
+ assert(std::get<1>(v).value == -1);
+ assert(std::get<1>(v2).value == 42);
+ }
+}
+
+void test_move_ctor_valueless_by_exception() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using V = std::variant<int, MakeEmptyT>;
+ V v1;
+ makeEmpty(v1);
+ V v(std::move(v1));
+ assert(v.valueless_by_exception());
+#endif
+}
+
+int main() {
+ test_move_ctor_basic();
+ test_move_ctor_valueless_by_exception();
+ test_move_noexcept();
+ test_move_ctor_sfinae();
+}
OpenPOWER on IntegriCloud