libcxx

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

enable_reduced_arity_initialization_extension.pass.cpp (3732B)


      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // <tuple>
     11 
     12 // template <class... Types> class tuple;
     13 
     14 // template <class... UTypes>
     15 //   explicit tuple(UTypes&&... u);
     16 
     17 // UNSUPPORTED: c++98, c++03
     18 
     19 // MODULES_DEFINES: _LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION
     20 #define _LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION
     21 #include <tuple>
     22 #include <cassert>
     23 #include <type_traits>
     24 #include <string>
     25 #include <system_error>
     26 
     27 #include "test_macros.h"
     28 #include "test_convertible.hpp"
     29 #include "MoveOnly.h"
     30 
     31 
     32 struct NoDefault { NoDefault() = delete; };
     33 
     34 
     35 // Make sure the _Up... constructor SFINAEs out when the types that
     36 // are not explicitly initialized are not all default constructible.
     37 // Otherwise, std::is_constructible would return true but instantiating
     38 // the constructor would fail.
     39 void test_default_constructible_extension_sfinae()
     40 {
     41     typedef MoveOnly MO;
     42     typedef NoDefault ND;
     43     {
     44         typedef std::tuple<MO, ND> Tuple;
     45         static_assert(!std::is_constructible<Tuple, MO>::value, "");
     46         static_assert(std::is_constructible<Tuple, MO, ND>::value, "");
     47         static_assert(test_convertible<Tuple, MO, ND>(), "");
     48     }
     49     {
     50         typedef std::tuple<MO, MO, ND> Tuple;
     51         static_assert(!std::is_constructible<Tuple, MO, MO>::value, "");
     52         static_assert(std::is_constructible<Tuple, MO, MO, ND>::value, "");
     53         static_assert(test_convertible<Tuple, MO, MO, ND>(), "");
     54     }
     55     {
     56         // Same idea as above but with a nested tuple type.
     57         typedef std::tuple<MO, ND> Tuple;
     58         typedef std::tuple<MO, Tuple, MO, MO> NestedTuple;
     59 
     60         static_assert(!std::is_constructible<
     61             NestedTuple, MO, MO, MO, MO>::value, "");
     62         static_assert(std::is_constructible<
     63             NestedTuple, MO, Tuple, MO, MO>::value, "");
     64     }
     65     {
     66         typedef std::tuple<MO, int> Tuple;
     67         typedef std::tuple<MO, Tuple, MO, MO> NestedTuple;
     68 
     69         static_assert(std::is_constructible<
     70             NestedTuple, MO, MO, MO, MO>::value, "");
     71         static_assert(test_convertible<
     72             NestedTuple, MO, MO, MO, MO>(), "");
     73 
     74         static_assert(std::is_constructible<
     75             NestedTuple, MO, Tuple, MO, MO>::value, "");
     76         static_assert(test_convertible<
     77             NestedTuple, MO, Tuple, MO, MO>(), "");
     78     }
     79 }
     80 
     81 std::tuple<std::string, int, std::error_code> doc_example() {
     82       return {"hello world", 42};
     83 }
     84 
     85 // Test that the example given in UsingLibcxx.rst actually works.
     86 void test_example_from_docs() {
     87   auto tup = doc_example();
     88   assert(std::get<0>(tup) == "hello world");
     89   assert(std::get<1>(tup) == 42);
     90   assert(std::get<2>(tup) == std::error_code{});
     91 }
     92 
     93 int main()
     94 {
     95 
     96     {
     97         using E = MoveOnly;
     98         using Tup = std::tuple<E, E, E>;
     99         static_assert(test_convertible<Tup, E, E, E>(), "");
    100 
    101         Tup t = {E(0), E(1)};
    102         static_assert(test_convertible<Tup, E, E>(), "");
    103         assert(std::get<0>(t) == 0);
    104         assert(std::get<1>(t) == 1);
    105         assert(std::get<2>(t) == MoveOnly());
    106 
    107         Tup t2 = {E(0)};
    108         static_assert(test_convertible<Tup, E>(), "");
    109         assert(std::get<0>(t) == 0);
    110         assert(std::get<1>(t) == E());
    111         assert(std::get<2>(t) == E());
    112     }
    113     // Check that SFINAE is properly applied with the default reduced arity
    114     // constructor extensions.
    115     test_default_constructible_extension_sfinae();
    116     test_example_from_docs();
    117 }