libcxx

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

PR31384.pass.cpp (2233B)


      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 // template <class TupleLike> tuple(TupleLike&&); // libc++ extension
     16 
     17 // See llvm.org/PR31384
     18 #include <tuple>
     19 #include <cassert>
     20 
     21 int count = 0;
     22 
     23 struct Explicit {
     24   Explicit() = default;
     25   explicit Explicit(int) {}
     26 };
     27 
     28 struct Implicit {
     29   Implicit() = default;
     30   Implicit(int) {}
     31 };
     32 
     33 template<class T>
     34 struct Derived : std::tuple<T> {
     35   using std::tuple<T>::tuple;
     36   template<class U>
     37   operator std::tuple<U>() && { ++count; return {}; }
     38 };
     39 
     40 
     41 template<class T>
     42 struct ExplicitDerived : std::tuple<T> {
     43   using std::tuple<T>::tuple;
     44   template<class U>
     45   explicit operator std::tuple<U>() && { ++count; return {}; }
     46 };
     47 
     48 int main() {
     49   {
     50     std::tuple<Explicit> foo = Derived<int>{42}; ((void)foo);
     51     assert(count == 1);
     52     std::tuple<Explicit> bar(Derived<int>{42}); ((void)bar);
     53     assert(count == 2);
     54   }
     55   count = 0;
     56   {
     57     std::tuple<Implicit> foo = Derived<int>{42}; ((void)foo);
     58     assert(count == 1);
     59     std::tuple<Implicit> bar(Derived<int>{42}); ((void)bar);
     60     assert(count == 2);
     61   }
     62   count = 0;
     63   {
     64     static_assert(!std::is_convertible<
     65         ExplicitDerived<int>, std::tuple<Explicit>>::value, "");
     66     std::tuple<Explicit> bar(ExplicitDerived<int>{42}); ((void)bar);
     67     assert(count == 1);
     68   }
     69   count = 0;
     70   {
     71     // FIXME: Libc++ incorrectly rejects this code.
     72 #ifndef _LIBCPP_VERSION
     73     std::tuple<Implicit> foo = ExplicitDerived<int>{42}; ((void)foo);
     74     static_assert(std::is_convertible<
     75         ExplicitDerived<int>, std::tuple<Implicit>>::value,
     76         "correct STLs accept this");
     77 #else
     78     static_assert(!std::is_convertible<
     79         ExplicitDerived<int>, std::tuple<Implicit>>::value,
     80         "libc++ incorrectly rejects this");
     81 #endif
     82     assert(count == 0);
     83     std::tuple<Implicit> bar(ExplicitDerived<int>{42}); ((void)bar);
     84     assert(count == 1);
     85   }
     86   count = 0;
     87 
     88 }