Implement std::meta::is_{{,trivially_,nothrow_}constructible,{,trivially_}invocable}_type.

This commit is contained in:
Jakub Jelinek
2025-10-14 19:42:45 +02:00
committed by Marek Polacek
parent 1adfc2ff48
commit e1c0c5766c
8 changed files with 1607 additions and 1 deletions

View File

@@ -1442,6 +1442,10 @@ cxx_pretty_printer::simple_type_specifier (tree t)
pp_cxx_trait (this, t);
break;
case META_TYPE:
pp_cxx_ws_string (this, "std::meta::info");
break;
default:
c_pretty_printer::simple_type_specifier (t);
break;
@@ -1938,6 +1942,7 @@ cxx_pretty_printer::type_id (tree t)
case NULLPTR_TYPE:
case TEMPLATE_ID_EXPR:
case OFFSET_TYPE:
case META_TYPE:
pp_cxx_type_specifier_seq (this, t);
if (TYPE_PTRMEM_P (t))
abstract_declarator (t);

View File

@@ -262,6 +262,263 @@ get_info (const constexpr_ctx *ctx, tree call, int n, bool *non_constant_p,
return info;
}
/* Helper function for get_info_vec, called through cp_walk_tree. */
static tree
replace_parm_r (tree *tp, int *walk_subtrees, void *data)
{
tree *p = (tree *) data;
if (*tp == p[0])
*tp = p[1];
else if (TYPE_P (*tp))
*walk_subtrees = 0;
return NULL_TREE;
}
/* Extract the N-th reflection_range argument from a metafunction call CALL
and return it as TREE_VEC. */
static tree
get_info_vec (location_t loc, const constexpr_ctx *ctx, tree call, int n,
bool *non_constant_p, bool *overflow_p, tree *jump_target)
{
gcc_checking_assert (call_expr_nargs (call) > n);
tree arg = get_nth_callarg (call, n);
tree parm = DECL_ARGUMENTS (cp_get_callee_fndecl_nofold (call));
for (int i = 0; i < n; ++i)
parm = DECL_CHAIN (parm);
tree type = TREE_TYPE (arg);
gcc_checking_assert (TYPE_REF_P (type));
arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue, non_constant_p,
overflow_p, jump_target);
fail_ret:
if (*jump_target)
return NULL_TREE;
if (*non_constant_p)
return call;
tree map[2] = { parm, arg };
/* To speed things up, check
if constexpr (std::ranges::contiguous_range <_R>). */
tree ranges_ns = lookup_qualified_name (std_node, "ranges");
if (TREE_CODE (ranges_ns) != NAMESPACE_DECL)
{
error_at (loc, "%<std::ranges%> is not a namespace");
*non_constant_p = true;
return call;
}
tree contiguous_range
= lookup_qualified_name (ranges_ns, "contiguous_range");
if (TREE_CODE (contiguous_range) != TEMPLATE_DECL
|| !concept_definition_p (contiguous_range))
contiguous_range = NULL_TREE;
else
{
tree args = make_tree_vec (1);
TREE_VEC_ELT (args, 0) = TREE_TYPE (type);
contiguous_range = build2_loc (loc, TEMPLATE_ID_EXPR, boolean_type_node,
contiguous_range, args);
if (!integer_nonzerop (maybe_constant_value (contiguous_range)))
contiguous_range = NULL_TREE;
}
tree p = convert_from_reference (parm);
auto obj_call = [=, &map] (tree obj, tsubst_flags_t complain) {
releasing_vec args;
vec_safe_push (args, p);
tree call = finish_call_expr (obj, &args, true, false, complain);
if (call == error_mark_node)
return call;
cp_walk_tree (&call, replace_parm_r, map, NULL);
if (complain != tf_none)
return call;
call = cxx_eval_constant_expression (ctx, call, vc_prvalue, non_constant_p,
overflow_p, jump_target);
if (*jump_target || *non_constant_p)
return NULL_TREE;
return call;
};
/* If true, call std::ranges::data (p) and std::ranges::size (p)
and if that works out and what the former returns can be handled,
grab the elements from the initializer of the decl pointed by the
first expression. p has to be convert_from_reference (PARM_DECL)
rather than its value, otherwise it is not considered lvalue. */
if (contiguous_range)
{
tree data = lookup_qualified_name (ranges_ns, "data");
tree size = lookup_qualified_name (ranges_ns, "size");
if (TREE_CODE (data) != VAR_DECL || TREE_CODE (size) != VAR_DECL)
goto non_contiguous;
data = obj_call (data, tf_none);
if (error_operand_p (data))
goto non_contiguous;
if (data == NULL_TREE)
goto fail_ret;
size = obj_call (size, tf_none);
if (error_operand_p (size))
goto non_contiguous;
if (size == NULL_TREE)
goto fail_ret;
if (!tree_fits_uhwi_p (size) || tree_to_uhwi (size) > INT_MAX)
goto non_contiguous;
if (integer_zerop (size))
return make_tree_vec (0);
STRIP_NOPS (data);
if (TREE_CODE (data) != ADDR_EXPR)
goto non_contiguous;
data = TREE_OPERAND (data, 0);
unsigned HOST_WIDE_INT minidx = 0;
if (TREE_CODE (data) == ARRAY_REF
&& tree_fits_uhwi_p (TREE_OPERAND (data, 1)))
{
minidx = tree_to_uhwi (TREE_OPERAND (data, 1));
data = TREE_OPERAND (data, 0);
}
if (TREE_CODE (data) != VAR_DECL)
goto non_contiguous;
data = cxx_eval_constant_expression (ctx, data, vc_prvalue,
non_constant_p, overflow_p,
jump_target);
if (*jump_target)
return NULL_TREE;
if (*non_constant_p)
return call;
if (TREE_CODE (data) != CONSTRUCTOR
|| TREE_CODE (TREE_TYPE (data)) != ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (TREE_TYPE (data))) != META_TYPE)
goto non_contiguous;
unsigned sz = tree_to_uhwi (size), i;
unsigned HOST_WIDE_INT j = 0;
tree ret = make_tree_vec (sz);
tree null = get_null_reflection ();
for (i = 0; i < sz; ++i)
TREE_VEC_ELT (ret, i) = null;
tree field, value;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (data), i, field, value)
if (field == NULL_TREE)
{
if (j >= minidx && j - minidx < sz)
TREE_VEC_ELT (ret, j - minidx) = value;
++j;
}
else if (TREE_CODE (field) == RANGE_EXPR)
{
tree lo = TREE_OPERAND (field, 0);
tree hi = TREE_OPERAND (field, 1);
if (!tree_fits_uhwi_p (lo) || !tree_fits_uhwi_p (hi))
goto non_contiguous;
unsigned HOST_WIDE_INT m = tree_to_uhwi (hi);
for (j = tree_to_uhwi (lo); j < m; ++j)
if (j >= minidx && j - minidx < sz)
TREE_VEC_ELT (ret, j - minidx) = value;
}
else if (tree_fits_uhwi_p (field))
{
j = tree_to_uhwi (field);
if (j >= minidx && j - minidx < sz)
TREE_VEC_ELT (ret, j - minidx) = value;
++j;
}
else
goto non_contiguous;
return ret;
}
non_contiguous:
/* Otherwise, do it the slower way. Initialize two temporaries,
one to std::ranges::base (p) and another to std::ranges::end (p)
and use a loop. */
tree begin = lookup_qualified_name (ranges_ns, "begin");
tree end = lookup_qualified_name (ranges_ns, "end");
if (TREE_CODE (begin) != VAR_DECL || TREE_CODE (end) != VAR_DECL)
{
error_at (loc, "missing %<std::ranges::begin%> or %<std::ranges::end%>");
*non_constant_p = true;
return call;
}
begin = obj_call (begin, tf_warning_or_error);
if (error_operand_p (begin))
{
*non_constant_p = true;
return call;
}
end = obj_call (end, tf_warning_or_error);
if (error_operand_p (end))
{
*non_constant_p = true;
return call;
}
if (!CLASS_TYPE_P (TREE_TYPE (begin)) && !POINTER_TYPE_P (TREE_TYPE (begin)))
{
error_at (loc, "incorrect type %qT of %<std::ranges::begin(arg)%>",
TREE_TYPE (begin));
*non_constant_p = true;
return call;
}
if (VOID_TYPE_P (TREE_TYPE (end)))
{
error_at (loc, "incorrect type %qT of %<std::ranges::end(arg)%>",
TREE_TYPE (end));
*non_constant_p = true;
return call;
}
begin = get_target_expr (begin);
end = get_target_expr (end);
begin = cxx_eval_constant_expression (ctx, begin, vc_glvalue, non_constant_p,
overflow_p, jump_target);
if (*jump_target || *non_constant_p)
goto fail_ret;
end = cxx_eval_constant_expression (ctx, end, vc_glvalue, non_constant_p,
overflow_p, jump_target);
if (*jump_target || *non_constant_p)
goto fail_ret;
tree cmp = build_new_op (loc, NE_EXPR, LOOKUP_NORMAL, begin, end,
tf_warning_or_error);
tree deref = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, begin,
NULL_TREE, tf_warning_or_error);
tree inc = build_new_op (loc, PREINCREMENT_EXPR, LOOKUP_NORMAL, begin,
NULL_TREE, tf_warning_or_error);
cmp = condition_conversion (cmp);
if (error_operand_p (cmp)
|| error_operand_p (deref)
|| error_operand_p (inc))
{
*non_constant_p = true;
return call;
}
if (TREE_CODE (TREE_TYPE (deref)) != META_TYPE)
{
error_at (loc, "unexpected type %qT of iterator dereference",
TREE_TYPE (deref));
*non_constant_p = true;
return call;
}
auto_vec<tree, 32> retvec;
/* while (begin != end) { push (*begin); ++begin; } */
do
{
tree t = cxx_eval_constant_expression (ctx, cmp, vc_prvalue,
non_constant_p, overflow_p,
jump_target);
if (*jump_target || *non_constant_p)
goto fail_ret;
if (integer_zerop (t))
break;
t = cxx_eval_constant_expression (ctx, deref, vc_prvalue, non_constant_p,
overflow_p, jump_target);
if (*jump_target || *non_constant_p)
goto fail_ret;
retvec.safe_push (t);
cxx_eval_constant_expression (ctx, inc, vc_discard, non_constant_p,
overflow_p, jump_target);
if (*jump_target || *non_constant_p)
goto fail_ret;
}
while (true);
tree ret = make_tree_vec (retvec.length ()), v;
unsigned int i;
FOR_EACH_VEC_ELT (retvec, i, v)
TREE_VEC_ELT (ret, i) = v;
return ret;
}
/* Return std::vector<info>. */
static tree
@@ -668,6 +925,30 @@ eval_is_object (reflect_kind kind)
return boolean_false_node;
}
/* Like get_info_vec, but throw exception if any of the elements aren't
eval_is_type reflections and change their content to the corresponding
REFLECT_EXPR_HANDLE. */
static tree
get_type_info_vec (location_t loc, const constexpr_ctx *ctx, tree call, int n,
bool *non_constant_p, bool *overflow_p, tree *jump_target)
{
tree vec = get_info_vec (loc, ctx, call, n, non_constant_p, overflow_p,
jump_target);
if (*jump_target)
return NULL_TREE;
if (*non_constant_p)
return call;
for (int i = 0; i < TREE_VEC_LENGTH (vec); i++)
{
tree type = REFLECT_EXPR_HANDLE (TREE_VEC_ELT (vec, i));
if (eval_is_type (type) != boolean_true_node)
return throw_exception_nontype (loc, ctx, type, jump_target);
TREE_VEC_ELT (vec, i) = type;
}
return vec;
}
/* Process std::meta::is_structured_binding.
Returns: true if r represents a structured binding. Otherwise, false. */
@@ -2696,6 +2977,20 @@ eval_is_scoped_enum_type (location_t loc, const constexpr_ctx *ctx,
return boolean_false_node;
}
/* Process std::meta::is_constructible_type. */
static tree
eval_is_constructible_type (location_t loc, const constexpr_ctx *ctx,
tree type, tree tvec, tree *jump_target)
{
if (eval_is_type (type) != boolean_true_node)
return throw_exception_nontype (loc, ctx, type, jump_target);
if (is_xible (INIT_EXPR, type, tvec))
return boolean_true_node;
else
return boolean_false_node;
}
/* Process std::meta::is_default_constructible_type. */
static tree
@@ -2797,6 +3092,20 @@ eval_is_destructible_type (location_t loc, const constexpr_ctx *ctx, tree type,
return eval_type_trait (loc, ctx, type, CPTK_IS_DESTRUCTIBLE, jump_target);
}
/* Process std::meta::is_trivially_constructible_type. */
static tree
eval_is_trivially_constructible_type (location_t loc, const constexpr_ctx *ctx,
tree type, tree tvec, tree *jump_target)
{
if (eval_is_type (type) != boolean_true_node)
return throw_exception_nontype (loc, ctx, type, jump_target);
if (is_trivially_xible (INIT_EXPR, type, tvec))
return boolean_true_node;
else
return boolean_false_node;
}
/* Process std::meta::is_trivially_default_constructible_type. */
static tree
@@ -2904,6 +3213,20 @@ eval_is_trivially_destructible_type (location_t loc, const constexpr_ctx *ctx,
jump_target);
}
/* Process std::meta::is_nothrow_constructible_type. */
static tree
eval_is_nothrow_constructible_type (location_t loc, const constexpr_ctx *ctx,
tree type, tree tvec, tree *jump_target)
{
if (eval_is_type (type) != boolean_true_node)
return throw_exception_nontype (loc, ctx, type, jump_target);
if (is_nothrow_xible (INIT_EXPR, type, tvec))
return boolean_true_node;
else
return boolean_false_node;
}
/* Process std::meta::is_nothrow_default_constructible_type. */
static tree
@@ -3179,6 +3502,33 @@ eval_is_pointer_interconvertible_base_of_type (location_t loc,
jump_target);
}
/* Process std::meta::is_invocable_type. */
static tree
eval_is_invocable_type (location_t loc, const constexpr_ctx *ctx,
tree type, tree tvec, tree *jump_target)
{
if (eval_is_type (type) != boolean_true_node)
return throw_exception_nontype (loc, ctx, type, jump_target);
tree r = finish_trait_expr (input_location, CPTK_IS_INVOCABLE, type, tvec);
STRIP_ANY_LOCATION_WRAPPER (r);
return r;
}
/* Process std::meta::is_nothrow_invocable_type. */
static tree
eval_is_nothrow_invocable_type (location_t loc, const constexpr_ctx *ctx,
tree type, tree tvec, tree *jump_target)
{
if (eval_is_type (type) != boolean_true_node)
return throw_exception_nontype (loc, ctx, type, jump_target);
tree r = finish_trait_expr (input_location, CPTK_IS_NOTHROW_INVOCABLE,
type, tvec);
STRIP_ANY_LOCATION_WRAPPER (r);
return r;
}
/* Process std::meta::remove_cvref. */
static tree
@@ -3763,6 +4113,16 @@ process_metafunction (const constexpr_ctx *ctx, tree call,
return eval_is_unbounded_array_type (loc, ctx, h, jump_target);
if (!strcmp (ident, "scoped_enum_type"))
return eval_is_scoped_enum_type (loc, ctx, h, jump_target);
if (!strcmp (ident, "constructible_type"))
{
tree hvec = get_type_info_vec (loc, ctx, call, 1, non_constant_p,
overflow_p, jump_target);
if (*jump_target)
return NULL_TREE;
if (*non_constant_p)
return call;
return eval_is_constructible_type (loc, ctx, h, hvec, jump_target);
}
if (!strcmp (ident, "default_constructible_type"))
return eval_is_default_constructible_type (loc, ctx, h, jump_target);
if (!strcmp (ident, "copy_constructible_type"))
@@ -3775,6 +4135,17 @@ process_metafunction (const constexpr_ctx *ctx, tree call,
return eval_is_move_assignable_type (loc, ctx, h, jump_target);
if (!strcmp (ident, "destructible_type"))
return eval_is_destructible_type (loc, ctx, h, jump_target);
if (!strcmp (ident, "trivially_constructible_type"))
{
tree hvec = get_type_info_vec (loc, ctx, call, 1, non_constant_p,
overflow_p, jump_target);
if (*jump_target)
return NULL_TREE;
if (*non_constant_p)
return call;
return eval_is_trivially_constructible_type (loc, ctx, h, hvec,
jump_target);
}
if (!strcmp (ident, "trivially_default_constructible_type"))
return eval_is_trivially_default_constructible_type (loc, ctx, h,
jump_target);
@@ -3792,6 +4163,17 @@ process_metafunction (const constexpr_ctx *ctx, tree call,
jump_target);
if (!strcmp (ident, "trivially_destructible_type"))
return eval_is_trivially_destructible_type (loc, ctx, h, jump_target);
if (!strcmp (ident, "nothrow_constructible_type"))
{
tree hvec = get_type_info_vec (loc, ctx, call, 1, non_constant_p,
overflow_p, jump_target);
if (*jump_target)
return NULL_TREE;
if (*non_constant_p)
return call;
return eval_is_nothrow_constructible_type (loc, ctx, h, hvec,
jump_target);
}
if (!strcmp (ident, "nothrow_default_constructible_type"))
return eval_is_nothrow_default_constructible_type (loc, ctx, h,
jump_target);
@@ -3893,6 +4275,27 @@ process_metafunction (const constexpr_ctx *ctx, tree call,
h1,
jump_target);
}
if (!strcmp (ident, "invocable_type"))
{
tree hvec = get_type_info_vec (loc, ctx, call, 1, non_constant_p,
overflow_p, jump_target);
if (*jump_target)
return NULL_TREE;
if (*non_constant_p)
return call;
return eval_is_invocable_type (loc, ctx, h, hvec, jump_target);
}
if (!strcmp (ident, "nothrow_invocable_type"))
{
tree hvec = get_type_info_vec (loc, ctx, call, 1, non_constant_p,
overflow_p, jump_target);
if (*jump_target)
return NULL_TREE;
if (*non_constant_p)
return call;
return eval_is_nothrow_invocable_type (loc, ctx, h, hvec,
jump_target);
}
if (!strcmp (ident, "assignable_type"))
{
tree i1 = get_info (ctx, call, 1, non_constant_p, overflow_p,

View File

@@ -91,6 +91,36 @@ eval (int n)
case 25:
type_order (^^n, ^^S);
break;
case 26:
is_constructible_type (^^n, {});
break;
case 27:
is_constructible_type (^^S, { ^^S, ^^n, ^^S });
break;
case 28:
is_trivially_constructible_type (^^n, {});
break;
case 29:
is_trivially_constructible_type (^^S, { ^^n, ^^S, ^^S, ^^S });
break;
case 30:
is_nothrow_constructible_type (^^n, {});
break;
case 31:
is_nothrow_constructible_type (^^S, { ^^S, ^^S, ^^S, ^^S, ^^n });
break;
case 32:
is_invocable_type (^^n, {});
break;
case 33:
is_invocable_type (^^S, { ^^S, ^^S, ^^n, ^^S });
break;
case 34:
is_nothrow_invocable_type (^^n, {});
break;
case 35:
is_nothrow_invocable_type (^^S, { ^^S, ^^n, ^^S });
break;
default:
break;
}
@@ -131,3 +161,13 @@ static_assert (test (22));
static_assert (test (23));
static_assert (test (24));
static_assert (test (25));
static_assert (test (26));
static_assert (test (27));
static_assert (test (28));
static_assert (test (29));
static_assert (test (30));
static_assert (test (31));
static_assert (test (32));
static_assert (test (33));
static_assert (test (34));
static_assert (test (35));

View File

@@ -0,0 +1,674 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Test std::meta::is_constructible_type.
#include <meta>
using namespace std::meta;
class ClassType { };
class DerivedType : public ClassType { };
enum EnumType { e0 };
struct ThrowDefaultClass { ThrowDefaultClass () noexcept (false); };
struct ThrowCopyConsClass { ThrowCopyConsClass (const ThrowCopyConsClass &) noexcept (false); };
struct ThrowMoveConsClass { ThrowMoveConsClass (ThrowMoveConsClass &&) noexcept (false); };
struct NoexceptDefaultClass { NoexceptDefaultClass () noexcept (true); };
struct ExceptDefaultClass { ExceptDefaultClass () noexcept (false); };
struct NoexceptCopyConsClass { NoexceptCopyConsClass (const NoexceptCopyConsClass &) noexcept (true); };
struct ExceptCopyConsClass { ExceptCopyConsClass (const ExceptCopyConsClass &) noexcept (false); };
struct NoexceptMoveConsClass { NoexceptMoveConsClass (NoexceptMoveConsClass &&) noexcept (true); NoexceptMoveConsClass &operator= (NoexceptMoveConsClass &&) = default; };
struct ExceptMoveConsClass { ExceptMoveConsClass (ExceptMoveConsClass &&) noexcept (false); };
struct NoexceptCopyAssignClass { NoexceptCopyAssignClass &operator= (const NoexceptCopyAssignClass &) noexcept (true); };
struct ExceptCopyAssignClass { ExceptCopyAssignClass &operator= (const ExceptCopyAssignClass &) noexcept (false); };
struct NoexceptMoveAssignClass { NoexceptMoveAssignClass (NoexceptMoveAssignClass &&) = default; NoexceptMoveAssignClass &operator= (NoexceptMoveAssignClass &&) noexcept (true); };
struct ExceptMoveAssignClass { ExceptMoveAssignClass &operator= (ExceptMoveAssignClass &&) noexcept (false); };
struct DeletedCopyAssignClass { DeletedCopyAssignClass & operator= (const DeletedCopyAssignClass &) = delete; };
struct DeletedMoveAssignClass { DeletedMoveAssignClass &operator= (DeletedMoveAssignClass &&) = delete; };
struct NType { int i; int j; virtual ~NType (); };
struct TType { int i; private: int j; };
struct SLType { int i; int j; ~SLType (); };
struct PODType { int i; int j; };
struct Empty {};
struct B { int i; B () {} };
struct D : B {};
enum E { ee1 };
enum E2 { ee2 };
enum class SE { e1 };
enum class SE2 { e2 };
enum OpE : int;
enum class OpSE : bool;
union U { int i; Empty b; };
struct Abstract { virtual ~Abstract () = 0; };
struct AbstractDelDtor { ~AbstractDelDtor () = delete; virtual void foo () = 0; };
struct Ukn;
template <class To>
struct ImplicitTo { operator To (); };
template <class To>
struct DelImplicitTo { operator To () = delete; };
template <class To>
struct ExplicitTo { explicit operator To (); };
struct Ellipsis { Ellipsis (...) {} };
struct DelEllipsis { DelEllipsis (...) = delete; };
struct Any { template <class T> Any (T &&) {} };
struct nAny { template <class... T> nAny (T &&...) {} };
struct DelnAny { template <class... T> DelnAny (T &&...) = delete; };
template <class... Args>
struct FromArgs { FromArgs (Args...); };
struct DelDef { DelDef () = delete; };
struct DelCopy { DelCopy (const DelCopy &) = delete; };
struct DelDtor {
DelDtor () = default;
DelDtor (const DelDtor &) = default;
DelDtor (DelDtor &&) = default;
DelDtor (int);
DelDtor (int, B, U);
~DelDtor () = delete;
};
struct Nontrivial {
Nontrivial ();
Nontrivial (const Nontrivial &);
Nontrivial &operator= (const Nontrivial &);
~Nontrivial ();
};
union NontrivialUnion { int i; Nontrivial n; };
struct UnusualCopy { UnusualCopy (UnusualCopy &); };
static_assert (is_constructible_type (^^int, { ^^int }));
static_assert (is_constructible_type (^^std::nullptr_t, { ^^std::nullptr_t }));
static_assert (is_constructible_type (^^E, { ^^E }));
static_assert (is_constructible_type (^^SE, { ^^SE }));
static_assert (is_constructible_type (^^OpE, { ^^OpE }));
static_assert (is_constructible_type (^^OpSE, { ^^OpSE }));
static_assert (is_constructible_type (^^Empty, { ^^Empty }));
static_assert (is_constructible_type (^^B, { ^^B }));
static_assert (is_constructible_type (^^U, { ^^U }));
static_assert (is_constructible_type (^^int B::*, { ^^int B::* }));
static_assert (is_constructible_type (^^Ellipsis, { ^^Ellipsis }));
static_assert (is_constructible_type (^^int *, { ^^int * }));
static_assert (is_constructible_type (^^void *, { ^^void * }));
static_assert (is_constructible_type (^^Any, { ^^Any }));
static_assert (is_constructible_type (^^nAny, { ^^nAny }));
static_assert (is_constructible_type (^^std::initializer_list <int>, { ^^std::initializer_list <int> }));
static_assert (is_constructible_type (^^DelDef, { ^^DelDef }));
static_assert (!is_constructible_type (^^void, { ^^void }));
static_assert (!is_constructible_type (^^Abstract, { ^^Abstract }));
static_assert (!is_constructible_type (^^int [], { ^^int [] }));
static_assert (!is_constructible_type (^^int [1], { ^^int [1] }));
static_assert (!is_constructible_type (^^DelCopy, { ^^const DelCopy & }));
static_assert (!is_constructible_type (^^DelCopy, { ^^DelCopy && }));
static_assert (!is_constructible_type (^^DelCopy, { ^^DelCopy }));
static_assert (!is_constructible_type (^^DelDtor, { ^^void }));
static_assert (!is_constructible_type (^^DelDtor, { ^^int }));
static_assert (!is_constructible_type (^^DelDtor, { ^^DelDtor }));
static_assert (!is_constructible_type (^^DelDtor, { ^^DelDtor && }));
static_assert (!is_constructible_type (^^DelDtor, { ^^const DelDtor & }));
static_assert (is_constructible_type (^^DelEllipsis, { ^^const DelEllipsis & }));
static_assert (is_constructible_type (^^DelEllipsis, { ^^DelEllipsis && }));
static_assert (is_constructible_type (^^DelEllipsis, { ^^DelEllipsis }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^void }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^B }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^Empty }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^E }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^SE }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^OpE }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^OpSE }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^void () }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^void () const }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^int [1] }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^int [] }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^int * }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^void * }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^int B::* }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^int D::* }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^Abstract }));
static_assert (!is_constructible_type (^^int, { ^^DelImplicitTo <int> }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^DelImplicitTo <std::nullptr_t> }));
static_assert (!is_constructible_type (^^int &, { ^^DelImplicitTo <const int &> }));
static_assert (!is_constructible_type (^^int, { ^^void }));
static_assert (!is_constructible_type (^^void, { ^^int }));
static_assert (is_constructible_type (^^void *, { ^^int * }));
static_assert (!is_constructible_type (^^int *, { ^^void * }));
static_assert (is_constructible_type (^^int *, { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^int * }));
static_assert (!is_constructible_type (^^Empty, { ^^E }));
static_assert (!is_constructible_type (^^Empty, { ^^SE }));
static_assert (!is_constructible_type (^^Empty, { ^^OpE }));
static_assert (!is_constructible_type (^^Empty, { ^^OpSE }));
static_assert (!is_constructible_type (^^Empty, { ^^void }));
static_assert (!is_constructible_type (^^Empty, { ^^void * }));
static_assert (!is_constructible_type (^^Empty, { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^Empty, { ^^int [] }));
static_assert (!is_constructible_type (^^Empty, { ^^int [3] }));
static_assert (!is_constructible_type (^^Empty, { ^^int }));
static_assert (!is_constructible_type (^^Abstract, { ^^int }));
static_assert (!is_constructible_type (^^Abstract, { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^Abstract }));
static_assert (!is_constructible_type (^^Abstract, { ^^int [] }));
static_assert (is_constructible_type (^^B, { ^^D }));
static_assert (!is_constructible_type (^^int [], { ^^int [1] }));
static_assert (!is_constructible_type (^^int [1], { ^^int [] }));
static_assert (!is_constructible_type (^^int [], { ^^Empty }));
static_assert (!is_constructible_type (^^int [], { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^int [1], { ^^Abstract }));
static_assert (is_constructible_type (^^const int *, { ^^int * }));
static_assert (is_constructible_type (^^const void *, { ^^void * }));
static_assert (is_constructible_type (^^const void *, { ^^int * }));
static_assert (!is_constructible_type (^^int *, { ^^const void * }));
static_assert (is_constructible_type (^^int, { ^^E }));
static_assert (!is_constructible_type (^^E, { ^^int }));
static_assert (!is_constructible_type (^^E, { ^^E2 }));
static_assert (is_constructible_type (^^E, { ^^E }));
static_assert (is_constructible_type (^^bool, { ^^E }));
static_assert (!is_constructible_type (^^E, { ^^bool }));
static_assert (is_constructible_type (^^double, { ^^E }));
static_assert (!is_constructible_type (^^E, { ^^double }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^E }));
static_assert (!is_constructible_type (^^E, { ^^std::nullptr_t }));
static_assert (is_constructible_type (^^int, { ^^OpE }));
static_assert (!is_constructible_type (^^OpE, { ^^int }));
static_assert (!is_constructible_type (^^OpE, { ^^E2 }));
static_assert (is_constructible_type (^^OpE, { ^^OpE }));
static_assert (is_constructible_type (^^bool, { ^^OpE }));
static_assert (!is_constructible_type (^^OpE, { ^^bool }));
static_assert (is_constructible_type (^^double, { ^^OpE }));
static_assert (!is_constructible_type (^^OpE, { ^^double }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^OpE }));
static_assert (!is_constructible_type (^^OpE, { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^int, { ^^SE }));
static_assert (!is_constructible_type (^^SE, { ^^int }));
static_assert (!is_constructible_type (^^E, { ^^SE }));
static_assert (!is_constructible_type (^^SE, { ^^SE2 }));
static_assert (is_constructible_type (^^SE, { ^^SE }));
static_assert (!is_constructible_type (^^bool, { ^^SE }));
static_assert (!is_constructible_type (^^SE, { ^^bool }));
static_assert (!is_constructible_type (^^double, { ^^SE }));
static_assert (!is_constructible_type (^^SE, { ^^double }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^SE }));
static_assert (!is_constructible_type (^^SE, { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^int, { ^^OpSE }));
static_assert (!is_constructible_type (^^OpSE, { ^^int }));
static_assert (!is_constructible_type (^^OpE, { ^^OpSE }));
static_assert (!is_constructible_type (^^OpSE, { ^^SE2 }));
static_assert (is_constructible_type (^^OpSE, { ^^OpSE }));
static_assert (!is_constructible_type (^^bool, { ^^OpSE }));
static_assert (!is_constructible_type (^^OpSE, { ^^bool }));
static_assert (!is_constructible_type (^^double, { ^^OpSE }));
static_assert (!is_constructible_type (^^OpSE, { ^^double }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^OpSE }));
static_assert (!is_constructible_type (^^OpSE, { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^D *, { ^^B * }));
static_assert (!is_constructible_type (^^const volatile D *, { ^^B * }));
static_assert (!is_constructible_type (^^D *, { ^^const volatile B * }));
static_assert (!is_constructible_type (^^D *, { ^^B * const }));
static_assert (!is_constructible_type (^^const volatile D *, { ^^B * const }));
static_assert (!is_constructible_type (^^D *, { ^^const volatile B * const }));
static_assert (!is_constructible_type (^^D *, { ^^B * & }));
static_assert (!is_constructible_type (^^const volatile D *, { ^^B * & }));
static_assert (!is_constructible_type (^^D *, { ^^const volatile B * & }));
static_assert (!is_constructible_type (^^int B::*, { ^^int D::* }));
static_assert (!is_constructible_type (^^const volatile int B::*, { ^^int D::* }));
static_assert (!is_constructible_type (^^int B::*, { ^^const volatile int D::* }));
static_assert (!is_constructible_type (^^int B::*, { ^^int D::* const }));
static_assert (!is_constructible_type (^^const volatile int B::*, { ^^int D::* const }));
static_assert (!is_constructible_type (^^int B::*, { ^^const volatile int D::* const }));
static_assert (!is_constructible_type (^^int B::*, { ^^int D::* & }));
static_assert (!is_constructible_type (^^const volatile int B::*, { ^^int D::* & }));
static_assert (!is_constructible_type (^^int B::*, { ^^const volatile int D::* & }));
static_assert (!is_constructible_type (^^int B::*, { ^^int D::* const & }));
static_assert (!is_constructible_type (^^const volatile int B::*, { ^^int D::* const & }));
static_assert (!is_constructible_type (^^int B::*, { ^^const volatile int D::* const & }));
static_assert (!is_constructible_type (^^int &&, { ^^int & }));
static_assert (!is_constructible_type (^^const int &&, { ^^int & }));
static_assert (is_constructible_type (^^B &, { ^^D & }));
static_assert (is_constructible_type (^^B &&, { ^^D && }));
static_assert (is_constructible_type (^^const B &, { ^^D & }));
static_assert (is_constructible_type (^^const B &&, { ^^D && }));
static_assert (!is_constructible_type (^^B &, { ^^const D & }));
static_assert (!is_constructible_type (^^B &&, { ^^const D && }));
static_assert (!is_constructible_type (^^D &, { ^^B & }));
static_assert (is_constructible_type (^^D &&, { ^^B && }));
static_assert (!is_constructible_type (^^D &, { ^^const B & }));
static_assert (is_constructible_type (^^D &&, { ^^const B && }));
static_assert (is_constructible_type (^^const D &, { ^^B & }));
static_assert (is_constructible_type (^^const D &&, { ^^B && }));
static_assert (!is_constructible_type (^^B &&, { ^^B & }));
static_assert (!is_constructible_type (^^B &&, { ^^D & }));
static_assert (is_constructible_type (^^B &&, { ^^ImplicitTo <D &&> }));
static_assert (is_constructible_type (^^B &&, { ^^ImplicitTo <D &&> & }));
static_assert (is_constructible_type (^^int &&, { ^^double & }));
static_assert (is_constructible_type (^^const int &, { ^^ImplicitTo <int &> & }));
static_assert (is_constructible_type (^^const int &, { ^^ImplicitTo <int &> }));
static_assert (is_constructible_type (^^const int &, { ^^ExplicitTo <int &> & }));
static_assert (is_constructible_type (^^const int &, { ^^ExplicitTo <int &> }));
static_assert (!is_constructible_type (^^B &&, { ^^ExplicitTo <D &&> }));
static_assert (!is_constructible_type (^^B &&, { ^^ExplicitTo <D &&> & }));
static_assert (!is_constructible_type (^^B &, { ^^B && }));
static_assert (!is_constructible_type (^^D &, { ^^B && }));
static_assert (!is_constructible_type (^^B &, { ^^D && }));
static_assert (is_constructible_type (^^void (&) (), { ^^void (&) () }));
static_assert (is_constructible_type (^^void (&&) (), { ^^void (&&) () }));
static_assert (is_constructible_type (^^void (&&) (), { ^^void () }));
static_assert (!is_constructible_type (^^void, { }));
static_assert (!is_constructible_type (^^void, { ^^int }));
static_assert (!is_constructible_type (^^void, { ^^int, ^^double }));
static_assert (!is_constructible_type (^^int &, {}));
static_assert (!is_constructible_type (^^const int &, {}));
static_assert (!is_constructible_type (^^int &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const int &, { ^^int, ^^int }));
static_assert (is_constructible_type (^^void (&) (), { ^^void () }));
static_assert (is_constructible_type (^^void (&) (), { ^^void (&&) () }));
static_assert (is_constructible_type (^^int &, { ^^int & }));
static_assert (!is_constructible_type (^^int &, { ^^const int & }));
static_assert (!is_constructible_type (^^int &, { ^^int }));
static_assert (!is_constructible_type (^^int &, { ^^int && }));
static_assert (!is_constructible_type (^^int &, { ^^const int && }));
static_assert (is_constructible_type (^^const int &, { ^^int & }));
static_assert (is_constructible_type (^^const int &, { ^^int }));
static_assert (is_constructible_type (^^const int &, { ^^const int }));
static_assert (is_constructible_type (^^const int &, { ^^int && }));
static_assert (is_constructible_type (^^const int &, { ^^const int && }));
static_assert (is_constructible_type (^^volatile int &, { ^^int & }));
static_assert (!is_constructible_type (^^volatile int &, { ^^const int & }));
static_assert (!is_constructible_type (^^volatile int &, { ^^int }));
static_assert (!is_constructible_type (^^volatile int &, { ^^int && }));
static_assert (!is_constructible_type (^^volatile int &, { ^^const int && }));
static_assert (is_constructible_type (^^const volatile int &, { ^^int & }));
static_assert (!is_constructible_type (^^const volatile int &, { ^^int }));
static_assert (!is_constructible_type (^^const volatile int &, { ^^const int }));
static_assert (!is_constructible_type (^^const volatile int &, { ^^int && }));
static_assert (!is_constructible_type (^^const volatile int &, { ^^const int && }));
static_assert (is_constructible_type (^^int &&, { ^^int }));
static_assert (is_constructible_type (^^int &&, { ^^int && }));
static_assert (!is_constructible_type (^^int &&, { ^^const int && }));
static_assert (!is_constructible_type (^^int &&, { ^^int & }));
static_assert (!is_constructible_type (^^int &&, { ^^const int & }));
static_assert (is_constructible_type (^^int &&, { ^^double & }));
static_assert (is_constructible_type (^^const int &&, { ^^int }));
static_assert (is_constructible_type (^^const int &&, { ^^int && }));
static_assert (is_constructible_type (^^const int &&, { ^^const int }));
static_assert (is_constructible_type (^^const int &&, { ^^const int && }));
static_assert (!is_constructible_type (^^int &&, { ^^const int & }));
static_assert (!is_constructible_type (^^const int &&, { ^^int & }));
static_assert (!is_constructible_type (^^const int &&, { ^^const int & }));
static_assert (is_constructible_type (^^volatile int &&, { ^^int }));
static_assert (is_constructible_type (^^volatile int &&, { ^^int && }));
static_assert (!is_constructible_type (^^volatile int &&, { ^^const int && }));
static_assert (!is_constructible_type (^^volatile int &&, { ^^int & }));
static_assert (!is_constructible_type (^^volatile int &&, { ^^const int & }));
static_assert (is_constructible_type (^^volatile int &&, { ^^double & }));
static_assert (is_constructible_type (^^volatile const int &&, { ^^int }));
static_assert (is_constructible_type (^^const volatile int &&, { ^^int && }));
static_assert (is_constructible_type (^^const volatile int &&, { ^^const int }));
static_assert (is_constructible_type (^^const volatile int &&, { ^^const int && }));
static_assert (!is_constructible_type (^^volatile int &&, { ^^const int & }));
static_assert (!is_constructible_type (^^const volatile int &&, { ^^int & }));
static_assert (!is_constructible_type (^^const volatile int &&, { ^^const int & }));
static_assert (is_constructible_type (^^Empty &, { ^^Empty & }));
static_assert (!is_constructible_type (^^Empty &, { ^^const Empty & }));
static_assert (!is_constructible_type (^^Empty &, { ^^Empty }));
static_assert (!is_constructible_type (^^Empty &, { ^^Empty && }));
static_assert (!is_constructible_type (^^Empty &, { ^^const Empty && }));
static_assert (is_constructible_type (^^const Empty &, { ^^Empty & }));
static_assert (is_constructible_type (^^const Empty &, { ^^Empty }));
static_assert (is_constructible_type (^^const Empty &, { ^^const Empty }));
static_assert (is_constructible_type (^^const Empty &, { ^^Empty && }));
static_assert (is_constructible_type (^^const Empty &, { ^^const Empty && }));
static_assert (is_constructible_type (^^volatile Empty &, { ^^Empty & }));
static_assert (!is_constructible_type (^^volatile Empty &, { ^^const Empty & }));
static_assert (!is_constructible_type (^^volatile Empty &, { ^^Empty }));
static_assert (!is_constructible_type (^^volatile Empty &, { ^^Empty && }));
static_assert (!is_constructible_type (^^volatile Empty &, { ^^const Empty && }));
static_assert (is_constructible_type (^^const volatile Empty &, { ^^Empty & }));
static_assert (!is_constructible_type (^^const volatile Empty &, { ^^Empty }));
static_assert (!is_constructible_type (^^const volatile Empty &, { ^^const Empty }));
static_assert (!is_constructible_type (^^const volatile Empty &, { ^^Empty && }));
static_assert (!is_constructible_type (^^const volatile Empty &, { ^^const Empty && }));
static_assert (is_constructible_type (^^Empty &&, { ^^Empty }));
static_assert (is_constructible_type (^^Empty &&, { ^^Empty && }));
static_assert (!is_constructible_type (^^Empty &&, { ^^const Empty && }));
static_assert (!is_constructible_type (^^Empty &&, { ^^Empty & }));
static_assert (!is_constructible_type (^^Empty &&, { ^^const Empty & }));
static_assert (!is_constructible_type (^^Empty &&, { ^^double & }));
static_assert (!is_constructible_type (^^Empty &&, { ^^const double & }));
static_assert (is_constructible_type (^^const Empty &&, { ^^Empty }));
static_assert (is_constructible_type (^^const Empty &&, { ^^Empty && }));
static_assert (is_constructible_type (^^const Empty &&, { ^^const Empty }));
static_assert (is_constructible_type (^^const Empty &&, { ^^const Empty && }));
static_assert (!is_constructible_type (^^Empty &&, { ^^const Empty & }));
static_assert (!is_constructible_type (^^const Empty &&, { ^^Empty & }));
static_assert (!is_constructible_type (^^const Empty &&, { ^^const Empty & }));
static_assert (is_constructible_type (^^volatile Empty &&, { ^^Empty }));
static_assert (is_constructible_type (^^volatile Empty &&, { ^^Empty && }));
static_assert (!is_constructible_type (^^volatile Empty &&, { ^^const Empty && }));
static_assert (!is_constructible_type (^^volatile Empty &&, { ^^Empty & }));
static_assert (!is_constructible_type (^^volatile Empty &&, { ^^const Empty & }));
static_assert (!is_constructible_type (^^volatile Empty &&, { ^^double & }));
static_assert (!is_constructible_type (^^volatile Empty &&, { ^^const double & }));
static_assert (is_constructible_type (^^const volatile Empty &&, { ^^Empty }));
static_assert (is_constructible_type (^^const volatile Empty &&, { ^^Empty && }));
static_assert (is_constructible_type (^^const volatile Empty &&, { ^^const Empty }));
static_assert (is_constructible_type (^^const volatile Empty &&, { ^^const Empty && }));
static_assert (!is_constructible_type (^^volatile Empty &&, { ^^const Empty & }));
static_assert (!is_constructible_type (^^const volatile Empty &&, { ^^Empty & }));
static_assert (!is_constructible_type (^^const volatile Empty &&, { ^^const Empty & }));
static_assert (is_constructible_type (^^Ellipsis, { ^^int }));
static_assert (is_constructible_type (^^Ellipsis, { ^^Empty }));
static_assert (is_constructible_type (^^Ellipsis, { ^^std::nullptr_t }));
static_assert (is_constructible_type (^^Ellipsis, { ^^int [] }));
static_assert (is_constructible_type (^^Ellipsis, { ^^int [1] }));
static_assert (!is_constructible_type (^^Ellipsis, { ^^void }));
static_assert (is_constructible_type (^^int (&) [1], { ^^int (&) [1] }));
static_assert (is_constructible_type (^^const int (&) [1], { ^^int (&) [1] }));
static_assert (is_constructible_type (^^volatile int (&) [1], { ^^int (&) [1] }));
static_assert (is_constructible_type (^^const volatile int (&) [1], { ^^int (&) [1] }));
static_assert (!is_constructible_type (^^int (&) [1], { ^^const int (&) [1] }));
static_assert (!is_constructible_type (^^const int (&) [1], { ^^volatile int (&) [1] }));
static_assert (is_constructible_type (^^int (&) [], { ^^int (&) [] }));
static_assert (!is_constructible_type (^^int (&) [1], { ^^int (&) [2] }));
static_assert (!is_constructible_type (^^int (&) [1], { ^^int & }));
static_assert (!is_constructible_type (^^int &, { ^^int (&) [1] }));
static_assert (!is_constructible_type (^^U, { ^^Empty }));
static_assert (!is_constructible_type (^^void (), { ^^void () }));
static_assert (!is_constructible_type (^^void (), { ^^int }));
static_assert (!is_constructible_type (^^void (), { ^^Abstract }));
static_assert (!is_constructible_type (^^void (), { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^void (), { ^^Empty }));
static_assert (!is_constructible_type (^^void (), { ^^U }));
static_assert (!is_constructible_type (^^void (), { ^^E }));
static_assert (!is_constructible_type (^^void (), { ^^SE }));
static_assert (!is_constructible_type (^^void (), { ^^OpE }));
static_assert (!is_constructible_type (^^void (), { ^^OpSE }));
static_assert (!is_constructible_type (^^void (), { ^^int [] }));
static_assert (!is_constructible_type (^^void (), { ^^int [1] }));
static_assert (!is_constructible_type (^^void () const, { ^^void () volatile }));
static_assert (!is_constructible_type (^^void () const, { ^^int }));
static_assert (!is_constructible_type (^^void () const, { ^^Abstract }));
static_assert (!is_constructible_type (^^void () const, { ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^void () const, { ^^Empty }));
static_assert (!is_constructible_type (^^void () const, { ^^U }));
static_assert (!is_constructible_type (^^void () const, { ^^E }));
static_assert (!is_constructible_type (^^void () const, { ^^SE }));
static_assert (!is_constructible_type (^^void () const, { ^^OpE }));
static_assert (!is_constructible_type (^^void () const, { ^^OpSE }));
static_assert (!is_constructible_type (^^void () const, { ^^int [] }));
static_assert (!is_constructible_type (^^void () const, { ^^int [1] }));
static_assert (!is_constructible_type (^^void (int), { ^^void () }));
static_assert (!is_constructible_type (^^int, { ^^void () }));
static_assert (!is_constructible_type (^^Abstract, { ^^void () }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^void () }));
static_assert (!is_constructible_type (^^Empty, { ^^void () }));
static_assert (!is_constructible_type (^^U, { ^^void () }));
static_assert (!is_constructible_type (^^E, { ^^void () }));
static_assert (!is_constructible_type (^^SE, { ^^void () }));
static_assert (!is_constructible_type (^^OpE, { ^^void () }));
static_assert (!is_constructible_type (^^OpSE, { ^^void () }));
static_assert (!is_constructible_type (^^int [], { ^^void () }));
static_assert (!is_constructible_type (^^int [1], { ^^void () }));
static_assert (!is_constructible_type (^^void (int) const, { ^^void () const }));
static_assert (!is_constructible_type (^^int, { ^^void () const }));
static_assert (!is_constructible_type (^^Abstract, { ^^void () const }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^void () const }));
static_assert (!is_constructible_type (^^Empty, { ^^void () const }));
static_assert (!is_constructible_type (^^U, { ^^void () const }));
static_assert (!is_constructible_type (^^E, { ^^void () const }));
static_assert (!is_constructible_type (^^SE, { ^^void () const }));
static_assert (!is_constructible_type (^^OpE, { ^^void () const }));
static_assert (!is_constructible_type (^^OpSE, { ^^void () const }));
static_assert (!is_constructible_type (^^int [], { ^^void () const }));
static_assert (!is_constructible_type (^^int [1], { ^^void () const }));
static_assert (!is_constructible_type (^^void, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^void, { ^^Empty, ^^B }));
static_assert (!is_constructible_type (^^void, { ^^Empty, ^^Empty }));
static_assert (!is_constructible_type (^^void, { ^^U, ^^Empty }));
static_assert (!is_constructible_type (^^void, { ^^U, ^^U }));
static_assert (!is_constructible_type (^^void, { ^^std::nullptr_t, ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^void, { ^^int [1], ^^int [1] }));
static_assert (!is_constructible_type (^^void, { ^^int [], ^^int [] }));
static_assert (!is_constructible_type (^^void, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^void, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^void, { ^^void (), ^^void () }));
static_assert (!is_constructible_type (^^void, { ^^void () const, ^^void () volatile }));
static_assert (!is_constructible_type (^^int, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const int, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^int, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const int, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^int, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const int, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^bool, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const bool, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const std::nullptr_t, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const std::nullptr_t, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^std::nullptr_t, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const std::nullptr_t, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^E, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const E, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^E, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const E, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^E, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const E, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^SE, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const SE, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^SE, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const SE, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^SE, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const SE, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^OpE, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const OpE, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^OpE, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const OpE, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^OpE, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const OpE, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^OpSE, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const OpSE, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^OpSE, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const OpSE, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^OpSE, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const OpSE, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^Empty, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const Empty, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^Empty, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const Empty, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^Empty, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const Empty, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^U, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const U, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^U, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const U, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^U, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const U, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^B, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const B, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^B, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const B, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^B, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const B, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^Any, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const Any, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^Any, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const Any, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^Any, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const Any, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^nAny, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const nAny, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^nAny, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const nAny, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^FromArgs <>, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const FromArgs <>, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^FromArgs <>, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const FromArgs <>, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^FromArgs <>, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const FromArgs <>, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^Abstract, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const Abstract, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^Abstract, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const Abstract, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^Abstract, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const Abstract, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^AbstractDelDtor, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const AbstractDelDtor, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^AbstractDelDtor, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const AbstractDelDtor, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^AbstractDelDtor, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const AbstractDelDtor, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^int [1], { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const int [1], { ^^int, ^^int }));
static_assert (!is_constructible_type (^^int [1], { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const int [1], { ^^void, ^^int }));
static_assert (!is_constructible_type (^^int [1], { ^^void, ^^void }));
static_assert (!is_constructible_type (^^const int [1], { ^^void, ^^void }));
static_assert (!is_constructible_type (^^int &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^int &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^int &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^int &, { ^^int &, ^^int & }));
static_assert (!is_constructible_type (^^int &, { ^^void, ^^int & }));
static_assert (!is_constructible_type (^^int &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^std::nullptr_t &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^std::nullptr_t &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^std::nullptr_t &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^E &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^E &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^E &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^SE &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^SE &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^SE &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^OpE &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^OpE &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^OpE &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^OpSE &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^OpSE &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^OpSE &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^Empty &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^Empty &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^Empty &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^U &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^U &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^U &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^B &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^B &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^B &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^Any &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^Any &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^Any &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^nAny &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^nAny &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^FromArgs <> &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^FromArgs <> &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^FromArgs <> &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^Abstract &, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^Abstract &, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^Abstract &, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^int (&) [1], { ^^int, ^^int }));
static_assert (!is_constructible_type (^^int (&) [1], { ^^void, ^^int }));
static_assert (!is_constructible_type (^^int (&) [1], { ^^void, ^^void }));
static_assert (!is_constructible_type (^^void (), { ^^int, ^^int }));
static_assert (!is_constructible_type (^^void (), { ^^void, ^^int }));
static_assert (!is_constructible_type (^^void (), { ^^void, ^^void }));
static_assert (!is_constructible_type (^^void (), { ^^void (), ^^int }));
static_assert (!is_constructible_type (^^void (), { ^^void (), ^^void () }));
static_assert (!is_constructible_type (^^void () const, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^void () const, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^void () const, { ^^void, ^^void }));
static_assert (!is_constructible_type (^^void () const, { ^^void () volatile, ^^int }));
static_assert (!is_constructible_type (^^void () const, { ^^void () volatile const, ^^void () const }));
static_assert (!is_constructible_type (^^FromArgs <int>, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const FromArgs <int>, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^FromArgs <int>, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const FromArgs <int>, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^FromArgs <int, int>, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^const FromArgs <int, int>, { ^^void, ^^int }));
static_assert (!is_constructible_type (^^DelDtor, { ^^int, ^^B, ^^U }));
static_assert (!is_constructible_type (^^const DelDtor, { ^^int, ^^B, ^^U }));
static_assert (!is_constructible_type (^^DelDtor, { ^^int }));
static_assert (!is_constructible_type (^^const DelDtor, { ^^int }));
static_assert (!is_constructible_type (^^DelDtor, {}));
static_assert (!is_constructible_type (^^const DelDtor, {}));
static_assert (!is_constructible_type (^^DelDtor, { ^^void *, ^^void (&) () }));
static_assert (!is_constructible_type (^^const DelDtor, { ^^void *, ^^void (&) () }));
static_assert (!is_constructible_type (^^AbstractDelDtor, {}));
static_assert (!is_constructible_type (^^const AbstractDelDtor, {}));
static_assert (!is_constructible_type (^^DelEllipsis, {}));
static_assert (!is_constructible_type (^^const DelEllipsis, {}));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^double }));
static_assert (!is_constructible_type (^^const DelEllipsis, { ^^double }));
static_assert (!is_constructible_type (^^DelEllipsis, { ^^double, ^^int & }));
static_assert (!is_constructible_type (^^const DelEllipsis, { ^^double, ^^int & }));
static_assert (!is_constructible_type (^^DelnAny, {}));
static_assert (!is_constructible_type (^^const DelnAny, {}));
static_assert (!is_constructible_type (^^DelnAny, { ^^int }));
static_assert (!is_constructible_type (^^const DelnAny, { ^^int }));
static_assert (!is_constructible_type (^^DelnAny, { ^^int, ^^void * }));
static_assert (!is_constructible_type (^^const DelnAny, { ^^int, ^^void * }));
static_assert (!is_constructible_type (^^DelnAny, { ^^Empty, ^^B, ^^D }));
static_assert (!is_constructible_type (^^const DelnAny, { ^^Empty, ^^B, ^^D }));
static_assert (!is_constructible_type (^^NontrivialUnion, {}));
static_assert (!is_constructible_type (^^NontrivialUnion, { ^^const NontrivialUnion & }));
static_assert (!is_constructible_type (^^UnusualCopy, {}));
static_assert (!is_constructible_type (^^UnusualCopy, { ^^UnusualCopy }));
static_assert (!is_constructible_type (^^UnusualCopy, { ^^UnusualCopy && }));
static_assert (!is_constructible_type (^^UnusualCopy, { ^^const UnusualCopy & }));
static_assert (is_constructible_type (^^UnusualCopy, { ^^UnusualCopy & }));
static_assert (is_constructible_type (^^FromArgs <int, char>, { ^^int, ^^char }));
static_assert (is_constructible_type (^^const FromArgs <int, char>, { ^^int, ^^char }));
static_assert (is_constructible_type (^^FromArgs <int, char>, { ^^int, ^^int }));
static_assert (is_constructible_type (^^const FromArgs <int, char>, { ^^int, ^^int }));
static_assert (is_constructible_type (^^nAny, { ^^int, ^^int }));
static_assert (is_constructible_type (^^const nAny, { ^^int, ^^int }));
static_assert (is_constructible_type (^^FromArgs <int, char>, { ^^ImplicitTo <int>, ^^ImplicitTo <char> }));
static_assert (is_constructible_type (^^const FromArgs <int, char>, { ^^ImplicitTo <int>, ^^ImplicitTo <char> }));
static_assert (is_constructible_type (^^Ellipsis, { ^^int, ^^char }));
static_assert (is_constructible_type (^^const Ellipsis, { ^^int, ^^char }));
static_assert (is_constructible_type (^^Ellipsis, { ^^B, ^^U, ^^int & }));
static_assert (is_constructible_type (^^const Ellipsis, { ^^B, ^^U, ^^int & }));
static_assert (is_constructible_type (^^nAny, { ^^B, ^^U, ^^int & }));
static_assert (is_constructible_type (^^const nAny, { ^^B, ^^U, ^^int & }));
static_assert (is_constructible_type (^^FromArgs <std::initializer_list <int>, std::initializer_list <B>>, { ^^std::initializer_list <int>, ^^std::initializer_list <B> }));
static_assert (is_constructible_type (^^const FromArgs <std::initializer_list <int>, std::initializer_list <B>>, { ^^std::initializer_list <int>, ^^std::initializer_list <B> }));
static_assert (is_constructible_type (^^FromArgs <std::initializer_list <int>, std::initializer_list <B>>, { ^^std::initializer_list <int> &, ^^std::initializer_list <B> & }));
static_assert (!is_constructible_type (^^FromArgs <std::initializer_list <int> &, std::initializer_list <B> &>, { ^^std::initializer_list <int>, ^^std::initializer_list <B> }));
static_assert (!is_constructible_type (^^FromArgs <std::initializer_list <int>>, { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const FromArgs <std::initializer_list <int>>, { ^^int, ^^int }));
static_assert (is_constructible_type (^^B [2], { ^^B, ^^B }));
static_assert (is_constructible_type (^^const B [2], { ^^B, ^^B }));
static_assert (is_constructible_type (^^U [2], { ^^U, ^^U }));
static_assert (is_constructible_type (^^const U [2], { ^^U, ^^U }));
static_assert (!is_constructible_type (^^E, { ^^E, ^^E }));
static_assert (!is_constructible_type (^^const E, { ^^E, ^^E }));
static_assert (!is_constructible_type (^^SE, { ^^SE, ^^SE }));
static_assert (!is_constructible_type (^^const SE, { ^^SE, ^^SE }));
static_assert (!is_constructible_type (^^E, { ^^B, ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^const E, { ^^B, ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^SE, { ^^B, ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^const SE, { ^^B, ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^E, { ^^int [], ^^int [] }));
static_assert (!is_constructible_type (^^const E, { ^^int [], ^^int [] }));
static_assert (!is_constructible_type (^^SE, { ^^int [], ^^int [] }));
static_assert (!is_constructible_type (^^const SE, { ^^int [], ^^int [] }));
static_assert (!is_constructible_type (^^OpE, { ^^OpE, ^^OpE }));
static_assert (!is_constructible_type (^^const OpE, { ^^OpE, ^^OpE }));
static_assert (!is_constructible_type (^^OpSE, { ^^OpSE, ^^OpSE }));
static_assert (!is_constructible_type (^^const OpSE, { ^^OpSE, ^^OpSE }));
static_assert (!is_constructible_type (^^OpE, { ^^B, ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^const OpE, { ^^B, ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^OpSE, { ^^B, ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^const OpSE, { ^^B, ^^std::nullptr_t }));
static_assert (!is_constructible_type (^^OpE, { ^^int [], ^^int [] }));
static_assert (!is_constructible_type (^^const OpE, { ^^int [], ^^int [] }));
static_assert (!is_constructible_type (^^OpSE, { ^^int [], ^^int [] }));
static_assert (!is_constructible_type (^^const OpSE, { ^^int [], ^^int [] }));
static_assert (!is_constructible_type (^^int [], { ^^int, ^^int }));
static_assert (!is_constructible_type (^^const int [], { ^^int, ^^int }));
static_assert (is_constructible_type (^^int &, { ^^ImplicitTo <int &> }));
static_assert (is_constructible_type (^^const int &, { ^^ImplicitTo <int &&> }));
static_assert (is_constructible_type (^^int &&, { ^^ImplicitTo <int &&> }));
static_assert (is_constructible_type (^^const int &, { ^^ImplicitTo <int> }));
static_assert (!is_constructible_type (^^const int &, { ^^ExplicitTo <int> }));
static_assert (!is_constructible_type (^^int &&, { ^^ExplicitTo <int> }));
static_assert (is_constructible_type (^^int &, { ^^ExplicitTo <int &> }));
static_assert (is_constructible_type (^^int &&, { ^^ExplicitTo <int &&> }));
static_assert (!is_constructible_type (^^const int &, { ^^ExplicitTo <int &&> }));
static_assert (!is_constructible_type (^^const int &, { ^^ExplicitTo <double &&> }));
static_assert (!is_constructible_type (^^int &&, { ^^ExplicitTo <double &&> }));
static_assert (is_constructible_type (^^void (&&) (), { ^^void (&) () }));

View File

@@ -0,0 +1,137 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Test std::meta::is_constructible_type.
#include <array>
#include <list>
#include <meta>
#include <ranges>
#include <span>
#include <vector>
using namespace std::meta;
template <class... Args>
struct FromArgs { FromArgs (Args...); };
static_assert (!is_constructible_type (^^FromArgs <int &, long &, const double &>, {}));
static_assert (is_constructible_type (^^FromArgs <int &, long &, const double &>, { ^^int &, ^^long &, ^^const double & }));
constexpr info arr1[6] = { ^^double, ^^int &, ^^unsigned long long &, ^^int *, ^^short &, ^^char & };
static_assert (is_constructible_type (^^FromArgs <double, int &, unsigned long long &, int *, short &, char &>, arr1));
constexpr std::span <const info> sp1 (arr1);
static_assert (is_constructible_type (^^FromArgs <double, int &, unsigned long long &, int *, short &, char &>, sp1));
static_assert (is_constructible_type (^^FromArgs <int &, unsigned long long &, int *>, sp1.subspan (1, 3)));
static_assert (is_constructible_type (^^FromArgs <double, int &, unsigned long long &, int *, short &>, sp1.first (5)));
static_assert (is_constructible_type (^^FromArgs <int *, unsigned long long &, int &>, sp1.subspan (1, 3) | std::views::reverse));
static_assert (is_constructible_type (^^FromArgs <short &, int *, unsigned long long &, int &, double>, sp1.first (5) | std::views::reverse));
static_assert (!is_constructible_type (^^FromArgs <double, int &, unsigned long long &, int *, short &>, sp1.first (5) | std::views::reverse));
consteval bool
foo ()
{
auto a = std::vector <info> { ^^int &, ^^long &, ^^long long & };
if (!is_constructible_type (^^FromArgs <int &, long &, long long &>, a))
return false;
auto b = std::vector <info> { ^^short &, ^^double &, ^^float &, ^^char & };
if (!is_constructible_type (^^FromArgs <short &, double &, float &, char &>, b))
return false;
auto c = std::array { ^^long &, ^^short &, ^^char &, ^^int };
if (!is_constructible_type (^^FromArgs <long &, short &, char &, int>, c))
return false;
if (!is_constructible_type (^^FromArgs <long long &, long &, int &>, a | std::views::reverse))
return false;
if (!is_constructible_type (^^FromArgs <char &, float &, double &, short &>, b | std::views::reverse))
return false;
if (!is_constructible_type (^^FromArgs <int, char &, short &, long &>, c | std::views::reverse))
return false;
return true;
}
static_assert (foo ());
struct G
{
consteval const info *begin () const { return &arr1[0]; }
consteval const info *end () const { return &arr1[4]; }
};
static_assert (is_constructible_type (^^FromArgs <double, int &, unsigned long long &, int *>, G {}));
struct H
{
consteval const info *begin () const { return &arr1[1]; }
consteval const info *end () const { return &arr1[4]; }
};
static_assert (is_constructible_type (^^FromArgs <int &, unsigned long long &, int *>, H {}));
struct I
{
using difference_type = std::ptrdiff_t;
using value_type = info;
consteval info operator * () const {
if (p == 0) return arr1[2];
else if (p == 1) return arr1[0];
else if (p == 2) return arr1[1];
else return arr1[3];
}
constexpr I &operator ++ () { ++p; return *this; }
constexpr void operator ++ (int) { ++*this; }
constexpr bool operator == (const I &x) const { return p == x.p; }
int p;
};
struct J
{
constexpr I begin () const { return I { 0 }; }
constexpr I end () const { return I { 4 }; }
};
static_assert (is_constructible_type (^^FromArgs <unsigned long long &, double, int &, int *>, J {}));
struct K
{
constexpr K () : q (new int) {}
constexpr K (const K &) : q (new int) {}
constexpr K &operator = (const K &) { return *this; }
constexpr ~K () { delete q; }
int *q;
};
template <typename T, T E>
struct L
{
using difference_type = std::ptrdiff_t;
using value_type = T;
constexpr T &operator * () const { return *p; }
constexpr L (T *x) : p (x), q (new int) {}
constexpr L (const L &x) : p (x.p), q (new int) {}
constexpr L &operator = (const L &x) { p = x.p; return *this; }
constexpr ~L () { delete q; }
constexpr L &operator ++ () { ++p; return *this; }
constexpr void operator ++ (int) { ++*this; }
constexpr bool operator == (const L &x) const { return p == x.p; }
constexpr bool operator == (const K &) const { return *p == E; }
T *p;
int *q;
};
template <typename T, T E>
struct M
{
constexpr M (T *x) : p (x), q (new int) {}
constexpr M (const M &x) : p (x.p), q (new int) {}
constexpr M &operator = (const M &x) { p = x.p; return *this; }
constexpr ~M () { delete q; }
constexpr L <T, E> begin () const { return L <T, E> (p); }
constexpr K end () const { return K (); }
T *p;
int *q;
};
consteval bool
bar ()
{
info a[] = { ^^int &, ^^short &, ^^long &, ^^unsigned &, ^^char &, ^^void, ^^int };
auto b = M <info, ^^void> (&a[0]);
if (!is_constructible_type (^^FromArgs <int &, short &, long &, unsigned &, char &>, b))
return false;
return true;
}
static_assert (bar ());

View File

@@ -0,0 +1,330 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Test reflection type traits [meta.reflection.traits], type properties.
#include <meta>
using namespace std::meta;
class ClassType { };
class DerivedType : public ClassType { };
enum EnumType { e0 };
struct ThrowDefaultClass { ThrowDefaultClass () noexcept (false); };
struct ThrowCopyConsClass { ThrowCopyConsClass (const ThrowCopyConsClass &) noexcept (false); };
struct ThrowMoveConsClass { ThrowMoveConsClass (ThrowMoveConsClass &&) noexcept (false); };
struct NoexceptDefaultClass { NoexceptDefaultClass () noexcept (true); };
struct ExceptDefaultClass { ExceptDefaultClass () noexcept (false); };
struct NoexceptCopyConsClass { NoexceptCopyConsClass (const NoexceptCopyConsClass &) noexcept (true); };
struct ExceptCopyConsClass { ExceptCopyConsClass (const ExceptCopyConsClass &) noexcept (false); };
struct NoexceptMoveConsClass { NoexceptMoveConsClass (NoexceptMoveConsClass &&) noexcept (true); NoexceptMoveConsClass &operator= (NoexceptMoveConsClass &&) = default; };
struct ExceptMoveConsClass { ExceptMoveConsClass (ExceptMoveConsClass &&) noexcept (false); };
struct NoexceptCopyAssignClass { NoexceptCopyAssignClass &operator= (const NoexceptCopyAssignClass &) noexcept (true); };
struct ExceptCopyAssignClass { ExceptCopyAssignClass &operator= (const ExceptCopyAssignClass &) noexcept (false); };
struct NoexceptMoveAssignClass { NoexceptMoveAssignClass (NoexceptMoveAssignClass &&) = default; NoexceptMoveAssignClass &operator= (NoexceptMoveAssignClass &&) noexcept (true); };
struct ExceptMoveAssignClass { ExceptMoveAssignClass &operator= (ExceptMoveAssignClass &&) noexcept (false); };
struct DeletedCopyAssignClass { DeletedCopyAssignClass & operator= (const DeletedCopyAssignClass &) = delete; };
struct DeletedMoveAssignClass { DeletedMoveAssignClass &operator= (DeletedMoveAssignClass &&) = delete; };
struct NType { int i; int j; virtual ~NType (); };
struct TType { int i; private: int j; };
struct SLType { int i; int j; ~SLType (); };
struct PODType { int i; int j; };
struct LType { int i; constexpr LType (int j) : i(j) {} };
struct HasTemplateCCtor { HasTemplateCCtor (const HasTemplateCCtor &) = default; template <class T> HasTemplateCCtor (T &&); };
struct MoveOnly { MoveOnly (MoveOnly &&) = default; };
struct MoveOnly2 { MoveOnly2 (MoveOnly2 &&) = delete; };
class PolymorphicClass { virtual void rotate (int); };
struct CopyConsOnlyType {
CopyConsOnlyType (int) { }
CopyConsOnlyType (CopyConsOnlyType &&) = delete;
CopyConsOnlyType (const CopyConsOnlyType &) = default;
CopyConsOnlyType &operator= (const CopyConsOnlyType &) = delete;
CopyConsOnlyType &operator= (CopyConsOnlyType &&) = delete;
};
struct MoveConsOnlyType {
MoveConsOnlyType (int) { }
MoveConsOnlyType (const MoveConsOnlyType &) = delete;
MoveConsOnlyType (MoveConsOnlyType &&) = default;
MoveConsOnlyType &operator= (const MoveConsOnlyType &) = delete;
MoveConsOnlyType &operator= (MoveConsOnlyType &&) = delete;
};
struct NoexceptExplicitClass {
NoexceptExplicitClass (double &) noexcept (true);
explicit NoexceptExplicitClass (int &) noexcept (true);
NoexceptExplicitClass (double &, int &, double &) noexcept (true);
};
struct ExceptExplicitClass {
ExceptExplicitClass (double &) noexcept (false);
explicit ExceptExplicitClass (int &) noexcept (false);
ExceptExplicitClass (double &, int &, double &) noexcept (false);
};
struct NothrowExplicitClass {
NothrowExplicitClass (double &) throw ();
explicit NothrowExplicitClass (int &) throw ();
NothrowExplicitClass (double &, int &, double &) throw ();
};
namespace N1
{
struct Empty {};
struct B { int i; B () {} };
struct D : B {};
enum E { ee1 };
enum E2 { ee2 };
enum class SE { e1 };
enum class SE2 { e2 };
enum OpE : int;
enum class OpSE : bool;
union U { int i; Empty b; };
struct Abstract { virtual ~Abstract () = 0; };
struct AbstractDelDtor { ~AbstractDelDtor () = delete; virtual void foo () = 0; };
struct Ukn;
template <class To>
struct ImplicitTo { operator To (); };
template <class To>
struct DelImplicitTo { operator To () = delete; };
template <class To>
struct ExplicitTo { explicit operator To (); };
struct Ellipsis { Ellipsis (...) {} };
struct DelEllipsis { DelEllipsis (...) = delete; };
struct Any { template <class T> Any (T &&) {} };
struct nAny { template <class... T> nAny (T &&...) {} };
struct DelnAny { template <class... T> DelnAny (T &&...) = delete; };
template <class... Args>
struct FromArgs { FromArgs (Args...); };
struct DelDef { DelDef () = delete; };
struct DelCopy { DelCopy (const DelCopy &) = delete; };
struct DelDtor {
DelDtor () = default;
DelDtor (const DelDtor &) = default;
DelDtor (DelDtor &&) = default;
DelDtor (int);
DelDtor (int, B, U);
~DelDtor () = delete;
};
struct Nontrivial {
Nontrivial ();
Nontrivial (const Nontrivial &);
Nontrivial &operator= (const Nontrivial &);
~Nontrivial ();
};
union NontrivialUnion { int i; Nontrivial n; };
struct UnusualCopy { UnusualCopy (UnusualCopy &); };
}
struct X { X () = default; X (int) noexcept {} X (double) {} };
struct Y { int i; X x; };
struct Z : Y { };
static_assert (is_trivially_constructible_type (^^int, {}));
static_assert (is_trivially_constructible_type (^^int, { ^^int }));
static_assert (is_trivially_constructible_type (^^int, { ^^int & }));
static_assert (is_trivially_constructible_type (^^int, { ^^int && }));
static_assert (is_trivially_constructible_type (^^int, { ^^const int & }));
static_assert (!is_trivially_constructible_type (^^int, { ^^void * }));
static_assert (!is_trivially_constructible_type (^^int, { ^^int * }));
static_assert (!is_trivially_constructible_type (^^int, { ^^const int * }));
static_assert (!is_trivially_constructible_type (^^int *, { ^^void * }));
static_assert (!is_trivially_constructible_type (^^int *, { ^^const int * }));
static_assert (!is_trivially_constructible_type (^^int &, { ^^const int }));
static_assert (is_trivially_constructible_type (^^const int &, { ^^int }));
static_assert (is_trivially_constructible_type (^^const int &, { ^^int & }));
static_assert (is_trivially_constructible_type (^^const int *, { ^^int * }));
static_assert (!is_trivially_constructible_type (^^PolymorphicClass, {}));
static_assert (!is_trivially_constructible_type (^^PolymorphicClass, { ^^PolymorphicClass }));
static_assert (!is_trivially_constructible_type (^^PolymorphicClass, { ^^PolymorphicClass & }));
static_assert (!is_trivially_constructible_type (^^PolymorphicClass, { ^^PolymorphicClass && }));
static_assert (!is_trivially_constructible_type (^^PolymorphicClass, { ^^const PolymorphicClass & }));
static_assert (is_trivially_constructible_type (^^TType, {}));
static_assert (is_trivially_constructible_type (^^TType, { ^^TType }));
static_assert (is_trivially_constructible_type (^^TType, { ^^TType & }));
static_assert (is_trivially_constructible_type (^^TType, { ^^TType && }));
static_assert (is_trivially_constructible_type (^^TType, { ^^const TType & }));
static_assert (!is_trivially_constructible_type (^^TType, { ^^int, ^^int }));
static_assert (is_trivially_constructible_type (^^PODType, {}));
static_assert (is_trivially_constructible_type (^^PODType, { ^^PODType }));
static_assert (is_trivially_constructible_type (^^PODType, { ^^PODType & }));
static_assert (is_trivially_constructible_type (^^PODType, { ^^PODType && }));
static_assert (is_trivially_constructible_type (^^PODType, { ^^const PODType & }));
static_assert (is_trivially_constructible_type (^^PODType, { ^^int, ^^int }));
static_assert (!is_trivially_constructible_type (^^NType, {}));
static_assert (!is_trivially_constructible_type (^^SLType, {}));
static_assert (!is_trivially_constructible_type (^^LType, {}));
static_assert (!is_trivially_constructible_type (^^LType, { ^^int }));
static_assert (!is_trivially_constructible_type (^^N1::DelDef, {}));
static_assert (!is_trivially_constructible_type (^^N1::Abstract, {}));
static_assert (!is_trivially_constructible_type (^^N1::Ellipsis, {}));
static_assert (!is_trivially_constructible_type (^^N1::DelEllipsis, {}));
static_assert (!is_trivially_constructible_type (^^N1::Any, {}));
static_assert (!is_trivially_constructible_type (^^N1::DelCopy, {}));
static_assert (!is_trivially_constructible_type (^^N1::DelCopy, { ^^const N1::DelCopy & }));
static_assert (!is_trivially_constructible_type (^^N1::DelDtor, {}));
static_assert (!is_trivially_constructible_type (^^N1::Nontrivial, {}));
static_assert (!is_trivially_constructible_type (^^N1::UnusualCopy, {}));
static_assert (!is_trivially_constructible_type (^^CopyConsOnlyType, {}));
static_assert (!is_trivially_constructible_type (^^CopyConsOnlyType, { ^^CopyConsOnlyType }));
static_assert (is_trivially_constructible_type (^^CopyConsOnlyType, { ^^CopyConsOnlyType & }));
static_assert (!is_trivially_constructible_type (^^CopyConsOnlyType, { ^^CopyConsOnlyType && }));
static_assert (is_trivially_constructible_type (^^CopyConsOnlyType, { ^^const CopyConsOnlyType & }));
static_assert (!is_trivially_constructible_type (^^MoveConsOnlyType, {}));
static_assert (is_trivially_constructible_type (^^MoveConsOnlyType, { ^^MoveConsOnlyType }));
static_assert (!is_trivially_constructible_type (^^MoveConsOnlyType, { ^^MoveConsOnlyType & }));
static_assert (is_trivially_constructible_type (^^MoveConsOnlyType, { ^^MoveConsOnlyType && }));
static_assert (!is_trivially_constructible_type (^^MoveConsOnlyType, { ^^const MoveConsOnlyType & }));
static_assert (is_trivially_constructible_type (^^ClassType, { ^^DerivedType }));
static_assert (is_trivially_constructible_type (^^ClassType, { ^^DerivedType & }));
static_assert (is_trivially_constructible_type (^^ClassType, { ^^DerivedType && }));
static_assert (is_trivially_constructible_type (^^ClassType, { ^^const DerivedType & }));
static_assert (!is_trivially_constructible_type (^^HasTemplateCCtor, {}));
static_assert (!is_trivially_constructible_type (^^HasTemplateCCtor, { ^^HasTemplateCCtor }));
static_assert (is_trivially_constructible_type (^^HasTemplateCCtor, { ^^const HasTemplateCCtor & }));
static_assert (!is_trivially_constructible_type (^^MoveOnly, {}));
static_assert (is_trivially_constructible_type (^^MoveOnly, { ^^MoveOnly }));
static_assert (!is_trivially_constructible_type (^^MoveOnly, { ^^MoveOnly & }));
static_assert (is_trivially_constructible_type (^^MoveOnly, { ^^MoveOnly && }));
static_assert (!is_trivially_constructible_type (^^MoveOnly, { ^^const MoveOnly & }));
static_assert (!is_trivially_constructible_type (^^MoveOnly2, {}));
static_assert (!is_trivially_constructible_type (^^int [], {}));
static_assert (is_nothrow_constructible_type (^^NoexceptExplicitClass, { ^^double & }));
static_assert (is_nothrow_constructible_type (^^NoexceptExplicitClass, { ^^int & }));
static_assert (is_nothrow_constructible_type (^^NoexceptExplicitClass, { ^^double &, ^^int &, ^^double & }));
static_assert (is_nothrow_constructible_type (^^NothrowExplicitClass, { ^^double & }));
static_assert (is_nothrow_constructible_type (^^NothrowExplicitClass, { ^^int & }));
static_assert (is_nothrow_constructible_type (^^NothrowExplicitClass, { ^^double &, ^^int &, ^^double & }));
static_assert (is_nothrow_constructible_type (^^int [1], {}));
static_assert (!is_nothrow_constructible_type (^^NoexceptExplicitClass, { ^^void * }));
static_assert (!is_nothrow_constructible_type (^^NoexceptExplicitClass, {}));
static_assert (!is_nothrow_constructible_type (^^NoexceptExplicitClass, { ^^int, ^^double }));
static_assert (!is_nothrow_constructible_type (^^NothrowExplicitClass, { ^^void * }));
static_assert (!is_nothrow_constructible_type (^^NothrowExplicitClass, {}));
static_assert (!is_nothrow_constructible_type (^^NothrowExplicitClass, { ^^int, ^^double }));
static_assert (!is_nothrow_constructible_type (^^ExceptExplicitClass, { ^^double & }));
static_assert (!is_nothrow_constructible_type (^^ExceptExplicitClass, { ^^int & }));
static_assert (!is_nothrow_constructible_type (^^ExceptExplicitClass, { ^^double &, ^^int &, ^^double & }));
static_assert (!is_nothrow_constructible_type (^^int [], {}));
static_assert (is_nothrow_constructible_type (^^int [1], {}));
static_assert (is_nothrow_constructible_type (^^int [1], { ^^int }));
static_assert (is_nothrow_constructible_type (^^int [2], { ^^int }));
static_assert (is_nothrow_constructible_type (^^int [2], { ^^int, ^^int }));
static_assert (!is_nothrow_constructible_type (^^int [1], { ^^int, ^^int }));
static_assert (!is_nothrow_constructible_type (^^int [], {}));
static_assert (!is_nothrow_constructible_type (^^int [], { ^^int }));
static_assert (!is_nothrow_constructible_type (^^int [], { ^^int, ^^int }));
static_assert (is_nothrow_constructible_type (^^X [2], {}));
static_assert (is_nothrow_constructible_type (^^X [1], { ^^X }));
static_assert (is_nothrow_constructible_type (^^X [1], { ^^int }));
static_assert (!is_nothrow_constructible_type (^^X [1], { ^^double }));
static_assert (!is_nothrow_constructible_type (^^X [2], { ^^int, ^^double }));
static_assert (is_nothrow_constructible_type (^^Y, {}));
static_assert (is_nothrow_constructible_type (^^Y, { ^^Y }));
static_assert (is_nothrow_constructible_type (^^Y, { ^^int }));
static_assert (!is_nothrow_constructible_type (^^Y, { ^^X }));
static_assert (is_nothrow_constructible_type (^^Y, { ^^int, ^^X }));
static_assert (is_nothrow_constructible_type (^^Y, { ^^int, ^^int }));
static_assert (!is_nothrow_constructible_type (^^Y, { ^^int, ^^double }));
static_assert (is_nothrow_constructible_type (^^Z, {}));
static_assert (is_nothrow_constructible_type (^^Z, { ^^Z }));
static_assert (is_nothrow_constructible_type (^^Z, { ^^Y }));
static_assert (!is_nothrow_constructible_type (^^Z, { ^^int }));
static_assert (!is_nothrow_constructible_type (^^Z, { ^^int, ^^X }));
static_assert (!is_nothrow_constructible_type (^^Z, { ^^int, ^^int }));
static_assert (!is_nothrow_constructible_type (^^Z, { ^^Y, ^^double }));
static_assert (!is_nothrow_constructible_type (^^Z, { ^^int, ^^double }));
static_assert (!is_nothrow_constructible_type (^^Z, { ^^X }));
using func_type_v0 = void (*) ();
using func_type_i0 = int (*) ();
using func_type_l0 = int &(*) ();
using func_type_ii = int (*) (int);
using func_type_il = int (*) (int &);
using func_type_ir = int (*) (int &&);
struct W { };
using mem_type_i = int W::*;
using memfun_type_i = int (W::*) ();
using memfun_type_iic = int &(W::*) (int &) const;
struct F {
int &operator () ();
long &operator () () const;
short &operator () (int) &&;
char &operator () (int) const &;
private:
void operator () (int, int);
};
using CF = const F;
struct T { T (int) { } };
struct NT { NT (int) noexcept { } };
struct Ex { explicit Ex (int) noexcept { } };
using func_type = void (*) ();
using func_type_nt = void (*) () noexcept;
using mem_type = int W::*;
using memfun_type = int (W::*) ();
using memfun_type_nt = int (W::*) () noexcept;
struct F2 {
int &operator () ();
long &operator () () const noexcept;
short &operator () (int) &&;
char &operator () (int) const & noexcept;
private:
void operator () (int, int) noexcept;
};
using CF2 = const F2;
struct FW { W operator () () const noexcept { return {}; } };
struct V { explicit V (W) noexcept; V (...); };
static_assert (is_invocable_type (^^func_type_v0, {}));
static_assert (!is_invocable_type (^^func_type_v0, { ^^int }));
static_assert (is_invocable_type (^^func_type_i0, {}));
static_assert (!is_invocable_type (^^func_type_i0, { ^^int }));
static_assert (is_invocable_type (^^func_type_l0, {}));
static_assert (!is_invocable_type (^^func_type_l0 (int), {}));
static_assert (!is_invocable_type (^^func_type_ii, {}));
static_assert (is_invocable_type (^^func_type_ii, { ^^int }));
static_assert (!is_invocable_type (^^func_type_il, {}));
static_assert (!is_invocable_type (^^func_type_il, { ^^int }));
static_assert (is_invocable_type (^^func_type_il, { ^^int & }));
static_assert (!is_invocable_type (^^func_type_ir, {}));
static_assert (is_invocable_type (^^func_type_ir, { ^^int }));
static_assert (!is_invocable_type (^^func_type_ir, { ^^int & }));
static_assert (!is_invocable_type (^^mem_type_i, {}));
static_assert (!is_invocable_type (^^mem_type_i, { ^^int }));
static_assert (!is_invocable_type (^^mem_type_i, { ^^int & }));
static_assert (is_invocable_type (^^mem_type_i, { ^^W & }));
static_assert (!is_invocable_type (^^memfun_type_i, {}));
static_assert (!is_invocable_type (^^memfun_type_i, { ^^int }));
static_assert (!is_invocable_type (^^memfun_type_i, { ^^int & }));
static_assert (is_invocable_type (^^memfun_type_i, { ^^W & }));
static_assert (is_invocable_type (^^memfun_type_i, { ^^W * }));
static_assert (!is_invocable_type (^^memfun_type_i, { ^^const W & }));
static_assert (!is_invocable_type (^^memfun_type_i, { ^^W &, ^^int }));
static_assert (!is_invocable_type (^^memfun_type_iic, {}));
static_assert (!is_invocable_type (^^memfun_type_iic, { ^^int }));
static_assert (!is_invocable_type (^^memfun_type_iic, { ^^int & }));
static_assert (!is_invocable_type (^^memfun_type_iic, { ^^W &, ^^int }));
static_assert (!is_invocable_type (^^memfun_type_iic, { ^^const W &, ^^int }));
static_assert (!is_invocable_type (^^memfun_type_iic, { ^^const W &, ^^int &, ^^int }));
static_assert (is_invocable_type (^^memfun_type_iic, { ^^const W &, ^^int & }));
static_assert (is_invocable_type (^^memfun_type_iic, { ^^const W *, ^^int & }));
static_assert (!is_invocable_type (^^F, { ^^int, ^^int }));
static_assert (!is_nothrow_invocable_type (^^func_type, {}));
static_assert (is_nothrow_invocable_type (^^func_type_nt, {}));
static_assert (!is_nothrow_invocable_type (^^mem_type, {}));
static_assert (!is_nothrow_invocable_type (^^mem_type, { ^^int }));
static_assert (!is_nothrow_invocable_type (^^mem_type, { ^^int & }));
static_assert (is_nothrow_invocable_type (^^mem_type, { ^^W & }));
static_assert (!is_nothrow_invocable_type (^^memfun_type, {}));
static_assert (!is_nothrow_invocable_type (^^memfun_type, { ^^int }));
static_assert (!is_nothrow_invocable_type (^^memfun_type, { ^^int & }));
static_assert (!is_nothrow_invocable_type (^^memfun_type, { ^^W & }));
static_assert (!is_nothrow_invocable_type (^^memfun_type, { ^^W * }));
static_assert (!is_nothrow_invocable_type (^^memfun_type_nt, {}));
static_assert (!is_nothrow_invocable_type (^^memfun_type_nt, { ^^int }));
static_assert (!is_nothrow_invocable_type (^^memfun_type_nt, { ^^int & }));
static_assert (is_nothrow_invocable_type (^^memfun_type_nt, { ^^W & }));
static_assert (is_nothrow_invocable_type (^^memfun_type_nt, { ^^W * }));
static_assert (!is_nothrow_invocable_type (^^F2, {}));
static_assert (is_nothrow_invocable_type (^^CF2, {}));
static_assert (!is_nothrow_invocable_type (^^F2, { ^^int }));
static_assert (is_nothrow_invocable_type (^^F2 &, { ^^int }));
static_assert (is_nothrow_invocable_type (^^CF2, { ^^int }));
static_assert (is_nothrow_invocable_type (^^CF2 &, { ^^int }));
static_assert (!is_nothrow_invocable_type (^^F2, { ^^int, ^^int }));
static_assert (is_nothrow_invocable_type (^^FW, {}));

View File

@@ -1005,7 +1005,7 @@ namespace ranges
// for use by __range_iter_t below.
template<typename _Tp>
requires is_array_v<_Tp> || __member_begin<_Tp&> || __adl_begin<_Tp&>
auto
constexpr auto
__begin(_Tp& __t)
{
if constexpr (is_array_v<_Tp>)

View File

@@ -269,6 +269,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval size_t size_of(info);
consteval size_t bit_size_of(info);
template<class _R>
concept reflection_range = ranges::input_range<_R>
&& same_as<ranges::range_value_t<_R>, info>
&& same_as<remove_cvref_t<ranges::range_reference_t<_R>>, info>;
// [meta.reflection.result], expression result reflection
template<typename _Tp>
requires (is_copy_constructible_v<_Tp>)
@@ -319,6 +324,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_unbounded_array_type(info);
consteval bool is_scoped_enum_type(info);
template<reflection_range _R = initializer_list<info>>
consteval bool is_constructible_type(info, _R&&);
consteval bool is_default_constructible_type(info);
consteval bool is_copy_constructible_type(info);
consteval bool is_move_constructible_type(info);
@@ -329,6 +336,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_destructible_type(info);
template<reflection_range _R = initializer_list<info>>
consteval bool is_trivially_constructible_type(info, _R&&);
consteval bool is_trivially_default_constructible_type(info);
consteval bool is_trivially_copy_constructible_type(info);
consteval bool is_trivially_move_constructible_type(info);
@@ -338,6 +347,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_trivially_move_assignable_type(info);
consteval bool is_trivially_destructible_type(info);
template<reflection_range _R = initializer_list<info>>
consteval bool is_nothrow_constructible_type(info, _R&&);
consteval bool is_nothrow_default_constructible_type(info);
consteval bool is_nothrow_copy_constructible_type(info);
consteval bool is_nothrow_move_constructible_type(info);
@@ -369,6 +380,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_layout_compatible_type(info, info);
consteval bool is_pointer_interconvertible_base_of_type(info, info);
template<reflection_range _R = initializer_list<info>>
consteval bool is_invocable_type(info, _R&&);
template<reflection_range _R = initializer_list<info>>
consteval bool is_nothrow_invocable_type(info, _R&&);
// associated with [meta.trans.cv], const-volatile modifications
consteval info remove_const(info);
consteval info remove_volatile(info);