]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
Vendor import of libc++ trunk r300422:
[FreeBSD/FreeBSD.git] / test / std / utilities / variant / variant.variant / variant.mod / emplace_type_init_list_args.pass.cpp
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 // UNSUPPORTED: c++98, c++03, c++11, c++14
12
13 // <variant>
14
15 // template <class ...Types> class variant;
16
17 // template <class T, class U, class ...Args>
18 //   T& emplace(initializer_list<U> il,Args&&... args);
19
20 #include <cassert>
21 #include <string>
22 #include <type_traits>
23 #include <variant>
24
25 #include "archetypes.hpp"
26 #include "test_convertible.hpp"
27 #include "test_macros.h"
28
29 struct InitList {
30   std::size_t size;
31   constexpr InitList(std::initializer_list<int> il) : size(il.size()) {}
32 };
33
34 struct InitListArg {
35   std::size_t size;
36   int value;
37   constexpr InitListArg(std::initializer_list<int> il, int v)
38       : size(il.size()), value(v) {}
39 };
40
41 template <class Var, class T, class... Args>
42 constexpr auto test_emplace_exists_imp(int) -> decltype(
43     std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
44   return true;
45 }
46
47 template <class, class, class...>
48 constexpr auto test_emplace_exists_imp(long) -> bool {
49   return false;
50 }
51
52 template <class... Args> constexpr bool emplace_exists() {
53   return test_emplace_exists_imp<Args...>(0);
54 }
55
56 void test_emplace_sfinae() {
57   using V =
58       std::variant<int, TestTypes::NoCtors, InitList, InitListArg, long, long>;
59   using IL = std::initializer_list<int>;
60   static_assert(emplace_exists<V, InitList, IL>(), "");
61   static_assert(!emplace_exists<V, InitList, int>(), "args don't match");
62   static_assert(!emplace_exists<V, InitList, IL, int>(), "too many args");
63   static_assert(emplace_exists<V, InitListArg, IL, int>(), "");
64   static_assert(!emplace_exists<V, InitListArg, int>(), "args don't match");
65   static_assert(!emplace_exists<V, InitListArg, IL>(), "too few args");
66   static_assert(!emplace_exists<V, InitListArg, IL, int, int>(),
67                 "too many args");
68 }
69
70 void test_basic() {
71   using V = std::variant<int, InitList, InitListArg, TestTypes::NoCtors>;
72   V v;
73   auto& ref1 = v.emplace<InitList>({1, 2, 3});
74   static_assert(std::is_same_v<InitList&,decltype(ref1)>, "");
75   assert(std::get<InitList>(v).size == 3);
76   assert(&ref1 == &std::get<InitList>(v));
77   auto& ref2 = v.emplace<InitListArg>({1, 2, 3, 4}, 42);
78   static_assert(std::is_same_v<InitListArg&,decltype(ref2)>, "");
79   assert(std::get<InitListArg>(v).size == 4);
80   assert(std::get<InitListArg>(v).value == 42);
81   assert(&ref2 == &std::get<InitListArg>(v));
82   auto& ref3 = v.emplace<InitList>({1});
83   static_assert(std::is_same_v<InitList&,decltype(ref3)>, "");
84   assert(std::get<InitList>(v).size == 1);
85   assert(&ref3 == &std::get<InitList>(v));
86 }
87
88 int main() {
89   test_basic();
90   test_emplace_sfinae();
91 }