cpp_define (pfile, "__cpp_constexpr_exceptions=202411L");
cpp_define (pfile, "__cpp_static_assert=202306L");
cpp_define (pfile, "__cpp_placeholder_variables=202306L");
- cpp_define (pfile, "__cpp_structured_bindings=202403L");
+ cpp_define (pfile, "__cpp_structured_bindings=202411L");
cpp_define (pfile, "__cpp_deleted_function=202403L");
cpp_define (pfile, "__cpp_variadic_friend=202403L");
cpp_define (pfile, "__cpp_pack_indexing=202311L");
}
return false;
}
+ tree ve = DECL_VALUE_EXPR (t);
/* Treat __PRETTY_FUNCTION__ inside a template function as
potentially-constant. */
- else if (DECL_PRETTY_FUNCTION_P (t)
- && DECL_VALUE_EXPR (t) == error_mark_node)
+ if (DECL_PRETTY_FUNCTION_P (t) && ve == error_mark_node)
return true;
- return RECUR (DECL_VALUE_EXPR (t), rval);
+ if (DECL_DECOMPOSITION_P (t) && TREE_CODE (ve) == TREE_VEC)
+ return RECUR (TREE_VEC_ELT (ve, 0), rval);
+ return RECUR (ve, rval);
}
if (want_rval
&& (now || !var_in_maybe_constexpr_fn (t))
/* Return std::tuple_element<I,TYPE>::type. */
static tree
-get_tuple_element_type (tree type, unsigned i)
+get_tuple_element_type (tree type, unsigned HOST_WIDE_INT i)
{
tree args = make_tree_vec (2);
TREE_VEC_ELT (args, 0) = build_int_cst (integer_type_node, i);
/* Return e.get<i>() or get<i>(e). */
static tree
-get_tuple_decomp_init (tree decl, unsigned i)
+get_tuple_decomp_init (tree decl, unsigned HOST_WIDE_INT i)
{
tree targs = make_tree_vec (1);
TREE_VEC_ELT (targs, 0) = build_int_cst (integer_type_node, i);
}
}
+/* Append #i to DECL_NAME (decl). */
+
+static void
+set_sb_pack_name (tree decl, unsigned HOST_WIDE_INT i)
+{
+ tree name = DECL_NAME (decl);
+ size_t len = IDENTIFIER_LENGTH (name) + 22;
+ char *n = XALLOCAVEC (char, len);
+ snprintf (n, len, "%s#" HOST_WIDE_INT_PRINT_UNSIGNED,
+ IDENTIFIER_POINTER (name), i);
+ DECL_NAME (decl) = get_identifier (n);
+}
+
/* Finish a decomposition declaration. DECL is the underlying declaration
"e", FIRST is the head of a chain of decls for the individual identifiers
chained through DECL_CHAIN in reverse order and COUNT is the number of
auto_vec<tree, 16> v;
v.safe_grow (count, true);
tree d = first;
+ int pack = -1;
for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
{
v[count - i - 1] = d;
fit_decomposition_lang_decl (d, decl);
+ if (DECL_PACK_P (d))
+ pack = count - i - 1;
}
tree type = TREE_TYPE (decl);
tree eltype = NULL_TREE;
unsigned HOST_WIDE_INT eltscnt = 0;
+ /* Structured binding packs when initializer is non-dependent should
+ have their DECL_VALUE_EXPR set to a TREE_VEC. First two elements
+ of that TREE_VEC are the base and index, what is normally represented
+ as DECL_VALUE_EXPR ARRAY_REF <base, index> where index is the index
+ of the pack first element. The remaining elements of the TREE_VEC
+ are VAR_DECLs for the pack elements. */
+ tree packv = NULL_TREE;
+
if (TREE_CODE (type) == ARRAY_TYPE)
{
tree nelts;
goto error_out;
}
eltscnt = tree_to_uhwi (nelts);
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
{
cnt_mismatch:
auto_diagnostic_group d;
eltype = TREE_TYPE (type);
for (unsigned int i = 0; i < count; i++)
{
+ if ((unsigned) pack == i)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j);
+ maybe_push_decl (t);
+ TREE_TYPE (t) = eltype;
+ layout_decl (t, 0);
+ if (!processing_template_decl)
+ {
+ tree a = unshare_expr (dexp);
+ a = build4 (ARRAY_REF, eltype, a, size_int (j + pack),
+ NULL_TREE, NULL_TREE);
+ SET_DECL_VALUE_EXPR (t, a);
+ DECL_HAS_VALUE_EXPR_P (t) = 1;
+ }
+ }
+ continue;
+ }
TREE_TYPE (v[i]) = eltype;
layout_decl (v[i], 0);
if (processing_template_decl)
continue;
tree t = unshare_expr (dexp);
- t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE);
+ unsigned HOST_WIDE_INT j = i;
+ if (pack != -1 && (unsigned) pack < i)
+ j = i + eltscnt - count;
+ t = build4 (ARRAY_REF, eltype, t, size_int (j), NULL_TREE, NULL_TREE);
SET_DECL_VALUE_EXPR (v[i], t);
DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
}
else if (TREE_CODE (type) == COMPLEX_TYPE)
{
eltscnt = 2;
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
goto cnt_mismatch;
eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
for (unsigned int i = 0; i < count; i++)
{
+ if ((unsigned) pack == i)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j);
+ maybe_push_decl (t);
+ TREE_TYPE (t) = eltype;
+ layout_decl (t, 0);
+ if (!processing_template_decl)
+ {
+ tree a = build1 (pack + j ? IMAGPART_EXPR : REALPART_EXPR, eltype,
+ unshare_expr (dexp));
+ SET_DECL_VALUE_EXPR (t, a);
+ DECL_HAS_VALUE_EXPR_P (t) = 1;
+ }
+ }
+ continue;
+ }
TREE_TYPE (v[i]) = eltype;
layout_decl (v[i], 0);
if (processing_template_decl)
continue;
tree t = unshare_expr (dexp);
- t = build1 (i ? IMAGPART_EXPR : REALPART_EXPR, eltype, t);
+ unsigned HOST_WIDE_INT j = i;
+ if (pack != -1 && (unsigned) pack < i)
+ j = i + eltscnt - count;
+ t = build1 (j ? IMAGPART_EXPR : REALPART_EXPR, eltype, t);
SET_DECL_VALUE_EXPR (v[i], t);
DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
}
error_at (loc, "cannot decompose variable length vector %qT", type);
goto error_out;
}
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
goto cnt_mismatch;
eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
for (unsigned int i = 0; i < count; i++)
{
+ if ((unsigned) pack == i)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j);
+ maybe_push_decl (t);
+ TREE_TYPE (t) = eltype;
+ layout_decl (t, 0);
+ if (!processing_template_decl)
+ {
+ tree a = unshare_expr (dexp);
+ location_t loc = DECL_SOURCE_LOCATION (t);
+ tree s = size_int (j + pack);
+ convert_vector_to_array_for_subscript (loc, &a, s);
+ a = build4 (ARRAY_REF, eltype, a, s,
+ NULL_TREE, NULL_TREE);
+ SET_DECL_VALUE_EXPR (t, a);
+ DECL_HAS_VALUE_EXPR_P (t) = 1;
+ }
+ }
+ continue;
+ }
TREE_TYPE (v[i]) = eltype;
layout_decl (v[i], 0);
if (processing_template_decl)
continue;
tree t = unshare_expr (dexp);
+ unsigned HOST_WIDE_INT j = i;
+ if (pack != -1 && (unsigned) pack < i)
+ j = i + eltscnt - count;
convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]),
- &t, size_int (i));
- t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE);
+ &t, size_int (j));
+ t = build4 (ARRAY_REF, eltype, t, size_int (j), NULL_TREE, NULL_TREE);
SET_DECL_VALUE_EXPR (v[i], t);
DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
}
goto error_out;
}
eltscnt = tree_to_uhwi (tsize);
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
goto cnt_mismatch;
- if (test_p)
+ if (test_p && eltscnt)
return true;
- if (!processing_template_decl && DECL_DECOMP_BASE (decl))
+ if (!processing_template_decl && DECL_DECOMP_BASE (decl) && eltscnt)
{
/* For structured bindings used in conditions we need to evaluate
the conversion of decl (aka e in the standard) to bool or
location_t sloc = input_location;
location_t dloc = DECL_SOURCE_LOCATION (v[i]);
+ if ((unsigned) pack == i)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j);
+ input_location = dloc;
+ tree init = get_tuple_decomp_init (decl, j + pack);
+ tree eltype = (init == error_mark_node ? error_mark_node
+ : get_tuple_element_type (type, j + pack));
+ input_location = sloc;
+
+ if (VOID_TYPE_P (eltype))
+ {
+ error ("%<std::tuple_element<%wu, %T>::type%> is "
+ "%<void%>", j + pack, type);
+ eltype = error_mark_node;
+ }
+ if (init == error_mark_node || eltype == error_mark_node)
+ {
+ inform (dloc, "in initialization of structured binding "
+ "pack %qD", v[pack]);
+ goto error_out;
+ }
+ if (j == 0
+ && !processing_template_decl
+ && TREE_STATIC (decl))
+ {
+ sorry_at (dloc, "mangling of structured binding pack "
+ "elements not implemented yet");
+ goto error_out;
+ }
+ maybe_push_decl (t);
+ /* Save the decltype away before reference collapse. */
+ hash_map_safe_put<hm_ggc> (decomp_type_table, t, eltype);
+ eltype = cp_build_reference_type (eltype, !lvalue_p (init));
+ TREE_TYPE (t) = eltype;
+ layout_decl (t, 0);
+ DECL_HAS_VALUE_EXPR_P (t) = 0;
+ if (!processing_template_decl)
+ {
+ copy_linkage (t, decl);
+ cp_finish_decl (t, init, /*constexpr*/false,
+ /*asm*/NULL_TREE, LOOKUP_NORMAL);
+ }
+ }
+ continue;
+ }
+
+ unsigned HOST_WIDE_INT j = i;
+ if (pack != -1 && (unsigned) pack < i)
+ j = i + eltscnt - count;
input_location = dloc;
- tree init = get_tuple_decomp_init (decl, i);
+ tree init = get_tuple_decomp_init (decl, j);
tree eltype = (init == error_mark_node ? error_mark_node
- : get_tuple_element_type (type, i));
+ : get_tuple_element_type (type, j));
input_location = sloc;
if (VOID_TYPE_P (eltype))
{
- error ("%<std::tuple_element<%u, %T>::type%> is %<void%>",
- i, type);
+ error ("%<std::tuple_element<%wu, %T>::type%> is %<void%>",
+ j, type);
eltype = error_mark_node;
}
if (init == error_mark_node || eltype == error_mark_node)
goto error_out;
else if (btype == NULL_TREE)
{
+ if (pack == 0 && count == 1)
+ {
+ eltscnt = 0;
+ packv = make_tree_vec (2);
+ goto done;
+ }
error_at (loc, "cannot decompose class type %qT without non-static "
"data members", type);
goto error_out;
continue;
else
eltscnt++;
- if (count != eltscnt)
+ if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
goto cnt_mismatch;
tree t = dexp;
if (type != btype)
/*nonnull*/false, tf_warning_or_error);
type = btype;
}
+ unsigned HOST_WIDE_INT j = 0;
unsigned int i = 0;
for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field))
if (TREE_CODE (field) != FIELD_DECL
NULL_TREE);
if (REFERENCE_REF_P (tt))
tt = TREE_OPERAND (tt, 0);
+ if (pack != -1 && j >= (unsigned) pack)
+ {
+ if (j == (unsigned) pack)
+ {
+ packv = make_tree_vec (eltscnt - count + 3);
+ i++;
+ }
+ if (j < (unsigned) pack + eltscnt - (count - 1))
+ {
+ tree t;
+ TREE_VEC_ELT (packv, j + 3 - i) = t = copy_node (v[pack]);
+ set_sb_pack_name (t, j + 1 - i);
+ maybe_push_decl (t);
+ TREE_TYPE (t) = TREE_TYPE (tt);
+ layout_decl (t, 0);
+ if (!processing_template_decl)
+ {
+ SET_DECL_VALUE_EXPR (t, tt);
+ DECL_HAS_VALUE_EXPR_P (t) = 1;
+ }
+ else
+ DECL_HAS_VALUE_EXPR_P (t) = 0;
+ j++;
+ continue;
+ }
+ }
TREE_TYPE (v[i]) = TREE_TYPE (tt);
layout_decl (v[i], 0);
if (!processing_template_decl)
DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
}
i++;
+ j++;
}
+ if (pack != -1 && j == (unsigned) pack)
+ {
+ gcc_checking_assert (eltscnt == count - 1);
+ packv = make_tree_vec (2);
+ }
+ }
+ done:
+ if (packv)
+ {
+ gcc_checking_assert (pack != -1);
+ TREE_VEC_ELT (packv, 0) = decl;
+ TREE_VEC_ELT (packv, 1) = size_int (pack);
+ SET_DECL_VALUE_EXPR (v[pack], packv);
+ DECL_HAS_VALUE_EXPR_P (v[pack]) = 1;
+ DECL_IGNORED_P (v[pack]) = 1;
+ if (!processing_template_decl)
+ for (unsigned int i = 0; i < TREE_VEC_LENGTH (packv) - 2U; ++i)
+ pushdecl (TREE_VEC_ELT (packv, 2 + i));
}
if (processing_template_decl)
{
tree v = DECL_VALUE_EXPR (range_decl);
/* For decomposition declaration get all of the corresponding
declarations out of the way. */
- if (TREE_CODE (v) == ARRAY_REF
- && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+ if ((TREE_CODE (v) == ARRAY_REF
+ && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+ || (TREE_CODE (v) == TREE_VEC
+ && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0))))
{
tree d = range_decl;
- range_decl = TREE_OPERAND (v, 0);
decomp = &decomp_d;
- decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
+ if (TREE_CODE (v) == ARRAY_REF)
+ {
+ range_decl = TREE_OPERAND (v, 0);
+ decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
+ }
+ else
+ {
+ range_decl = TREE_VEC_ELT (v, 0);
+ decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1;
+ }
decomp->decl = d;
bool seen_name_independent_decl = false;
for (unsigned int i = 0; i < decomp->count;
}
/* Helper of cp_parser_simple_declaration, parse a decomposition declaration.
- decl-specifier-seq ref-qualifier [opt] [ identifier-list ]
+ decl-specifier-seq ref-qualifier [opt] [ sb-identifier-list ]
initializer ; */
static tree
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
- /* Parse the identifier-list. */
+ /* Parse the sb-identifier-list. */
auto_vec<cp_expr, 10> v;
bool attr_diagnosed = false;
int first_attr = -1;
+ int pack = -1;
unsigned int cnt = 0;
if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
while (true)
{
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ location_t elloc = cp_lexer_peek_token (parser->lexer)->location;
+ if (!processing_template_decl)
+ error_at (elloc, "structured binding pack outside of template");
+ else if (pack != -1)
+ error_at (elloc,
+ "multiple packs in structured binding declaration");
+ else
+ {
+ if (keyword == RID_MAX
+ && cxx_dialect >= cxx17
+ && cxx_dialect < cxx26)
+ pedwarn (elloc, OPT_Wc__26_extensions,
+ "structured binding packs only available with "
+ "%<-std=c++2c%> or %<-std=gnu++2c%>");
+ pack = cnt;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ }
cp_expr e = cp_parser_identifier (parser);
if (e.get_value () == error_mark_node)
break;
tree attr = NULL_TREE;
if (cp_next_tokens_can_be_std_attribute_p (parser))
{
- if (cxx_dialect >= cxx17 && cxx_dialect < cxx26 && !attr_diagnosed)
+ if (keyword == RID_MAX
+ && cxx_dialect >= cxx17
+ && cxx_dialect < cxx26
+ && !attr_diagnosed)
{
pedwarn (cp_lexer_peek_token (parser->lexer)->location,
OPT_Wc__26_extensions,
&pushed_scope);
tree orig_decl = decl;
- unsigned int i;
+ unsigned int i, j;
cp_expr e;
cp_decl_specifier_seq decl_specs;
clear_decl_specs (&decl_specs);
if (decl_specifiers->storage_class == sc_static)
decl_specs.storage_class = sc_static;
tree prev = decl;
+ j = 0;
FOR_EACH_VEC_ELT (v, i, e)
{
if (i == 0)
prev = decl2;
DECL_DECLARED_CONSTEXPR_P (decl2) = DECL_DECLARED_CONSTEXPR_P (decl);
DECL_DECLARED_CONSTINIT_P (decl2) = DECL_DECLARED_CONSTINIT_P (decl);
+ if (j == (unsigned) pack)
+ {
+ tree dtype = cxx_make_type (DECLTYPE_TYPE);
+ DECLTYPE_TYPE_EXPR (dtype) = decl2;
+ DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (dtype) = 1;
+ SET_TYPE_STRUCTURAL_EQUALITY (dtype);
+ tree type = cxx_make_type (TYPE_PACK_EXPANSION);
+ PACK_EXPANSION_PATTERN (type) = dtype;
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+ PACK_EXPANSION_PARAMETER_PACKS (type) = decl2;
+ TREE_TYPE (decl2) = type;
+ }
}
if (elt_pushed_scope)
pop_scope (elt_pushed_scope);
+ ++j;
}
if (v.is_empty ())
decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
decomp->decl = decl;
}
+ else if (TREE_CODE (v) == TREE_VEC
+ && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0)))
+ {
+ d = TREE_VEC_ELT (v, 0);
+ decomp = &decomp_d;
+ decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1;
+ decomp->decl = decl;
+ }
}
do_range_for_auto_deduction (d, init, decomp);
}
decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
decomp->decl = d;
}
+ else if (TREE_CODE (v) == TREE_VEC
+ && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0)))
+ {
+ tree d = orig_decl;
+ orig_decl = TREE_VEC_ELT (v, 0);
+ decomp = &decomp_d;
+ decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1;
+ decomp->decl = d;
+ }
}
tree auto_node = type_uses_auto (TREE_TYPE (orig_decl));
else if (is_capture_proxy (parm_pack))
{
arg_pack = retrieve_local_specialization (parm_pack);
+ if (DECL_DECOMPOSITION_P (arg_pack))
+ {
+ orig_arg = arg_pack;
+ goto expand_sb_pack;
+ }
if (DECL_PACK_P (arg_pack))
arg_pack = NULL_TREE;
}
+ else if (DECL_DECOMPOSITION_P (parm_pack))
+ {
+ orig_arg = retrieve_local_specialization (parm_pack);
+ expand_sb_pack:
+ gcc_assert (DECL_DECOMPOSITION_P (orig_arg));
+ if (TREE_TYPE (orig_arg) == error_mark_node)
+ return error_mark_node;
+ gcc_assert (DECL_HAS_VALUE_EXPR_P (orig_arg));
+ arg_pack = DECL_VALUE_EXPR (orig_arg);
+ tree vec = make_tree_vec (TREE_VEC_LENGTH (arg_pack) - 2);
+ if (TREE_VEC_LENGTH (vec))
+ memcpy (TREE_VEC_BEGIN (vec), &TREE_VEC_ELT (arg_pack, 2),
+ TREE_VEC_LENGTH (vec) * sizeof (tree));
+ arg_pack = make_node (NONTYPE_ARGUMENT_PACK);
+ ARGUMENT_PACK_ARGS (arg_pack) = vec;
+ }
else
{
int idx;
arg_pack = NULL_TREE;
}
- orig_arg = arg_pack;
+ if (orig_arg == NULL_TREE)
+ orig_arg = arg_pack;
if (arg_pack && TREE_CODE (arg_pack) == ARGUMENT_PACK_SELECT)
arg_pack = ARGUMENT_PACK_SELECT_FROM_PACK (arg_pack);
if (arg_pack)
{
- int my_len =
- TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack));
+ int my_len
+ = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack));
/* Don't bother trying to do a partial substitution with
incomplete packs; we'll try again after deduction. */
/* Update the corresponding argument. */
if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
- TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx) =
- TREE_TYPE (pack);
+ TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx)
+ = TREE_TYPE (pack);
else
TREE_VEC_ELT (args, idx) = TREE_TYPE (pack);
}
tsubst_flags_t tcomplain = complain;
if (VAR_P (t))
tcomplain |= tf_tst_ok;
- type = tsubst (type, args, tcomplain, in_decl);
+ if (DECL_DECOMPOSITION_P (t) && DECL_PACK_P (t))
+ type = NULL_TREE;
+ else
+ type = tsubst (type, args, tcomplain, in_decl);
/* Substituting the type might have recursively instantiated this
same alias (c++/86171). */
if (use_spec_table && gen_tmpl && DECL_ALIAS_TEMPLATE_P (gen_tmpl)
{
DECL_INITIALIZED_P (r) = 0;
DECL_TEMPLATE_INSTANTIATED (r) = 0;
+ if (DECL_DECOMPOSITION_P (t) && DECL_PACK_P (t))
+ {
+ tree dtype = cxx_make_type (DECLTYPE_TYPE);
+ DECLTYPE_TYPE_EXPR (dtype) = r;
+ DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (dtype) = 1;
+ SET_TYPE_STRUCTURAL_EQUALITY (dtype);
+ type = cxx_make_type (TYPE_PACK_EXPANSION);
+ PACK_EXPANSION_PATTERN (type) = dtype;
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+ PACK_EXPANSION_PARAMETER_PACKS (type) = r;
+ }
if (TREE_CODE (type) == FUNCTION_TYPE)
{
/* It may seem that this case cannot occur, since:
if (decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (decl))
{
tree v = DECL_VALUE_EXPR (decl);
- if (TREE_CODE (v) == ARRAY_REF
- && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+ if ((TREE_CODE (v) == ARRAY_REF
+ && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+ || (TREE_CODE (v) == TREE_VEC
+ && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0))))
{
+ v = (TREE_CODE (v) == ARRAY_REF
+ ? TREE_OPERAND (v, 0) : TREE_VEC_ELT (v, 0));
cp_decomp decomp_d = { NULL_TREE, 0 };
- tree d = tsubst_decl (TREE_OPERAND (v, 0), args, complain);
+ tree d = tsubst_decl (v, args, complain);
maybe_push_decl (d);
- d = tsubst_decomp_names (d, TREE_OPERAND (v, 0), args, complain,
+ d = tsubst_decomp_names (d, v, args, complain,
in_decl, &decomp_d);
decomp = true;
if (d == error_mark_node)
++c_inhibit_evaluation_warnings;
/* We only want to compute the number of arguments. */
if (PACK_EXPANSION_P (op))
- expanded = tsubst_pack_expansion (op, args, complain, in_decl);
+ {
+ expanded = NULL_TREE;
+ if (DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (op)))
+ {
+ tree d = PACK_EXPANSION_PATTERN (op);
+ if (DECL_HAS_VALUE_EXPR_P (d))
+ {
+ d = DECL_VALUE_EXPR (d);
+ if (TREE_CODE (d) == TREE_VEC)
+ {
+ tree b = TREE_VEC_ELT (d, 0);
+ if (!type_dependent_expression_p_push (b))
+ {
+ expanded = void_node;
+ len = TREE_VEC_LENGTH (d) - 2;
+ }
+ }
+ }
+ }
+ if (!expanded)
+ expanded = tsubst_pack_expansion (op, args, complain, in_decl);
+ }
else
expanded = tsubst_template_args (ARGUMENT_PACK_ARGS (op),
args, complain, in_decl);
case SIZEOF_EXPR:
if (SIZEOF_EXPR_TYPE_P (expression))
return dependent_type_p (TREE_TYPE (TREE_OPERAND (expression, 0)));
+ if (tree p = TREE_OPERAND (expression, 0))
+ if (PACK_EXPANSION_P (p)
+ && DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (p)))
+ {
+ tree d = PACK_EXPANSION_PATTERN (p);
+ if (DECL_HAS_VALUE_EXPR_P (d))
+ {
+ d = DECL_VALUE_EXPR (d);
+ /* [temp.dep.constexpr]/4:
+ Expressions of the following form are value-dependent:
+ sizeof ... ( identifier )
+ unless the identifier is a structured binding pack whose
+ initializer is not dependent. */
+ if (TREE_CODE (d) == TREE_VEC
+ && !type_dependent_expression_p (TREE_VEC_ELT (d, 0)))
+ return false;
+ }
+ }
/* FALLTHRU */
case ALIGNOF_EXPR:
case TYPEID_EXPR:
tree op = TREE_OPERAND (*tp, 0);
if (code == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (*tp))
op = TREE_TYPE (op);
+ else if (code == SIZEOF_EXPR
+ && PACK_EXPANSION_P (op)
+ && DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (op)))
+ {
+ tree d = PACK_EXPANSION_PATTERN (op);
+ if (DECL_HAS_VALUE_EXPR_P (d))
+ {
+ d = DECL_VALUE_EXPR (d);
+ if (TREE_CODE (d) == TREE_VEC
+ && !type_dependent_expression_p (TREE_VEC_ELT (d, 0)))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+ }
+ }
if (TYPE_P (op))
{
if (dependent_type_p (op))
--- /dev/null
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+struct S { int a, b, c, d; };
+struct T {
+ int a[5];
+ template <int I> int &get () { return a[I]; }
+};
+
+template<> struct std::tuple_size<T> { static const int value = 5; };
+template<int I> struct std::tuple_element<I,T> { using type = int; };
+
+template <int N>
+void
+foo ()
+{
+ auto [a, ...b, c] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ auto [...d] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ auto [...e, f, ...g, h] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "multiple packs in structured binding declaration" "" { target *-*-* } .-2 }
+ auto [i, j, k, l, ...m, n] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "6 names provided for structured binding" "" { target *-*-* } .-2 }
+ // { dg-message "while 'S' decomposes into 4 elements" "" { target *-*-* } .-3 }
+ auto [o, ...p, q, r, s] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ auto [t, u, v, w, x, ...y, z] = T (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "7 names provided for structured binding" "" { target *-*-* } .-2 }
+ // { dg-message "while 'T' decomposes into 5 elements" "" { target *-*-* } .-3 }
+ int aa[] = { 1, 2, 3 };
+ const auto & [ab, ...ac, ad, ae, af] = aa; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "5 names provided for structured binding" "" { target *-*-* } .-2 }
+ // { dg-message "while 'const int \\\[3\\\]' decomposes into 3 elements" "" { target *-*-* } .-3 }
+}
+
+void
+bar ()
+{
+ auto [a, ...b, c, d] = S (); // { dg-error "structured binding pack outside of template" }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+}
--- /dev/null
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct S {
+ int a; long long b; short c;
+ explicit operator bool () const noexcept { return true; }
+};
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+struct T {
+ short c; int a; long long b;
+ template <int I>
+ typename std::tuple_element<I, T>::type &get ();
+ template <int I>
+ typename std::tuple_element<I, const T>::type &get () const;
+ explicit operator bool () const noexcept { return false; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, T> { typedef int type; };
+template <>
+struct std::tuple_element<1, T> { typedef long long type; };
+template <>
+struct std::tuple_element<2, T> { typedef short type; };
+template <>
+std::tuple_element<0, T>::type &T::get <0> () { return a; }
+template <>
+std::tuple_element<1, T>::type &T::get <1> () { return b; }
+template <>
+std::tuple_element<2, T>::type &T::get <2> () { return c; }
+template <>
+struct std::tuple_size<const T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, const T> { typedef const int type; };
+template <>
+struct std::tuple_element<1, const T> { typedef const long long type; };
+template <>
+struct std::tuple_element<2, const T> { typedef const short type; };
+template <>
+std::tuple_element<0, const T>::type &T::get <0> () const { return a; }
+template <>
+std::tuple_element<1, const T>::type &T::get <1> () const { return b; }
+template <>
+std::tuple_element<2, const T>::type &T::get <2> () const { return c; }
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+int
+sum ()
+{
+ return 0;
+}
+
+template <typename T, typename ...A>
+T
+sum (T x, A... y)
+{
+ return x + sum (y...);
+}
+
+template <typename T>
+T
+square (T x)
+{
+ return x * x;
+}
+
+template <typename T>
+T &
+ref (T &x)
+{
+ return x;
+}
+
+using size_t = decltype (sizeof 0);
+
+template <int N>
+size_t
+foo ()
+{
+ S s = S { 1, 2, 3 };
+ auto [sa, sb, sc] = S { 1, 2, 3 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (sa), int>::value, "");
+ static_assert (same_type <decltype (sb), long long>::value, "");
+ static_assert (same_type <decltype (sc), short>::value, "");
+ auto [sd, ...se] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ constexpr size_t ses = sizeof... (se);
+ static_assert (sizeof... (se) == 2, "");
+ static_assert (same_type <decltype (sd), int>::value, "");
+ static_assert (same_type <decltype (se...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (se...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ const auto & [...sf [[]], sg] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sf) == 2, "");
+ static_assert (same_type <decltype (sf...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sf...[1]), const long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sg), const short>::value, "");
+ auto [sh, si, sj [[]], ...sk] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sk) == 0, "");
+ static_assert (same_type <decltype (sh), int>::value, "");
+ static_assert (same_type <decltype (si), long long>::value, "");
+ static_assert (same_type <decltype (sj), short>::value, "");
+ auto && [sl, ...sm [[maybe_unused]], sn] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sm) == 1, "");
+ static_assert (same_type <decltype (sl), int>::value, "");
+ static_assert (same_type <decltype (sm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sn), short>::value, "");
+ auto [...so] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (so) == 3, "");
+ static_assert (same_type <decltype (so...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (so...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (so...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...sp, sq, sr, ss [[maybe_unused]]] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sp) == 0, "");
+ static_assert (same_type <decltype (sq), int>::value, "");
+ static_assert (same_type <decltype (sr), long long>::value, "");
+ static_assert (same_type <decltype (ss), short>::value, "");
+ auto [st, ...su, sv, sw] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (su) == 0, "");
+ static_assert (same_type <decltype (st), int>::value, "");
+ static_assert (same_type <decltype (sv), long long>::value, "");
+ static_assert (same_type <decltype (sw), short>::value, "");
+ if (sa != 1 || sb != 2 || sc != 3
+ || sd != 1 || se...[0] != 2 || se...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sf...[0] != 1 || sf...[1] != 2 || sg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sh != 1 || si != 2 || sj != 3
+ || sl != 1 || sm...[0] != 2 || sn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || so...[0] != 1 || so...[1] != 2 || so...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sq != 1 || sr != 2 || ss != 3
+ || st != 1 || sv != 2 || sw != 3
+ || sum (se...) != 5
+ || sum <decltype (se)...> (se...) != 5
+ || sum (square (square (se))...) != 97
+ || sum (sf...) != 3
+ || sum (sk...) != 0
+ || sum (sm...) != 2
+ || sum (so...) != 6
+ || sum <decltype (so)...> (so...) != 6
+ || sum (square (so)...) != 14
+ || sum (sp...) != 0
+ || sum (su...) != 0
+ || (se + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + sf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + sk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (sm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (so + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (sp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + su) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ S s2[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
+ int i = 0;
+ for (auto [sx, ...sy [[]]] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sy) == 2, "");
+ static_assert (same_type <decltype (sx), int>::value, "");
+ static_assert (same_type <decltype (sy...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sy...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sx != i * 3 + 1 || sum (sy...) != i * 6 + 5)
+ __builtin_abort ();
+ auto fn1 = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn1 ();
+ auto fn2 = [&sy..., &i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn2 ();
+ auto fn3 = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn4 = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn5 = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn5 ();
+ auto fn6 = [sy..., i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn6 ();
+ auto fn7 = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn8 = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn9 = [&] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn9 ();
+ auto fn10 = [&sy..., &i] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn10 ();
+ auto fn11 = [&] () { auto fn = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn12 = [&sy..., &i] () { auto fn = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn13 = [=] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn13 ();
+ auto fn14 = [sy..., i] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn14 ();
+ auto fn15 = [=] () { auto fn = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn16 = [&sy..., &i] () { auto fn = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ ++i;
+ }
+ i = 0;
+ for (auto [...sz] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (sz) == 3, "");
+ static_assert (same_type <decltype (sz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (sz...) != i * 9 + 6)
+ __builtin_abort ();
+ auto fn = [=] () { if (sum (sz...) != i * 9 + 6) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn ();
+ ++i;
+ }
+ if (auto [...sx, sy] = s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ {
+ static_assert (sizeof... (sx) == 2, "");
+ static_assert (same_type <decltype (sx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sy), short>::value, "");
+ if (sum (sx...) != 3 || sy != 3)
+ __builtin_abort ();
+ }
+ else
+ __builtin_abort ();
+ T t = T { 3, 1, 2 };
+ auto [ta, tb, tc] = T { 3, 1, 2 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (ta), int>::value, "");
+ static_assert (same_type <decltype (tb), long long>::value, "");
+ static_assert (same_type <decltype (tc), short>::value, "");
+ auto [td [[maybe_unused]], ...te] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (te) == 2, "");
+ static_assert (same_type <decltype (td), int>::value, "");
+ static_assert (same_type <decltype (te...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (te...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...tf [[maybe_unused]], tg] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tf) == 2, "");
+ static_assert (same_type <decltype (tf...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tf...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tg), short>::value, "");
+ const auto & [th, ti, tj, ...tk] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (tk) == 0, "");
+ static_assert (same_type <decltype (th), const int>::value, "");
+ static_assert (same_type <decltype (ti), const long long>::value, "");
+ static_assert (same_type <decltype (tj), const short>::value, "");
+ auto [tl [[]], ...tm [[]], tn [[]]] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tm) == 1, "");
+ static_assert (same_type <decltype (tl), int>::value, "");
+ static_assert (same_type <decltype (tm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tn), short>::value, "");
+ auto && [...to] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (to) == 3, "");
+ static_assert (same_type <decltype (to...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (to...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (to...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...tp, tq [[]], tr, ts] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tp) == 0, "");
+ static_assert (same_type <decltype (tq), int>::value, "");
+ static_assert (same_type <decltype (tr), long long>::value, "");
+ static_assert (same_type <decltype (ts), short>::value, "");
+ auto [tt, ...tu [[]], tv, tw] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tu) == 0, "");
+ static_assert (same_type <decltype (tt), int>::value, "");
+ static_assert (same_type <decltype (tv), long long>::value, "");
+ static_assert (same_type <decltype (tw), short>::value, "");
+ if (ta != 1 || tb != 2 || tc != 3
+ || td != 1 || te...[0] != 2 || te...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || tf...[0] != 1 || tf...[1] != 2 || tg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || th != 1 || ti != 2 || tj != 3
+ || tl != 1 || tm...[0] != 2 || tn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || to...[0] != 1 || to...[1] != 2 || to...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || tq != 1 || tr != 2 || ts != 3
+ || tt != 1 || tv != 2 || tw != 3
+ || sum (te...) != 5
+ || sum <decltype (te)...> (te...) != 5
+ || sum (square (square (te))...) != 97
+ || sum (tf...) != 3
+ || sum (tk...) != 0
+ || sum (tm...) != 2
+ || sum (to...) != 6
+ || sum <decltype (to)...> (to...) != 6
+ || sum (square (to)...) != 14
+ || sum (tp...) != 0
+ || sum (tu...) != 0
+ || (te + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + tf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + tk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (tm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (to + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (tp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + tu) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ T t2[] = { { 3, 1, 2 }, { 6, 4, 5 }, { 9, 7, 8 } };
+ i = 0;
+ for (auto [tx, ...ty] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ty) == 2, "");
+ static_assert (same_type <decltype (tx), int>::value, "");
+ static_assert (same_type <decltype (ty...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ty...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (tx != i * 3 + 1 || sum (ty...) != i * 6 + 5)
+ __builtin_abort ();
+ auto fn1 = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+ fn1 ();
+ auto fn2 = [&ty..., &i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn2 ();
+ auto fn3 = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn4 = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn5 = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+ fn5 ();
+ auto fn6 = [ty..., i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn6 ();
+ auto fn7 = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn8 = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn9 = [&] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); };
+ fn9 ();
+ auto fn10 = [&ty..., &i] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn10 ();
+ auto fn11 = [&] () { auto fn = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn12 = [&ty..., &i] () { auto fn = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn13 = [=] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); };
+ fn13 ();
+ auto fn14 = [ty..., i] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn14 ();
+ auto fn15 = [=] () { auto fn = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn16 = [&ty..., &i] () { auto fn = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ ++i;
+ }
+ i = 0;
+ for (auto [...tz] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (tz) == 3, "");
+ static_assert (same_type <decltype (tz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (tz...) != i * 9 + 6)
+ __builtin_abort ();
+ auto fn = [=] () { if (sum (tz...) != i * 9 + 6) __builtin_abort (); };
+ fn ();
+ ++i;
+ }
+ if (auto [...tx [[maybe_unused]], ty] = t) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ __builtin_abort ();
+ else
+ {
+ static_assert (sizeof... (tx) == 2, "");
+ static_assert (same_type <decltype (tx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ty), short>::value, "");
+ if (sum (tx...) != 3 || ty != 3)
+ __builtin_abort ();
+ }
+ int a[3] = { 1, 2, 3 };
+ auto [aa, ab, ac] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (aa), int>::value, "");
+ static_assert (same_type <decltype (ab), int>::value, "");
+ static_assert (same_type <decltype (ac), int>::value, "");
+ auto [ad [[maybe_unused]], ...ae [[maybe_unused]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ae) == 2, "");
+ static_assert (same_type <decltype (ad), int>::value, "");
+ static_assert (same_type <decltype (ae...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ae...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...af, ag] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (af) == 2, "");
+ static_assert (same_type <decltype (af...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (af...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ag), int>::value, "");
+ auto [ah, ai [[]], aj, ...ak [[]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ak) == 0, "");
+ static_assert (same_type <decltype (ah), int>::value, "");
+ static_assert (same_type <decltype (ai), int>::value, "");
+ static_assert (same_type <decltype (aj), int>::value, "");
+ auto [al, ...am [[]], an] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (am) == 1, "");
+ static_assert (same_type <decltype (al), int>::value, "");
+ static_assert (same_type <decltype (am...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (an), int>::value, "");
+ const auto &[...ao] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ao) == 3, "");
+ static_assert (same_type <decltype (ao...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ao...[1]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ao...[2]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto &&[...ap, aq, ar [[]], as] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ap) == 0, "");
+ static_assert (same_type <decltype (aq), int>::value, "");
+ static_assert (same_type <decltype (ar), int>::value, "");
+ static_assert (same_type <decltype (as), int>::value, "");
+ auto [at, ...au, av, aw] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (au) == 0, "");
+ static_assert (same_type <decltype (at), int>::value, "");
+ static_assert (same_type <decltype (av), int>::value, "");
+ static_assert (same_type <decltype (aw), int>::value, "");
+ if (aa != 1 || ab != 2 || ac != 3
+ || ad != 1 || ae...[0] != 2 || ae...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || af...[0] != 1 || af...[1] != 2 || ag != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || ah != 1 || ai != 2 || aj != 3
+ || al != 1 || am...[0] != 2 || an != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || ao...[0] != 1 || ao...[1] != 2 || ao...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || aq != 1 || ar != 2 || as != 3
+ || at != 1 || av != 2 || aw != 3
+ || sum (ae...) != 5
+ || sum <decltype (ae)...> (ae...) != 5
+ || sum (square (square (ae))...) != 97
+ || sum (af...) != 3
+ || sum (ak...) != 0
+ || sum (am...) != 2
+ || sum (ao...) != 6
+ || sum <decltype (ao)...> (ao...) != 6
+ || sum (square (ao)...) != 14
+ || sum (ap...) != 0
+ || sum (au...) != 0
+ || (ae + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + af) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + ak) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (am + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (ao + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (ap + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + au) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ return ses;
+}
+
+int
+main ()
+{
+ if (foo <0> () != 2)
+ __builtin_abort ();
+}
--- /dev/null
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct S {
+ int a; long long b; short c;
+ explicit operator bool () const noexcept { return true; }
+};
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+struct T {
+ short c; int a; long long b;
+ template <int I>
+ typename std::tuple_element<I, T>::type &get ();
+ template <int I>
+ typename std::tuple_element<I, const T>::type &get () const;
+ explicit operator bool () const noexcept { return false; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, T> { typedef int type; };
+template <>
+struct std::tuple_element<1, T> { typedef long long type; };
+template <>
+struct std::tuple_element<2, T> { typedef short type; };
+template <>
+std::tuple_element<0, T>::type &T::get <0> () { return a; }
+template <>
+std::tuple_element<1, T>::type &T::get <1> () { return b; }
+template <>
+std::tuple_element<2, T>::type &T::get <2> () { return c; }
+template <>
+struct std::tuple_size<const T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, const T> { typedef const int type; };
+template <>
+struct std::tuple_element<1, const T> { typedef const long long type; };
+template <>
+struct std::tuple_element<2, const T> { typedef const short type; };
+template <>
+std::tuple_element<0, const T>::type &T::get <0> () const { return a; }
+template <>
+std::tuple_element<1, const T>::type &T::get <1> () const { return b; }
+template <>
+std::tuple_element<2, const T>::type &T::get <2> () const { return c; }
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+int
+sum ()
+{
+ return 0;
+}
+
+template <typename T, typename ...A>
+T
+sum (T x, A... y)
+{
+ return x + sum (y...);
+}
+
+template <typename T>
+T
+square (T x)
+{
+ return x * x;
+}
+
+template <typename T>
+T &
+ref (T &x)
+{
+ return x;
+}
+
+using size_t = decltype (sizeof 0);
+
+template <typename S, typename T, typename U>
+size_t
+foo ()
+{
+ S s = S { 1, 2, 3 };
+ auto [sa, sb, sc] = S { 1, 2, 3 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (sa), int>::value, "");
+ static_assert (same_type <decltype (sb), long long>::value, "");
+ static_assert (same_type <decltype (sc), short>::value, "");
+ auto [sd, ...se] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (se) == 2, "");
+ static_assert (same_type <decltype (sd), int>::value, "");
+ static_assert (same_type <decltype (se...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (se...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ const auto & [...sf [[]], sg] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sf) == 2, "");
+ static_assert (same_type <decltype (sf...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sf...[1]), const long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sg), const short>::value, "");
+ auto [sh, si, sj [[]], ...sk] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sk) == 0, "");
+ static_assert (same_type <decltype (sh), int>::value, "");
+ static_assert (same_type <decltype (si), long long>::value, "");
+ static_assert (same_type <decltype (sj), short>::value, "");
+ auto && [sl, ...sm [[maybe_unused]], sn] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sm) == 1, "");
+ static_assert (same_type <decltype (sl), int>::value, "");
+ static_assert (same_type <decltype (sm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sn), short>::value, "");
+ auto [...so] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (so) == 3, "");
+ static_assert (same_type <decltype (so...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (so...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (so...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...sp, sq, sr, ss [[maybe_unused]]] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sp) == 0, "");
+ static_assert (same_type <decltype (sq), int>::value, "");
+ static_assert (same_type <decltype (sr), long long>::value, "");
+ static_assert (same_type <decltype (ss), short>::value, "");
+ auto [st, ...su, sv, sw] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (su) == 0, "");
+ static_assert (same_type <decltype (st), int>::value, "");
+ static_assert (same_type <decltype (sv), long long>::value, "");
+ static_assert (same_type <decltype (sw), short>::value, "");
+ if (sa != 1 || sb != 2 || sc != 3
+ || sd != 1 || se...[0] != 2 || se...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sf...[0] != 1 || sf...[1] != 2 || sg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sh != 1 || si != 2 || sj != 3
+ || sl != 1 || sm...[0] != 2 || sn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || so...[0] != 1 || so...[1] != 2 || so...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sq != 1 || sr != 2 || ss != 3
+ || st != 1 || sv != 2 || sw != 3
+ || sum (se...) != 5
+ || sum <decltype (se)...> (se...) != 5
+ || sum (square (square (se))...) != 97
+ || sum (sf...) != 3
+ || sum (sk...) != 0
+ || sum (sm...) != 2
+ || sum (so...) != 6
+ || sum <decltype (so)...> (so...) != 6
+ || sum (square (so)...) != 14
+ || sum (sp...) != 0
+ || sum (su...) != 0
+ || (se + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + sf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + sk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (sm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (so + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (sp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + su) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ S s2[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
+ int i = 0;
+ for (auto [sx, ...sy [[]]] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (sy) == 2, "");
+ static_assert (same_type <decltype (sx), int>::value, "");
+ static_assert (same_type <decltype (sy...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sy...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sx != i * 3 + 1 || sum (sy...) != i * 6 + 5)
+ __builtin_abort ();
+ auto fn1 = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn1 ();
+ auto fn2 = [&sy..., &i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn2 ();
+ auto fn3 = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn4 = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn5 = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn5 ();
+ auto fn6 = [sy..., i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn6 ();
+ auto fn7 = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn8 = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn9 = [&] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn9 ();
+ auto fn10 = [&sy..., &i] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn10 ();
+ auto fn11 = [&] () { auto fn = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn12 = [&sy..., &i] () { auto fn = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn13 = [=] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn13 ();
+ auto fn14 = [sy..., i] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn14 ();
+ auto fn15 = [=] () { auto fn = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn16 = [&sy..., &i] () { auto fn = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ ++i;
+ }
+ i = 0;
+ for (auto [...sz] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (sz) == 3, "");
+ static_assert (same_type <decltype (sz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (sz...) != i * 9 + 6)
+ __builtin_abort ();
+ auto fn = [=] () { if (sum (sz...) != i * 9 + 6) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn ();
+ ++i;
+ }
+ if (auto [...sx, sy] = s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ {
+ static_assert (sizeof... (sx) == 2, "");
+ static_assert (same_type <decltype (sx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (sy), short>::value, "");
+ if (sum (sx...) != 3 || sy != 3)
+ __builtin_abort ();
+ }
+ else
+ __builtin_abort ();
+ T t = T { 3, 1, 2 };
+ auto [ta, tb, tc] = T { 3, 1, 2 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (ta), int>::value, "");
+ static_assert (same_type <decltype (tb), long long>::value, "");
+ static_assert (same_type <decltype (tc), short>::value, "");
+ auto [td [[maybe_unused]], ...te] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (te) == 2, "");
+ static_assert (same_type <decltype (td), int>::value, "");
+ static_assert (same_type <decltype (te...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (te...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...tf [[maybe_unused]], tg] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tf) == 2, "");
+ static_assert (same_type <decltype (tf...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tf...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tg), short>::value, "");
+ const auto & [th, ti, tj, ...tk] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (tk) == 0, "");
+ static_assert (same_type <decltype (th), const int>::value, "");
+ static_assert (same_type <decltype (ti), const long long>::value, "");
+ static_assert (same_type <decltype (tj), const short>::value, "");
+ auto [tl [[]], ...tm [[]], tn [[]]] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tm) == 1, "");
+ static_assert (same_type <decltype (tl), int>::value, "");
+ static_assert (same_type <decltype (tm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tn), short>::value, "");
+ auto && [...to] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (to) == 3, "");
+ constexpr size_t tos = sizeof... (to);
+ static_assert (same_type <decltype (to...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (to...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (to...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...tp, tq [[]], tr, ts] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tp) == 0, "");
+ static_assert (same_type <decltype (tq), int>::value, "");
+ static_assert (same_type <decltype (tr), long long>::value, "");
+ static_assert (same_type <decltype (ts), short>::value, "");
+ auto [tt, ...tu [[]], tv, tw] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (tu) == 0, "");
+ static_assert (same_type <decltype (tt), int>::value, "");
+ static_assert (same_type <decltype (tv), long long>::value, "");
+ static_assert (same_type <decltype (tw), short>::value, "");
+ if (ta != 1 || tb != 2 || tc != 3
+ || td != 1 || te...[0] != 2 || te...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || tf...[0] != 1 || tf...[1] != 2 || tg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || th != 1 || ti != 2 || tj != 3
+ || tl != 1 || tm...[0] != 2 || tn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || to...[0] != 1 || to...[1] != 2 || to...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || tq != 1 || tr != 2 || ts != 3
+ || tt != 1 || tv != 2 || tw != 3
+ || sum (te...) != 5
+ || sum <decltype (te)...> (te...) != 5
+ || sum (square (square (te))...) != 97
+ || sum (tf...) != 3
+ || sum (tk...) != 0
+ || sum (tm...) != 2
+ || sum (to...) != 6
+ || sum <decltype (to)...> (to...) != 6
+ || sum (square (to)...) != 14
+ || sum (tp...) != 0
+ || sum (tu...) != 0
+ || (te + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + tf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + tk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (tm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (to + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (tp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + tu) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ T t2[] = { { 3, 1, 2 }, { 6, 4, 5 }, { 9, 7, 8 } };
+ i = 0;
+ for (auto [tx, ...ty] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ty) == 2, "");
+ static_assert (same_type <decltype (tx), int>::value, "");
+ static_assert (same_type <decltype (ty...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ty...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (tx != i * 3 + 1 || sum (ty...) != i * 6 + 5)
+ __builtin_abort ();
+ auto fn1 = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+ fn1 ();
+ auto fn2 = [&ty..., &i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn2 ();
+ auto fn3 = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn4 = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn5 = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+ fn5 ();
+ auto fn6 = [ty..., i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn6 ();
+ auto fn7 = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn8 = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn9 = [&] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); };
+ fn9 ();
+ auto fn10 = [&ty..., &i] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn10 ();
+ auto fn11 = [&] () { auto fn = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn12 = [&ty..., &i] () { auto fn = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ auto fn13 = [=] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); };
+ fn13 ();
+ auto fn14 = [ty..., i] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } }
+ fn14 ();
+ auto fn15 = [=] () { auto fn = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto fn16 = [&ty..., &i] () { auto fn = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } }
+ fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 }
+ ++i;
+ }
+ i = 0;
+ for (auto [...tz] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (tz) == 3, "");
+ static_assert (same_type <decltype (tz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (tz...) != i * 9 + 6)
+ __builtin_abort ();
+ auto fn = [=] () { if (sum (tz...) != i * 9 + 6) __builtin_abort (); };
+ fn ();
+ ++i;
+ }
+ if (auto [...tx [[maybe_unused]], ty] = t) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ __builtin_abort ();
+ else
+ {
+ static_assert (sizeof... (tx) == 2, "");
+ static_assert (same_type <decltype (tx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (tx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ty), short>::value, "");
+ if (sum (tx...) != 3 || ty != 3)
+ __builtin_abort ();
+ }
+ U a[3] = { 1, 2, 3 };
+ auto [aa, ab, ac] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ static_assert (same_type <decltype (aa), int>::value, "");
+ static_assert (same_type <decltype (ab), int>::value, "");
+ static_assert (same_type <decltype (ac), int>::value, "");
+ auto [ad [[maybe_unused]], ...ae [[maybe_unused]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ae) == 2, "");
+ static_assert (same_type <decltype (ad), int>::value, "");
+ static_assert (same_type <decltype (ae...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ae...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...af, ag] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (af) == 2, "");
+ static_assert (same_type <decltype (af...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (af...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ag), int>::value, "");
+ auto [ah, ai [[]], aj, ...ak [[]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ak) == 0, "");
+ static_assert (same_type <decltype (ah), int>::value, "");
+ static_assert (same_type <decltype (ai), int>::value, "");
+ static_assert (same_type <decltype (aj), int>::value, "");
+ auto [al, ...am [[]], an] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (am) == 1, "");
+ static_assert (same_type <decltype (al), int>::value, "");
+ static_assert (same_type <decltype (am...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (an), int>::value, "");
+ const auto &[...ao] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ao) == 3, "");
+ static_assert (same_type <decltype (ao...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ao...[1]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ao...[2]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto &&[...ap, aq, ar [[]], as] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 }
+ static_assert (sizeof... (ap) == 0, "");
+ static_assert (same_type <decltype (aq), int>::value, "");
+ static_assert (same_type <decltype (ar), int>::value, "");
+ static_assert (same_type <decltype (as), int>::value, "");
+ auto [at, ...au, av, aw] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (au) == 0, "");
+ static_assert (same_type <decltype (at), int>::value, "");
+ static_assert (same_type <decltype (av), int>::value, "");
+ static_assert (same_type <decltype (aw), int>::value, "");
+ if (aa != 1 || ab != 2 || ac != 3
+ || ad != 1 || ae...[0] != 2 || ae...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || af...[0] != 1 || af...[1] != 2 || ag != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || ah != 1 || ai != 2 || aj != 3
+ || al != 1 || am...[0] != 2 || an != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || ao...[0] != 1 || ao...[1] != 2 || ao...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || aq != 1 || ar != 2 || as != 3
+ || at != 1 || av != 2 || aw != 3
+ || sum (ae...) != 5
+ || sum <decltype (ae)...> (ae...) != 5
+ || sum (square (square (ae))...) != 97
+ || sum (af...) != 3
+ || sum (ak...) != 0
+ || sum (am...) != 2
+ || sum (ao...) != 6
+ || sum <decltype (ao)...> (ao...) != 6
+ || sum (square (ao)...) != 14
+ || sum (ap...) != 0
+ || sum (au...) != 0
+ || (ae + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + af) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + ak) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (am + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (ao + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (ap + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + au) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ return tos;
+}
+
+int
+main ()
+{
+ if (foo <S, T, int> () != 3)
+ __builtin_abort ();
+}
--- /dev/null
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+int
+sum ()
+{
+ return 0;
+}
+
+template <typename T, typename ...A>
+T
+sum (T x, A... y)
+{
+ return x + sum (y...);
+}
+
+template <typename T>
+T
+square (T x)
+{
+ return x * x;
+}
+
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+typedef int V __attribute__((vector_size (16 * sizeof (int))));
+
+template <int N>
+void
+foo ()
+{
+ V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+ auto [...va] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (va) == 16, "");
+ static_assert (same_type <decltype (va...[5]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (va...[13]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [vb, ...vc, vd, ve] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vc) == 13, "");
+ static_assert (same_type <decltype (vb), int>::value, "");
+ static_assert (same_type <decltype (vc...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vc...[12]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vd), int>::value, "");
+ static_assert (same_type <decltype (ve), int>::value, "");
+ auto [vf, vg, vh, vi, ...vj] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vj) == 12, "");
+ static_assert (same_type <decltype (vf), int>::value, "");
+ static_assert (same_type <decltype (vg), int>::value, "");
+ static_assert (same_type <decltype (vh), int>::value, "");
+ static_assert (same_type <decltype (vi), int>::value, "");
+ static_assert (same_type <decltype (vj...[2]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vj...[10]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (va...[13] != 14 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (va...) != 8 * 17
+ || sum (square (va)...) != 1496
+ || vb != 1
+ || vc...[10] != 12 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (vc...) != 15 * 7 - 1
+ || sum <decltype (vc)...> (vc...) != 15 * 7 - 1
+ || vd != 15 || ve != 16
+ || vf != 1 || vg != 2 || vh != 3 || vi != 4
+ || sum (vj...) != 8 * 17 - 10
+ || (va + ...) != 8 * 17 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + vc) != 15 * 7 - 1 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + vj) != 8 * 17 - 10) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ V v2[3] = { v, v + 1, v + 2 };
+ int i = 0;
+ for (auto [vk, ...vl, vm] : v2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vl) == 14, "");
+ static_assert (same_type <decltype (vk), int>::value, "");
+ static_assert (same_type <decltype (vl...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vl...[9]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vm), int>::value, "");
+ if (vk != i + 1 || sum (vl...) != i * 14 + 15 * 8 - 1 || vm != i + 16)
+ __builtin_abort ();
+ ++i;
+ }
+ _Complex double c = 1.0 + 2.0i;
+ auto [...ca] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ca) == 2, "");
+ static_assert (same_type <decltype (ca...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ca...[1]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [cb, ...cc, cd] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cc) == 0, "");
+ static_assert (same_type <decltype (cb), double>::value, "");
+ static_assert (same_type <decltype (cd), double>::value, "");
+ auto [ce, ...cf] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cf) == 1, "");
+ static_assert (same_type <decltype (ce), double>::value, "");
+ static_assert (same_type <decltype (cf...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...cg, ch] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cg) == 1, "");
+ static_assert (same_type <decltype (cg...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ch), double>::value, "");
+ if (ca...[0] != 1.0 || ca...[1] != 2.0// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (ca...) != 3.0
+ || sum <decltype (ca)...> (ca...) != 3.0
+ || sum (square (square (square (ca)))...) != 257.0
+ || cb != 1.0 || cd != 2.0
+ || ce != 1.0 || cf...[0] != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (cf...) != 2.0
+ || cg...[0] != 1.0 || ch != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (cg...) != 1.0
+ || (ca + ...) != 3.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0.0 + ... + cc) != 0.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + cf) != 2.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (cg + ... + 0.0) != 1.0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ _Complex float c2[3] = { 1.0f + 2.0fi, 2.0f + 3.0fi, 3.0f + 4.0fi };
+ i = 0;
+ for (auto [...ci] : c2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ci) == 2, "");
+ static_assert (same_type <decltype (ci...[0]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ci...[1]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (ci...) != i * 2 + 3.0f)
+ __builtin_abort ();
+ ++i;
+ }
+}
+
+template <typename V, typename C, typename D>
+void
+bar ()
+{
+ V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+ auto [...va] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (va) == 16, "");
+ static_assert (same_type <decltype (va...[5]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (va...[13]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [vb, ...vc, vd, ve] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vc) == 13, "");
+ static_assert (same_type <decltype (vb), int>::value, "");
+ static_assert (same_type <decltype (vc...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vc...[12]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vd), int>::value, "");
+ static_assert (same_type <decltype (ve), int>::value, "");
+ auto [vf, vg, vh, vi, ...vj] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vj) == 12, "");
+ static_assert (same_type <decltype (vf), int>::value, "");
+ static_assert (same_type <decltype (vg), int>::value, "");
+ static_assert (same_type <decltype (vh), int>::value, "");
+ static_assert (same_type <decltype (vi), int>::value, "");
+ static_assert (same_type <decltype (vj...[2]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vj...[10]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (va...[13] != 14 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (va...) != 8 * 17
+ || vb != 1
+ || vc...[10] != 12 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (vc...) != 15 * 7 - 1
+ || sum <decltype (vc)...> (vc...) != 15 * 7 - 1
+ || vd != 15 || ve != 16
+ || vf != 1 || vg != 2 || vh != 3 || vi != 4
+ || sum (vj...) != 8 * 17 - 10
+ || (va + ...) != 8 * 17 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + vc) != 15 * 7 - 1 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0 + ... + vj) != 8 * 17 - 10) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ V v2[3] = { v, v + 1, v + 2 };
+ int i = 0;
+ for (auto [vk, ...vl, vm] : v2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (vl) == 14, "");
+ static_assert (same_type <decltype (vk), int>::value, "");
+ static_assert (same_type <decltype (vl...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vl...[9]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (vm), int>::value, "");
+ if (vk != i + 1 || sum (vl...) != i * 14 + 15 * 8 - 1 || vm != i + 16)
+ __builtin_abort ();
+ ++i;
+ }
+ C c = 1.0 + 2.0i;
+ auto [...ca] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ca) == 2, "");
+ static_assert (same_type <decltype (ca...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ca...[1]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [cb, ...cc, cd] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cc) == 0, "");
+ static_assert (same_type <decltype (cb), double>::value, "");
+ static_assert (same_type <decltype (cd), double>::value, "");
+ auto [ce, ...cf] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cf) == 1, "");
+ static_assert (same_type <decltype (ce), double>::value, "");
+ static_assert (same_type <decltype (cf...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ auto [...cg, ch] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (cg) == 1, "");
+ static_assert (same_type <decltype (cg...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ch), double>::value, "");
+ if (ca...[0] != 1.0 || ca...[1] != 2.0// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (ca...) != 3.0
+ || sum <decltype (ca)...> (ca...) != 3.0
+ || cb != 1.0 || cd != 2.0
+ || ce != 1.0 || cf...[0] != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (cf...) != 2.0
+ || cg...[0] != 1.0 || ch != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ || sum (cg...) != 1.0
+ || (ca + ...) != 3.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (0.0 + ... + cc) != 0.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (... + cf) != 2.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ || (cg + ... + 0.0) != 1.0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+ __builtin_abort ();
+ D c2[3] = { 1.0f + 2.0fi, 2.0f + 3.0fi, 3.0f + 4.0fi };
+ i = 0;
+ for (auto [...ci] : c2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ci) == 2, "");
+ static_assert (same_type <decltype (ci...[0]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ static_assert (same_type <decltype (ci...[1]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ if (sum (ci...) != i * 2 + 3.0f)
+ __builtin_abort ();
+ ++i;
+ }
+}
+
+int
+main ()
+{
+ foo <0> ();
+ bar <V, _Complex double, _Complex float> ();
+}
--- /dev/null
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+typedef int V __attribute__((vector_size (16 * sizeof (int))));
+
+template <int N>
+void
+foo ()
+{
+ V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+ auto [va, vb, vc, vd, ...ve, vf, vg, vh, vi, vj, vk, vl, vm, vn, vo, vp, vq, vr] = v;
+ // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } .-1 }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }
+ // { dg-error "18 names provided for structured binding" "" { target *-*-* } .-3 }
+ // { dg-message "while '__vector\\\(16\\\) int' decomposes into 16 elements" "" { target *-*-* } .-4 }
+ _Complex double c = 1.0 + 2.0i;
+ auto [...ca, cb, cc, cd] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-error "4 names provided for structured binding" "" { target *-*-* } .-2 }
+ // { dg-message "while '__complex__ double' decomposes into 2 elements" "" { target *-*-* } .-3 }
+}
+
+int
+main ()
+{
+ foo <0> ();
+}
--- /dev/null
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct S { int a, b, c; };
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+struct T {
+ int a[3];
+ template <int I>
+ int &get () { return a[2 - I]; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <int N>
+struct std::tuple_element<N, T> { typedef int type; };
+
+template <int N>
+inline int
+foo ()
+{
+ static int a[4] = { N, N + 1, N + 2, N + 3 };
+ static auto [...aa] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 }
+ aa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ return (... + aa); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+bar ()
+{
+ static S s = { N, N + 1, N + 2 };
+ static auto [...sa] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 }
+ sa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ return (sa + ...); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+baz ()
+{
+ static T t = { { N, N + 1, N + 2 } };
+ static auto [ta, ...tb, tc, td] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 }
+ tc++;
+ return ((ta + tc + td) + ... + tb); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+qux ()
+{
+ thread_local int a[4] = { N, N + 1, N + 2, N + 3 };
+ thread_local auto [...aa] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+ aa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ return (... + aa); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+freddy ()
+{
+ thread_local S s = { N, N + 1, N + 2 };
+ thread_local auto [...sa] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+ sa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ return (sa + ...); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+corge ()
+{
+ thread_local T t = { { N, N + 1, N + 2 } };
+ thread_local auto [ta, ...tb, tc, td] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+ tc++;
+ return ((ta + tc + td) + ... + tb); // { dg-warning "fold-expressions only available with" "" { target c++14_down } }
+}
+
+int
+main ()
+{
+ if (foo <2> () != 15 || foo <2> () != 16 || foo <2> () != 17
+ || foo <42> () != 175 || foo <42> () != 176
+ || bar <5> () != 19 || bar <5> () != 20 || bar <5> () != 21
+ || bar <18> () != 58 || bar <18> () != 59
+ || baz <3> () != 13 || baz <3> () != 14 || baz <3> () != 15
+ || baz <22> () != 70 || baz <22> () != 71)
+ __builtin_abort ();
+ if (qux <2> () != 15 || qux <2> () != 16 || qux <2> () != 17
+ || qux <42> () != 175 || qux <42> () != 176
+ || freddy <5> () != 19 || freddy <5> () != 20 || freddy <5> () != 21
+ || freddy <18> () != 58 || freddy <18> () != 59
+ || corge <3> () != 13 || corge <3> () != 14 || corge <3> () != 15
+ || corge <22> () != 70 || corge <22> () != 71)
+ __builtin_abort ();
+}
--- /dev/null
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+struct T {
+ int a[3];
+ template <int I>
+ int &get () { return a[2 - I]; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <int N>
+struct std::tuple_element<N, T> { typedef int type; };
+
+template <int N>
+inline void
+foo ()
+{
+ static T t = { { N, N + 1, N + 2 } };
+ static auto [ta, ...tb, tc] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 }
+ // { dg-message "mangling of structured binding pack elements not implemented yet" "" { target *-*-* } .-3 }
+}
+
+template <int N>
+inline void
+bar ()
+{
+ thread_local T t = { { N, N + 1, N + 2 } };
+ thread_local auto [...ta] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+ // { dg-message "mangling of structured binding pack elements not implemented yet" "" { target *-*-* } .-3 }
+}
+
+int
+main ()
+{
+ foo <0> ();
+ bar <0> ();
+}
--- /dev/null
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct S {
+ explicit operator bool () const noexcept { return true; }
+};
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+int x;
+struct T {
+ template <int I>
+ int &get () { return x; }
+ explicit operator bool () const noexcept { return false; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 0; };
+template <int N>
+struct std::tuple_element<N, T> { typedef int type; };
+
+template <int N>
+void
+foo ()
+{
+ int a[0] = {};
+ auto [...aa] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (aa) == 0, "");
+ S s = {};
+ auto [...sa] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (sa) == 0, "");
+ T t = {};
+ auto [...ta] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (ta) == 0, "");
+ if (auto [...sb] = s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ static_assert (sizeof... (sb) == 0, "");
+ else
+ __builtin_abort ();
+ if (auto [...tb] = t) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } }
+ __builtin_abort ();
+ else
+ static_assert (sizeof... (tb) == 0, "");
+}
+
+int
+main ()
+{
+ foo <0> ();
+}
--- /dev/null
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+using size_t = decltype (sizeof 0);
+
+auto g () -> int (&)[4]
+{
+ static int a[4] = { 1, 2, 3, 4 };
+ return a;
+}
+
+template <size_t N>
+void
+h (int (&arr)[N])
+{
+ auto [a, ...b, c] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (b) == 2, "");
+ auto &[f, ...g, h] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (g) == 2, "");
+ if (&f != &arr[0] || &h != &arr[3]
+ || &g...[0] != &arr[1] || &g...[1] != &arr[2]) // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ __builtin_abort ();
+ auto &[...e] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof ... (e) == 4, "");
+ if (&e...[0] != &arr[0] || &e...[3] != &arr[3]) // { dg-warning "pack indexing only available with" "" { target c++23_down } }
+ __builtin_abort ();
+}
+
+struct C { int x, y, z; };
+
+template <class T>
+void
+now_i_know_my ()
+{
+ auto [a, b, c] = C (); // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ auto [d, ...e] = C (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (e) == 2, "");
+ auto [...f, g] = C (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (f) == 2, "");
+ auto [h, i, j, ...k] = C (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (k) == 0, "");
+// auto [l, m, n, o, ...p] = C ();
+}
+
+auto foo () -> int (&)[2]
+{
+ static int a[2] = { 1, 2 };
+ return a;
+}
+
+template <class T>
+void
+bar ()
+{
+ auto [...a] = foo (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (a) == 2, "");
+ auto [b, c, ...d] = foo (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static_assert (sizeof... (d) == 0, "");
+}
+
+struct D { };
+
+void
+baz (...)
+{
+ __builtin_abort ();
+}
+
+template <typename T>
+void
+qux ()
+{
+ D arr[1] = {};
+ auto [...e] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ baz (e...);
+}
+
+int d;
+
+void
+baz (D)
+{
+ d = 1;
+}
+
+int
+main ()
+{
+ h (g ());
+ now_i_know_my <int> ();
+ bar <int> ();
+ qux <int> ();
+}
#ifndef __cpp_structured_bindings
# error "__cpp_structured_bindings"
-#elif __cpp_structured_bindings != 202403
-# error "__cpp_structured_bindings != 202403"
+#elif __cpp_structured_bindings != 202411
+# error "__cpp_structured_bindings != 202411"
#endif
#ifndef __cpp_template_template_args