summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp0x/constexpr-ref8.C
blob: 04de9c7e04caf498a0b3f35e073948ed1950ef04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// PR c++/63885
// { dg-do compile { target c++11 } }

template<class T> struct remove_reference { typedef T type; };
template<class T> struct remove_reference<T&> { typedef T type; };
template<class T> struct remove_reference<T&&> { typedef T type; };

template<class T> struct is_lvalue_reference { static const bool value = false; };
template<class T> struct is_lvalue_reference<T&> { static const bool value = true; };

template <bool B, class U, class V> struct conditional;
template <class U, class V> struct conditional<true, U, V> { typedef U type; };
template <class U, class V> struct conditional<false, U, V> { typedef V type; };

template<typename _Tp> constexpr _Tp&&
forward(typename remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }

///////////////////////////////////////////////////////////////////////////////

template <typename C> struct member_forward
{
    typedef typename remove_reference <C>::type::type T;
    typedef typename conditional
    <
        is_lvalue_reference <C &&>::value,
        T&,
        T
    >::type type;
};

template <typename C> using member_forward_t = typename member_forward <C>::type;

///////////////////////////////////////////////////////////////////////////////

template <int  , typename  > struct __get;
template <       typename T> struct __get <0, T>
{
    constexpr static auto value (T arg)
     -> decltype ((forward <member_forward_t <T>> (arg.t)))
    {
        return     forward <member_forward_t <T>> (arg.t);
    }
};

template <int N, typename T> constexpr auto get (T && arg)
 -> decltype (__get <N, T &&>::value (forward <T> (arg)))
{
    return    __get <N, T &&>::value (forward <T> (arg));
}

///////////////////////////////////////////////////////////////////////////////

template <typename T> struct S
{
    typedef T type;
    T t;

    template <typename U> constexpr S (U && u) : t (forward <U> (u)) {}
};
static_assert (get <0> (S <int &&> (1)) == 1, ""); // g++ 4.9 passes, g++ trunk r217559 fails