10373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// -*- C++ -*-
20373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier//===----------------------------------------------------------------------===//
30373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier//
40373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier//                     The LLVM Compiler Infrastructure
50373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier//
60373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
70373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// Source Licenses. See LICENSE.TXT for details.
80373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier//
90373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier//===----------------------------------------------------------------------===//
100373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
110373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// UNSUPPORTED: c++98, c++03, c++11, c++14
120373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
130373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// <variant>
140373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
150373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// template <class ...Types> class variant;
160373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
170373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// template <class T> constexpr variant(T&&) noexcept(see below);
180373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
190373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <cassert>
200373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <string>
210373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <type_traits>
220373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <variant>
230373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
240373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include "test_convertible.hpp"
250373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include "test_macros.h"
260373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include "variant_test_helpers.hpp"
270373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
280373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct Dummy {
290373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  Dummy() = default;
300373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier};
310373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
320373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct ThrowsT {
330373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  ThrowsT(int) noexcept(false) {}
340373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier};
350373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
360373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct NoThrowT {
370373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  NoThrowT(int) noexcept(true) {}
380373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier};
390373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
40b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Parkstruct AnyConstructible { template <typename T> AnyConstructible(T&&) {} };
41b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Parkstruct NoConstructible { NoConstructible() = delete; };
42b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park
430373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_T_ctor_noexcept() {
440373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
450373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<Dummy, NoThrowT>;
460373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::is_nothrow_constructible<V, int>::value, "");
470373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
480373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
490373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<Dummy, ThrowsT>;
500373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_nothrow_constructible<V, int>::value, "");
510373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
520373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}
530373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
540373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_T_ctor_sfinae() {
550373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
560373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<long, unsigned>;
570373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, int>::value, "ambiguous");
580373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
590373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
600373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<std::string, std::string>;
610373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
620373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
630373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
640373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<std::string, void *>;
650373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, int>::value,
660373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier                  "no matching constructor");
670373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
68b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park  {
69b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park    using V = std::variant<AnyConstructible, NoConstructible>;
70b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park    static_assert(
71b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park        !std::is_constructible<V, std::in_place_type_t<NoConstructible>>::value,
72b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park        "no matching constructor");
73b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park    static_assert(!std::is_constructible<V, std::in_place_index_t<1>>::value,
74b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park                  "no matching constructor");
75b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park  }
76b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park
77b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park
78b47a9bc6c40a06aeaec76262e056b8bd1a5203ecMichael Park
790373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
800373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
810373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<int, int &&>;
820373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, int>::value, "ambiguous");
830373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
840373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
85cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier    using V = std::variant<int, const int &>;
860373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, int>::value, "ambiguous");
870373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
880373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif
890373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}
900373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
910373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_T_ctor_basic() {
920373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
930373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    constexpr std::variant<int> v(42);
940373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(v.index() == 0, "");
950373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::get<0>(v) == 42, "");
960373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
970373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
980373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    constexpr std::variant<int, long> v(42l);
990373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(v.index() == 1, "");
1000373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::get<1>(v) == 42, "");
1010373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
1020373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
1030373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
104cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier    using V = std::variant<const int &, int &&, long>;
1050373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::is_convertible<int &, V>::value, "must be implicit");
1060373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    int x = 42;
1070373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    V v(x);
1080373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    assert(v.index() == 0);
1090373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    assert(&std::get<0>(v) == &x);
1100373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
1110373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
112cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier    using V = std::variant<const int &, int &&, long>;
1130373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::is_convertible<int, V>::value, "must be implicit");
1140373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    int x = 42;
1150373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    V v(std::move(x));
1160373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    assert(v.index() == 1);
1170373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    assert(&std::get<1>(v) == &x);
1180373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
1190373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif
1200373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}
1210373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
1220373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierint main() {
1230373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  test_T_ctor_basic();
1240373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  test_T_ctor_noexcept();
1250373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  test_T_ctor_sfinae();
1260373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}
127