libcxx

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

PR20855_tuple_ref_binding_diagnostics.pass.cpp (4224B)


      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
     12 
     13 // <tuple>
     14 
     15 // See llvm.org/PR20855
     16 
     17 #include <functional>
     18 #include <tuple>
     19 #include <string>
     20 #include <cassert>
     21 #include "test_macros.h"
     22 
     23 #if TEST_HAS_BUILTIN_IDENTIFIER(__reference_binds_to_temporary)
     24 # define ASSERT_REFERENCE_BINDS_TEMPORARY(...) static_assert(__reference_binds_to_temporary(__VA_ARGS__), "")
     25 # define ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(...) static_assert(!__reference_binds_to_temporary(__VA_ARGS__), "")
     26 #else
     27 # define ASSERT_REFERENCE_BINDS_TEMPORARY(...) static_assert(true, "")
     28 # define ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(...) static_assert(true, "")
     29 #endif
     30 
     31 template <class Tp>
     32 struct ConvertsTo {
     33   using RawTp = typename std::remove_cv< typename std::remove_reference<Tp>::type>::type;
     34 
     35   operator Tp() const {
     36     return static_cast<Tp>(value);
     37   }
     38 
     39   mutable RawTp value;
     40 };
     41 
     42 struct Base {};
     43 struct Derived : Base {};
     44 
     45 
     46 static_assert(std::is_same<decltype("abc"), decltype(("abc"))>::value, "");
     47 ASSERT_REFERENCE_BINDS_TEMPORARY(std::string const&, decltype("abc"));
     48 ASSERT_REFERENCE_BINDS_TEMPORARY(std::string const&, decltype(("abc")));
     49 ASSERT_REFERENCE_BINDS_TEMPORARY(std::string const&, const char*&&);
     50 
     51 ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(int&, const ConvertsTo<int&>&);
     52 ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(const int&, ConvertsTo<int&>&);
     53 ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(Base&, Derived&);
     54 
     55 
     56 static_assert(std::is_constructible<int&, std::reference_wrapper<int>>::value, "");
     57 static_assert(std::is_constructible<int const&, std::reference_wrapper<int>>::value, "");
     58 
     59 template <class T> struct CannotDeduce {
     60  using type = T;
     61 };
     62 
     63 template <class ...Args>
     64 void F(typename CannotDeduce<std::tuple<Args...>>::type const&) {}
     65 
     66 void compile_tests() {
     67   {
     68     F<int, int const&>(std::make_tuple(42, 42));
     69   }
     70   {
     71     F<int, int const&>(std::make_tuple<const int&, const int&>(42, 42));
     72     std::tuple<int, int const&> t(std::make_tuple<const int&, const int&>(42, 42));
     73   }
     74   {
     75     auto fn = &F<int, std::string const&>;
     76     fn(std::tuple<int, std::string const&>(42, std::string("a")));
     77     fn(std::make_tuple(42, std::string("a")));
     78   }
     79   {
     80     Derived d;
     81     std::tuple<Base&, Base const&> t(d, d);
     82   }
     83   {
     84     ConvertsTo<int&> ct;
     85     std::tuple<int, int&> t(42, ct);
     86   }
     87 }
     88 
     89 void allocator_tests() {
     90     std::allocator<void> alloc;
     91     int x = 42;
     92     {
     93         std::tuple<int&> t(std::ref(x));
     94         assert(&std::get<0>(t) == &x);
     95         std::tuple<int&> t1(std::allocator_arg, alloc, std::ref(x));
     96         assert(&std::get<0>(t1) == &x);
     97     }
     98     {
     99         auto r = std::ref(x);
    100         auto const& cr = r;
    101         std::tuple<int&> t(r);
    102         assert(&std::get<0>(t) == &x);
    103         std::tuple<int&> t1(cr);
    104         assert(&std::get<0>(t1) == &x);
    105         std::tuple<int&> t2(std::allocator_arg, alloc, r);
    106         assert(&std::get<0>(t2) == &x);
    107         std::tuple<int&> t3(std::allocator_arg, alloc, cr);
    108         assert(&std::get<0>(t3) == &x);
    109     }
    110     {
    111         std::tuple<int const&> t(std::ref(x));
    112         assert(&std::get<0>(t) == &x);
    113         std::tuple<int const&> t2(std::cref(x));
    114         assert(&std::get<0>(t2) == &x);
    115         std::tuple<int const&> t3(std::allocator_arg, alloc, std::ref(x));
    116         assert(&std::get<0>(t3) == &x);
    117         std::tuple<int const&> t4(std::allocator_arg, alloc, std::cref(x));
    118         assert(&std::get<0>(t4) == &x);
    119     }
    120     {
    121         auto r = std::ref(x);
    122         auto cr = std::cref(x);
    123         std::tuple<int const&> t(r);
    124         assert(&std::get<0>(t) == &x);
    125         std::tuple<int const&> t2(cr);
    126         assert(&std::get<0>(t2) == &x);
    127         std::tuple<int const&> t3(std::allocator_arg, alloc, r);
    128         assert(&std::get<0>(t3) == &x);
    129         std::tuple<int const&> t4(std::allocator_arg, alloc, cr);
    130         assert(&std::get<0>(t4) == &x);
    131     }
    132 }
    133 
    134 
    135 int main() {
    136   compile_tests();
    137   allocator_tests();
    138 }