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
400373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_T_ctor_noexcept() {
410373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
420373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<Dummy, NoThrowT>;
430373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::is_nothrow_constructible<V, int>::value, "");
440373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
450373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
460373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<Dummy, ThrowsT>;
470373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_nothrow_constructible<V, int>::value, "");
480373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
490373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}
500373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
510373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_T_ctor_sfinae() {
520373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
530373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<long, unsigned>;
540373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, int>::value, "ambiguous");
550373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
560373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
570373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<std::string, std::string>;
580373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
590373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
600373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
610373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<std::string, void *>;
620373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, int>::value,
630373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier                  "no matching constructor");
640373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
650373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
660373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
670373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    using V = std::variant<int, int &&>;
680373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, int>::value, "ambiguous");
690373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
700373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
71cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier    using V = std::variant<int, const int &>;
720373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(!std::is_constructible<V, int>::value, "ambiguous");
730373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
740373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif
750373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}
760373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
770373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_T_ctor_basic() {
780373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
790373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    constexpr std::variant<int> v(42);
800373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(v.index() == 0, "");
810373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::get<0>(v) == 42, "");
820373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
830373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
840373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    constexpr std::variant<int, long> v(42l);
850373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(v.index() == 1, "");
860373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::get<1>(v) == 42, "");
870373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
880373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
890373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
90cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier    using V = std::variant<const int &, int &&, long>;
910373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::is_convertible<int &, V>::value, "must be implicit");
920373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    int x = 42;
930373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    V v(x);
940373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    assert(v.index() == 0);
950373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    assert(&std::get<0>(v) == &x);
960373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
970373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  {
98cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier    using V = std::variant<const int &, int &&, long>;
990373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    static_assert(std::is_convertible<int, V>::value, "must be implicit");
1000373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    int x = 42;
1010373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    V v(std::move(x));
1020373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    assert(v.index() == 1);
1030373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier    assert(&std::get<1>(v) == &x);
1040373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  }
1050373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif
1060373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}
1070373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier
1080373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierint main() {
1090373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  test_T_ctor_basic();
1100373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  test_T_ctor_noexcept();
1110373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier  test_T_ctor_sfinae();
1120373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}
113