Home | History | Annotate | Download | only in variant.ctor
      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 // XFAIL: availability=macosx10.13
     16 // XFAIL: availability=macosx10.12
     17 // XFAIL: availability=macosx10.11
     18 // XFAIL: availability=macosx10.10
     19 // XFAIL: availability=macosx10.9
     20 // XFAIL: availability=macosx10.8
     21 // XFAIL: availability=macosx10.7
     22 
     23 // template <class ...Types> class variant;
     24 
     25 // template <class T> constexpr variant(T&&) noexcept(see below);
     26 
     27 #include <cassert>
     28 #include <string>
     29 #include <type_traits>
     30 #include <variant>
     31 
     32 #include "test_convertible.hpp"
     33 #include "test_macros.h"
     34 #include "variant_test_helpers.hpp"
     35 
     36 struct Dummy {
     37   Dummy() = default;
     38 };
     39 
     40 struct ThrowsT {
     41   ThrowsT(int) noexcept(false) {}
     42 };
     43 
     44 struct NoThrowT {
     45   NoThrowT(int) noexcept(true) {}
     46 };
     47 
     48 struct AnyConstructible { template <typename T> AnyConstructible(T&&) {} };
     49 struct NoConstructible { NoConstructible() = delete; };
     50 
     51 void test_T_ctor_noexcept() {
     52   {
     53     using V = std::variant<Dummy, NoThrowT>;
     54     static_assert(std::is_nothrow_constructible<V, int>::value, "");
     55   }
     56   {
     57     using V = std::variant<Dummy, ThrowsT>;
     58     static_assert(!std::is_nothrow_constructible<V, int>::value, "");
     59   }
     60 }
     61 
     62 void test_T_ctor_sfinae() {
     63   {
     64     using V = std::variant<long, unsigned>;
     65     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
     66   }
     67   {
     68     using V = std::variant<std::string, std::string>;
     69     static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
     70   }
     71   {
     72     using V = std::variant<std::string, void *>;
     73     static_assert(!std::is_constructible<V, int>::value,
     74                   "no matching constructor");
     75   }
     76   {
     77     using V = std::variant<AnyConstructible, NoConstructible>;
     78     static_assert(
     79         !std::is_constructible<V, std::in_place_type_t<NoConstructible>>::value,
     80         "no matching constructor");
     81     static_assert(!std::is_constructible<V, std::in_place_index_t<1>>::value,
     82                   "no matching constructor");
     83   }
     84 
     85 
     86 
     87 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
     88   {
     89     using V = std::variant<int, int &&>;
     90     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
     91   }
     92   {
     93     using V = std::variant<int, const int &>;
     94     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
     95   }
     96 #endif
     97 }
     98 
     99 void test_T_ctor_basic() {
    100   {
    101     constexpr std::variant<int> v(42);
    102     static_assert(v.index() == 0, "");
    103     static_assert(std::get<0>(v) == 42, "");
    104   }
    105   {
    106     constexpr std::variant<int, long> v(42l);
    107     static_assert(v.index() == 1, "");
    108     static_assert(std::get<1>(v) == 42, "");
    109   }
    110 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
    111   {
    112     using V = std::variant<const int &, int &&, long>;
    113     static_assert(std::is_convertible<int &, V>::value, "must be implicit");
    114     int x = 42;
    115     V v(x);
    116     assert(v.index() == 0);
    117     assert(&std::get<0>(v) == &x);
    118   }
    119   {
    120     using V = std::variant<const int &, int &&, long>;
    121     static_assert(std::is_convertible<int, V>::value, "must be implicit");
    122     int x = 42;
    123     V v(std::move(x));
    124     assert(v.index() == 1);
    125     assert(&std::get<1>(v) == &x);
    126   }
    127 #endif
    128 }
    129 
    130 int main() {
    131   test_T_ctor_basic();
    132   test_T_ctor_noexcept();
    133   test_T_ctor_sfinae();
    134 }
    135