libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

emplace_index_args.pass.cpp (6005B)


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