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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
// PR c++/96926
// { dg-do compile { target c++11 } }
namespace std
{
template<typename _Tp, _Tp __v>
struct integral_constant
{
static constexpr _Tp value = __v;
typedef integral_constant<_Tp, __v> type;
};
template<typename _Tp, _Tp __v>
constexpr _Tp integral_constant<_Tp, __v>::value;
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
template<bool __v>
using bool_constant = integral_constant<bool, __v>;
template<bool, typename, typename>
struct conditional;
template<typename...>
struct __and_;
template<>
struct __and_<>
: public true_type
{ };
template<typename _B1>
struct __and_<_B1>
: public _B1
{ };
template<typename _B1, typename _B2>
struct __and_<_B1, _B2>
: public conditional<_B1::value, _B2, _B1>::type
{ };
template<typename _B1, typename _B2, typename _B3, typename... _Bn>
struct __and_<_B1, _B2, _B3, _Bn...>
: public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type
{ };
template<typename _Tp, typename... _Args>
struct is_constructible
: public bool_constant<__is_constructible(_Tp, _Args...)>
{
};
template<bool, typename _Tp = void>
struct enable_if
{ };
template<typename _Tp>
struct enable_if<true, _Tp>
{ typedef _Tp type; };
template<bool _Cond, typename _Tp = void>
using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
template<bool _Cond, typename _Iftrue, typename _Iffalse>
struct conditional
{ typedef _Iftrue type; };
template<typename _Iftrue, typename _Iffalse>
struct conditional<false, _Iftrue, _Iffalse>
{ typedef _Iffalse type; };
template<bool, typename... _Types>
struct _TupleConstraints
{
template<typename... _UTypes>
static constexpr bool __is_implicitly_constructible()
{
// is_constructible is incomplete here, but only when
// it is also instantiated in __is_explicitly_constructible
return __and_<is_constructible<_Types, _UTypes>...,
true_type
>::value;
}
template<typename... _UTypes>
static constexpr bool __is_explicitly_constructible()
{
#if FIX
return false;
#else
return __and_<is_constructible<_Types, _UTypes>...,
false_type
>::value;
#endif
}
};
template<typename... _Elements>
class tuple
{
template<bool _Cond>
using _TCC = _TupleConstraints<_Cond, _Elements...>;
template<bool _Cond, typename... _Args>
using _ImplicitCtor = __enable_if_t<
_TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
bool>;
template<bool _Cond, typename... _Args>
using _ExplicitCtor = __enable_if_t<
_TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
bool>;
public:
template<bool _NotEmpty = true,
_ImplicitCtor<_NotEmpty, const _Elements&...> = true>
constexpr
tuple(const _Elements&... __elements)
{ }
template<bool _NotEmpty = true,
_ExplicitCtor<_NotEmpty, const _Elements&...> = false>
explicit constexpr
tuple(const _Elements&... __elements)
{ }
};
}
// first example
template <typename SessionT>
struct SomeQuery {
SessionT& session_;
SomeQuery(SessionT& session) : session_(session) {}
};
template <typename SessionT>
struct Handler {
std::tuple<SomeQuery<SessionT>> queries_;
Handler(SessionT& session) : queries_(session) {}
};
struct Session {
Handler<Session> handler_;
Session() : handler_{*this} {}
};
int main() {
Session session;
}
static_assert(std::is_constructible<SomeQuery<Session>, const SomeQuery<Session>&>::value, "");
// second example
template <typename T>
class DependsOnT
{
public:
DependsOnT(T&) {}
};
class Test
{
public:
Test() : test_{*this} {}
private:
std::tuple<DependsOnT<Test>> test_;
};
static_assert(std::is_constructible<DependsOnT<Test>, const DependsOnT<Test>&>::value, "");
|