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 // <variant>
     14 
     15 // template <class ...Types> class variant;
     16 
     17 // template <size_t I, class ...Args> void emplace(Args&&... args);
     18 
     19 #include <cassert>
     20 #include <string>
     21 #include <type_traits>
     22 #include <variant>
     23 
     24 #include "archetypes.hpp"
     25 #include "test_convertible.hpp"
     26 #include "test_macros.h"
     27 #include "variant_test_helpers.hpp"
     28 
     29 template <class Var, size_t I, class... Args>
     30 constexpr auto test_emplace_exists_imp(int) -> decltype(
     31     std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
     32   return true;
     33 }
     34 
     35 template <class, size_t, class...>
     36 constexpr auto test_emplace_exists_imp(long) -> bool {
     37   return false;
     38 }
     39 
     40 template <class Var, size_t I, class... Args> constexpr bool emplace_exists() {
     41   return test_emplace_exists_imp<Var, I, Args...>(0);
     42 }
     43 
     44 void test_emplace_sfinae() {
     45   {
     46     using V = std::variant<int, void *, const void *, TestTypes::NoCtors>;
     47     static_assert(emplace_exists<V, 0>(), "");
     48     static_assert(emplace_exists<V, 0, int>(), "");
     49     static_assert(!emplace_exists<V, 0, decltype(nullptr)>(),
     50                   "cannot construct");
     51     static_assert(emplace_exists<V, 1, decltype(nullptr)>(), "");
     52     static_assert(emplace_exists<V, 1, int *>(), "");
     53     static_assert(!emplace_exists<V, 1, const int *>(), "");
     54     static_assert(!emplace_exists<V, 1, int>(), "cannot construct");
     55     static_assert(emplace_exists<V, 2, const int *>(), "");
     56     static_assert(emplace_exists<V, 2, int *>(), "");
     57     static_assert(!emplace_exists<V, 3>(), "cannot construct");
     58   }
     59 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
     60   {
     61     using V = std::variant<int, int &, const int &, int &&, TestTypes::NoCtors>;
     62     static_assert(emplace_exists<V, 0>(), "");
     63     static_assert(emplace_exists<V, 0, int>(), "");
     64     static_assert(emplace_exists<V, 0, long long>(), "");
     65     static_assert(!emplace_exists<V, 0, int, int>(), "too many args");
     66     static_assert(emplace_exists<V, 1, int &>(), "");
     67     static_assert(!emplace_exists<V, 1>(), "cannot default construct ref");
     68     static_assert(!emplace_exists<V, 1, const int &>(), "cannot bind ref");
     69     static_assert(!emplace_exists<V, 1, int &&>(), "cannot bind ref");
     70     static_assert(emplace_exists<V, 2, int &>(), "");
     71     static_assert(emplace_exists<V, 2, const int &>(), "");
     72     static_assert(emplace_exists<V, 2, int &&>(), "");
     73     static_assert(!emplace_exists<V, 2, void *>(),
     74                   "not constructible from void*");
     75     static_assert(emplace_exists<V, 3, int>(), "");
     76     static_assert(!emplace_exists<V, 3, int &>(), "cannot bind ref");
     77     static_assert(!emplace_exists<V, 3, const int &>(), "cannot bind ref");
     78     static_assert(!emplace_exists<V, 3, const int &&>(), "cannot bind ref");
     79     static_assert(!emplace_exists<V, 4>(), "no ctors");
     80   }
     81 #endif
     82 }
     83 
     84 void test_basic() {
     85   {
     86     using V = std::variant<int>;
     87     V v(42);
     88     v.emplace<0>();
     89     assert(std::get<0>(v) == 0);
     90     v.emplace<0>(42);
     91     assert(std::get<0>(v) == 42);
     92   }
     93   {
     94     using V =
     95         std::variant<int, long, const void *, TestTypes::NoCtors, std::string>;
     96     const int x = 100;
     97     V v(std::in_place_index<0>, -1);
     98     // default emplace a value
     99     v.emplace<1>();
    100     assert(std::get<1>(v) == 0);
    101     v.emplace<2>(&x);
    102     assert(std::get<2>(v) == &x);
    103     // emplace with multiple args
    104     v.emplace<4>(3, 'a');
    105     assert(std::get<4>(v) == "aaa");
    106   }
    107 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
    108   {
    109     using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
    110                            std::string>;
    111     const int x = 100;
    112     int y = 42;
    113     int z = 43;
    114     V v(std::in_place_index<0>, -1);
    115     // default emplace a value
    116     v.emplace<1>();
    117     assert(std::get<1>(v) == 0);
    118     // emplace a reference
    119     v.emplace<2>(x);
    120     assert(&std::get<2>(v) == &x);
    121     // emplace an rvalue reference
    122     v.emplace<3>(std::move(y));
    123     assert(&std::get<3>(v) == &y);
    124     // re-emplace a new reference over the active member
    125     v.emplace<3>(std::move(z));
    126     assert(&std::get<3>(v) == &z);
    127     // emplace with multiple args
    128     v.emplace<5>(3, 'a');
    129     assert(std::get<5>(v) == "aaa");
    130   }
    131 #endif
    132 }
    133 
    134 int main() {
    135   test_basic();
    136   test_emplace_sfinae();
    137 }
    138