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 // variant(variant&&) noexcept(see below);
     18 
     19 #include <type_traits>
     20 #include <variant>
     21 
     22 #include "test_macros.h"
     23 
     24 struct NTMove {
     25   constexpr NTMove(int v) : value(v) {}
     26   NTMove(const NTMove &) = delete;
     27   NTMove(NTMove &&that) : value(that.value) { that.value = -1; }
     28   int value;
     29 };
     30 
     31 static_assert(!std::is_trivially_move_constructible<NTMove>::value, "");
     32 static_assert(std::is_move_constructible<NTMove>::value, "");
     33 
     34 struct TMove {
     35   constexpr TMove(int v) : value(v) {}
     36   TMove(const TMove &) = delete;
     37   TMove(TMove &&) = default;
     38   int value;
     39 };
     40 
     41 static_assert(std::is_trivially_move_constructible<TMove>::value, "");
     42 
     43 struct TMoveNTCopy {
     44   constexpr TMoveNTCopy(int v) : value(v) {}
     45   TMoveNTCopy(const TMoveNTCopy& that) : value(that.value) {}
     46   TMoveNTCopy(TMoveNTCopy&&) = default;
     47   int value;
     48 };
     49 
     50 static_assert(std::is_trivially_move_constructible<TMoveNTCopy>::value, "");
     51 
     52 void test_move_ctor_sfinae() {
     53   {
     54     using V = std::variant<int, long>;
     55     static_assert(std::is_trivially_move_constructible<V>::value, "");
     56   }
     57   {
     58     using V = std::variant<int, NTMove>;
     59     static_assert(!std::is_trivially_move_constructible<V>::value, "");
     60     static_assert(std::is_move_constructible<V>::value, "");
     61   }
     62   {
     63     using V = std::variant<int, TMove>;
     64     static_assert(std::is_trivially_move_constructible<V>::value, "");
     65   }
     66   {
     67     using V = std::variant<int, TMoveNTCopy>;
     68     static_assert(std::is_trivially_move_constructible<V>::value, "");
     69   }
     70 }
     71 
     72 template <typename T>
     73 struct Result { size_t index; T value; };
     74 
     75 void test_move_ctor_basic() {
     76   {
     77     struct {
     78       constexpr Result<int> operator()() const {
     79         std::variant<int> v(std::in_place_index<0>, 42);
     80         std::variant<int> v2 = std::move(v);
     81         return {v2.index(), std::get<0>(std::move(v2))};
     82       }
     83     } test;
     84     constexpr auto result = test();
     85     static_assert(result.index == 0, "");
     86     static_assert(result.value == 42, "");
     87   }
     88   {
     89     struct {
     90       constexpr Result<long> operator()() const {
     91         std::variant<int, long> v(std::in_place_index<1>, 42);
     92         std::variant<int, long> v2 = std::move(v);
     93         return {v2.index(), std::get<1>(std::move(v2))};
     94       }
     95     } test;
     96     constexpr auto result = test();
     97     static_assert(result.index == 1, "");
     98     static_assert(result.value == 42, "");
     99   }
    100   {
    101     struct {
    102       constexpr Result<TMove> operator()() const {
    103         std::variant<TMove> v(std::in_place_index<0>, 42);
    104         std::variant<TMove> v2(std::move(v));
    105         return {v2.index(), std::get<0>(std::move(v2))};
    106       }
    107     } test;
    108     constexpr auto result = test();
    109     static_assert(result.index == 0, "");
    110     static_assert(result.value.value == 42, "");
    111   }
    112   {
    113     struct {
    114       constexpr Result<TMove> operator()() const {
    115         std::variant<int, TMove> v(std::in_place_index<1>, 42);
    116         std::variant<int, TMove> v2(std::move(v));
    117         return {v2.index(), std::get<1>(std::move(v2))};
    118       }
    119     } test;
    120     constexpr auto result = test();
    121     static_assert(result.index == 1, "");
    122     static_assert(result.value.value == 42, "");
    123   }
    124   {
    125     struct {
    126       constexpr Result<TMoveNTCopy> operator()() const {
    127         std::variant<TMoveNTCopy> v(std::in_place_index<0>, 42);
    128         std::variant<TMoveNTCopy> v2(std::move(v));
    129         return {v2.index(), std::get<0>(std::move(v2))};
    130       }
    131     } test;
    132     constexpr auto result = test();
    133     static_assert(result.index == 0, "");
    134     static_assert(result.value.value == 42, "");
    135   }
    136   {
    137     struct {
    138       constexpr Result<TMoveNTCopy> operator()() const {
    139         std::variant<int, TMoveNTCopy> v(std::in_place_index<1>, 42);
    140         std::variant<int, TMoveNTCopy> v2(std::move(v));
    141         return {v2.index(), std::get<1>(std::move(v2))};
    142       }
    143     } test;
    144     constexpr auto result = test();
    145     static_assert(result.index == 1, "");
    146     static_assert(result.value.value == 42, "");
    147   }
    148 }
    149 
    150 int main() {
    151   test_move_ctor_basic();
    152   test_move_ctor_sfinae();
    153 }
    154