1 // PR c++/63885
2 // { dg-do compile { target c++11 } }
3 
4 template<class T> struct remove_reference { typedef T type; };
5 template<class T> struct remove_reference<T&> { typedef T type; };
6 template<class T> struct remove_reference<T&&> { typedef T type; };
7 
8 template<class T> struct is_lvalue_reference { static const bool value = false; };
9 template<class T> struct is_lvalue_reference<T&> { static const bool value = true; };
10 
11 template <bool B, class U, class V> struct conditional;
12 template <class U, class V> struct conditional<true, U, V> { typedef U type; };
13 template <class U, class V> struct conditional<false, U, V> { typedef V type; };
14 
15 template<typename _Tp> constexpr _Tp&&
16 forward(typename remove_reference<_Tp>::type& __t) noexcept
17 { return static_cast<_Tp&&>(__t); }
18 
19 ///////////////////////////////////////////////////////////////////////////////
20 
21 template <typename C> struct member_forward
22 {
23     typedef typename remove_reference <C>::type::type T;
24     typedef typename conditional
25     <
26         is_lvalue_reference <C &&>::value,
27         T&,
28         T
29     >::type type;
30 };
31 
32 template <typename C> using member_forward_t = typename member_forward <C>::type;
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 template <int  , typename  > struct __get;
37 template <       typename T> struct __get <0, T>
38 {
39     constexpr static auto value (T arg)
40      -> decltype ((forward <member_forward_t <T>> (arg.t)))
41     {
42         return     forward <member_forward_t <T>> (arg.t);
43     }
44 };
45 
46 template <int N, typename T> constexpr auto get (T && arg)
47  -> decltype (__get <N, T &&>::value (forward <T> (arg)))
48 {
49     return    __get <N, T &&>::value (forward <T> (arg));
50 }
51 
52 ///////////////////////////////////////////////////////////////////////////////
53 
54 template <typename T> struct S
55 {
56     typedef T type;
57     T t;
58 
59     template <typename U> constexpr S (U && u) : t (forward <U> (u)) {}
60 };
61 static_assert (get <0> (S <int &&> (1)) == 1, ""); // g++ 4.9 passes, g++ trunk r217559 fails
62