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