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