libstdc++: Specialize ranges::__detail::__box for semiregular types
authorPatrick Palka <ppalka@redhat.com>
Thu, 24 Sep 2020 16:58:39 +0000 (12:58 -0400)
committerPatrick Palka <ppalka@redhat.com>
Thu, 24 Sep 2020 16:58:39 +0000 (12:58 -0400)
commit42907ca9a495a4a535bbd995fa126afb76012023
treead506765bc4ff2bbeb905331e2e096e464c163a5
parent61f7995398a719f2ff91d07e8f8ed6d4413db697
libstdc++: Specialize ranges::__detail::__box for semiregular types

The class template semiregular-box<T> defined in [range.semi.wrap] is
used by a number of views to accomodate non-semiregular subobjects
while ensuring that the overall view remains semiregular.  It provides
a stand-in default constructor, copy assignment operator and move
assignment operator whenever the underlying type lacks them.  The
wrapper derives from std::optional<T> to support default construction
when T is not default constructible.

It would be nice for this wrapper to essentially be a no-op when the
underlying type is already semiregular, but this is currently not the
case due to its use of std::optional<T>, which incurs space overhead
compared to storing just T.

To that end, this patch specializes the semiregular wrapper for
semiregular T.  Compared to the primary template, this specialization
uses less space, and it allows [[no_unique_address]] to optimize away
wrapped data members whose underlying type is empty and semiregular
(e.g. a non-capturing lambda).  This patch also applies
[[no_unique_address]] to the five data members that use the wrapper.

libstdc++-v3/ChangeLog:

* include/std/ranges (__detail::__boxable): Split out the
associated constraints of __box into here.
(__detail::__box): Use the __boxable concept.  Define a leaner
partial specialization for semiregular types.
(single_view::_M_value): Give it [[no_unique_address]].
(filter_view::_M_pred): Likewise.
(transform_view::_M_fun): Likewise.
(take_while_view::_M_pred): Likewise.
(drop_while_view::_M_pred):: Likewise.
* testsuite/std/ranges/adaptors/detail/semiregular_box.cc: New
test.
libstdc++-v3/include/std/ranges
libstdc++-v3/testsuite/std/ranges/adaptors/detail/semiregular_box.cc [new file with mode: 0644]