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 struct AnyConstructible { template <typename T> AnyConstructible(T&&) {} };
     41 struct NoConstructible { NoConstructible() = delete; };
     42 
     43 void test_T_ctor_noexcept() {
     44   {
     45     using V = std::variant<Dummy, NoThrowT>;
     46     static_assert(std::is_nothrow_constructible<V, int>::value, "");
     47   }
     48   {
     49     using V = std::variant<Dummy, ThrowsT>;
     50     static_assert(!std::is_nothrow_constructible<V, int>::value, "");
     51   }
     52 }
     53 
     54 void test_T_ctor_sfinae() {
     55   {
     56     using V = std::variant<long, unsigned>;
     57     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
     58   }
     59   {
     60     using V = std::variant<std::string, std::string>;
     61     static_assert(!std::is_constructible<V, const char *>::value, "ambiguous");
     62   }
     63   {
     64     using V = std::variant<std::string, void *>;
     65     static_assert(!std::is_constructible<V, int>::value,
     66                   "no matching constructor");
     67   }
     68   {
     69     using V = std::variant<AnyConstructible, NoConstructible>;
     70     static_assert(
     71         !std::is_constructible<V, std::in_place_type_t<NoConstructible>>::value,
     72         "no matching constructor");
     73     static_assert(!std::is_constructible<V, std::in_place_index_t<1>>::value,
     74                   "no matching constructor");
     75   }
     76 
     77 
     78 
     79 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
     80   {
     81     using V = std::variant<int, int &&>;
     82     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
     83   }
     84   {
     85     using V = std::variant<int, const int &>;
     86     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
     87   }
     88 #endif
     89 }
     90 
     91 void test_T_ctor_basic() {
     92   {
     93     constexpr std::variant<int> v(42);
     94     static_assert(v.index() == 0, "");
     95     static_assert(std::get<0>(v) == 42, "");
     96   }
     97   {
     98     constexpr std::variant<int, long> v(42l);
     99     static_assert(v.index() == 1, "");
    100     static_assert(std::get<1>(v) == 42, "");
    101   }
    102 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
    103   {
    104     using V = std::variant<const int &, int &&, long>;
    105     static_assert(std::is_convertible<int &, V>::value, "must be implicit");
    106     int x = 42;
    107     V v(x);
    108     assert(v.index() == 0);
    109     assert(&std::get<0>(v) == &x);
    110   }
    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(std::move(x));
    116     assert(v.index() == 1);
    117     assert(&std::get<1>(v) == &x);
    118   }
    119 #endif
    120 }
    121 
    122 int main() {
    123   test_T_ctor_basic();
    124   test_T_ctor_noexcept();
    125   test_T_ctor_sfinae();
    126 }
    127