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 <size_t I, class U, class ...Args> 180373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// void emplace(initializer_list<U> il,Args&&... args); 190373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 200373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <cassert> 210373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <string> 220373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <type_traits> 230373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <variant> 240373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 250373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include "archetypes.hpp" 260373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include "test_convertible.hpp" 270373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include "test_macros.h" 280373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 290373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct InitList { 300373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::size_t size; 310373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier constexpr InitList(std::initializer_list<int> il) : size(il.size()) {} 320373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 330373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 340373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct InitListArg { 350373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::size_t size; 360373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier int value; 370373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier constexpr InitListArg(std::initializer_list<int> il, int v) 380373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier : size(il.size()), value(v) {} 390373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 400373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 410373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliertemplate <class Var, size_t I, class... Args> 420373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierconstexpr auto test_emplace_exists_imp(int) -> decltype( 430373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) { 440373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier return true; 450373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 460373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 470373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliertemplate <class, size_t, class...> 480373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierconstexpr auto test_emplace_exists_imp(long) -> bool { 490373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier return false; 500373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 510373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 520373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliertemplate <class Var, size_t I, class... Args> constexpr bool emplace_exists() { 530373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier return test_emplace_exists_imp<Var, I, Args...>(0); 540373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 550373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 560373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_emplace_sfinae() { 570373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = 580373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<int, TestTypes::NoCtors, InitList, InitListArg, long, long>; 590373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using IL = std::initializer_list<int>; 600373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!emplace_exists<V, 1, IL>(), "no such constructor"); 610373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(emplace_exists<V, 2, IL>(), ""); 620373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!emplace_exists<V, 2, int>(), "args don't match"); 630373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!emplace_exists<V, 2, IL, int>(), "too many args"); 640373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(emplace_exists<V, 3, IL, int>(), ""); 650373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!emplace_exists<V, 3, int>(), "args don't match"); 660373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!emplace_exists<V, 3, IL>(), "too few args"); 670373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!emplace_exists<V, 3, IL, int, int>(), "too many args"); 680373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 690373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 700373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_basic() { 710373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, InitList, InitListArg, TestTypes::NoCtors>; 720373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v; 730373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier v.emplace<1>({1, 2, 3}); 740373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v).size == 3); 750373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier v.emplace<2>({1, 2, 3, 4}, 42); 760373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<2>(v).size == 4); 770373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<2>(v).value == 42); 780373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier v.emplace<1>({1}); 790373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v).size == 1); 800373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 810373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 820373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierint main() { 830373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_basic(); 840373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_emplace_sfinae(); 850373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 86