Hi all, Here is an implementation of std::initializer_list objects that properly own the underlying sequence. This will allow list-initialization for containers like std::vector< std::unique_ptr< T > >, but such library support will come in a subsequent patch if this one is supported.
To summarize the new behavior:
- Partial specialization std::initializer_list< T && > (an “owning initializer
list”) is introduced.
- Such a list provides write access.
- An owned sequence is not eligible for the static-initialization optimization:
its lifetime is always that of the list object.
- An owning list converts to a classic std::initializer_list< T > via the
derived-to-base conversion.
- An owned sequence is destroyed when the list object is, like std::vector.
- Owning lists may transfer ownership by move-construction. The moved-from
state is empty.
- Owning list objects cannot be a nonstatic member or a return value.
- Overload resolution between otherwise-equivalent owning and non-owning
alternatives chooses ownership iff the element type has a nontrivial move
constructor.
- T in std::initializer_list< T && > may be deduced from a list with the same
semantics as in std::initializer_list< T >.
- The destructor of std::initializer_list< T && > has the same exception-safety
and triviality as that of T.
Removed behavior:
- Assignment operators are disabled for all initializer lists. They were
unspecified and usually produced UB. See LWG DR 2432.
Notable non-changes:
- Type deduction never introduces ownership. So, “for ( auto && x : { 1,
getch() } )” will deduce “int const & x”. Saying “auto &” instead will fail.
Internal changes:
- TARGET_EXPR_CLEANUP may be NULL for a nontrivially-destructible object,
indicating that no destructor should run.
- All list objects are built by AGGR_INIT_EXPR (a constructor function call)
instead of CONSTRUCTOR (aggregate initialization). (Guys, those names are
backwards…)
Regtested against r222796 on POWER.
- Cheers,
David
2015-05-06 David Krauss <[email protected]>
Implement owning initializer lists (C++ N4166).
* gcc/cp/call.c
(convert_like_real): Generate sequence-owning std::initializer_list.
(build_list_conv): Allow rvalue reference tag in std::initializer_list.
(compare_ics): Select owning or non-owning std::initializer_list.
(set_up_extended_ref_temp): Respect NULL TARGET_EXPR_CLEANUP.
(extend_ref_init_temps): Detect constructor call for initializer_list.
* gcc/cp/init.c (perform_member_init): Likewise.
* gcc/cp/tree.c (bot_manip): Preserve NULL TARGET_EXPR_CLEANUP.
* gcc/cp/class.c (finish_struct): Accept new <initializer_list> format.
(finish_struct1): Reject owning list nonstatic members.
* gcc/cp/typeck.c (check_return_expr): Flag owning list return values.
* gcc/cp/pt.c (unify): Allow deduction of owning list type from list.
* gcc/cp/search.c (accessible_p): exempt initializer_list from checks.
* gcc/cp/semantics.c (trait_expr_value): std::initializer_list may be
trivially destructible.
* libstdc++-v3/libsupc++/initializer_list (initializer_list<T>):
Disable move assignment. Support non-const access to sequence.
(initializer_list<T&&>): New specialization.
* gcc/testsuite/g++.dg/cpp1z/initlist-owned.C: New testcase.
* gcc/testsuite/g++.dg/cpp1z/initlist-forbidden.C: New testcase.
* gcc/testsuite/g++.dg/cpp1z/initlist-deduce.C: New testcase.
* gcc/testsuite/g++.dg/cpp0x/pr57101.C: Update.
* gcc/testsuite/g++.dg/opt/pr65554.C: Likewise.
* libstdc++-v3/testsuite/20_util/is_assignable/value.cc: Likewise.
* libstdc++-v3/testsuite/util/testsuite_random.h: Likewise.
movil.patch
Description: Binary data
