Home | History | Annotate | Download | only in variant.mod
      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 // XFAIL: with_system_cxx_lib=macosx10.12
     14 // XFAIL: with_system_cxx_lib=macosx10.11
     15 // XFAIL: with_system_cxx_lib=macosx10.10
     16 // XFAIL: with_system_cxx_lib=macosx10.9
     17 // XFAIL: with_system_cxx_lib=macosx10.7
     18 // XFAIL: with_system_cxx_lib=macosx10.8
     19 
     20 // <variant>
     21 
     22 // template <class ...Types> class variant;
     23 
     24 // template <class T, class U, class ...Args>
     25 //   T& emplace(initializer_list<U> il,Args&&... args);
     26 
     27 #include <cassert>
     28 #include <string>
     29 #include <type_traits>
     30 #include <variant>
     31 
     32 #include "archetypes.hpp"
     33 #include "test_convertible.hpp"
     34 #include "test_macros.h"
     35 
     36 struct InitList {
     37   std::size_t size;
     38   constexpr InitList(std::initializer_list<int> il) : size(il.size()) {}
     39 };
     40 
     41 struct InitListArg {
     42   std::size_t size;
     43   int value;
     44   constexpr InitListArg(std::initializer_list<int> il, int v)
     45       : size(il.size()), value(v) {}
     46 };
     47 
     48 template <class Var, class T, class... Args>
     49 constexpr auto test_emplace_exists_imp(int) -> decltype(
     50     std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
     51   return true;
     52 }
     53 
     54 template <class, class, class...>
     55 constexpr auto test_emplace_exists_imp(long) -> bool {
     56   return false;
     57 }
     58 
     59 template <class... Args> constexpr bool emplace_exists() {
     60   return test_emplace_exists_imp<Args...>(0);
     61 }
     62 
     63 void test_emplace_sfinae() {
     64   using V =
     65       std::variant<int, TestTypes::NoCtors, InitList, InitListArg, long, long>;
     66   using IL = std::initializer_list<int>;
     67   static_assert(emplace_exists<V, InitList, IL>(), "");
     68   static_assert(!emplace_exists<V, InitList, int>(), "args don't match");
     69   static_assert(!emplace_exists<V, InitList, IL, int>(), "too many args");
     70   static_assert(emplace_exists<V, InitListArg, IL, int>(), "");
     71   static_assert(!emplace_exists<V, InitListArg, int>(), "args don't match");
     72   static_assert(!emplace_exists<V, InitListArg, IL>(), "too few args");
     73   static_assert(!emplace_exists<V, InitListArg, IL, int, int>(),
     74                 "too many args");
     75 }
     76 
     77 void test_basic() {
     78   using V = std::variant<int, InitList, InitListArg, TestTypes::NoCtors>;
     79   V v;
     80   auto& ref1 = v.emplace<InitList>({1, 2, 3});
     81   static_assert(std::is_same_v<InitList&,decltype(ref1)>, "");
     82   assert(std::get<InitList>(v).size == 3);
     83   assert(&ref1 == &std::get<InitList>(v));
     84   auto& ref2 = v.emplace<InitListArg>({1, 2, 3, 4}, 42);
     85   static_assert(std::is_same_v<InitListArg&,decltype(ref2)>, "");
     86   assert(std::get<InitListArg>(v).size == 4);
     87   assert(std::get<InitListArg>(v).value == 42);
     88   assert(&ref2 == &std::get<InitListArg>(v));
     89   auto& ref3 = v.emplace<InitList>({1});
     90   static_assert(std::is_same_v<InitList&,decltype(ref3)>, "");
     91   assert(std::get<InitList>(v).size == 1);
     92   assert(&ref3 == &std::get<InitList>(v));
     93 }
     94 
     95 int main() {
     96   test_basic();
     97   test_emplace_sfinae();
     98 }
     99