Skip to content

<ranges>, <xutility>: Extract _Strategy to simplify code #1419

Description

The Ranges code in <ranges> and <xutility> has a commonly-repeated pattern, where metaprogramming is driven by a chosen "strategy". The code looks like this:

STL/stl/inc/ranges

Lines 830 to 834 in 2b4cf99

if constexpr (_Choice<_Rng>._Strategy == _St::_View) {
return _STD forward<_Rng>(_Range);
} else if constexpr (_Choice<_Rng>._Strategy == _St::_Ref) {
return ref_view{_STD forward<_Rng>(_Range)};
} else if constexpr (_Choice<_Rng>._Strategy == _St::_Subrange) {

STL/stl/inc/xutility

Lines 1088 to 1092 in 2b4cf99

if constexpr (_Choice<_Ty1, _Ty2>._Strategy == _St::_Custom) {
iter_swap(static_cast<_Ty1&&>(_Val1), static_cast<_Ty2&&>(_Val2));
} else if constexpr (_Choice<_Ty1, _Ty2>._Strategy == _St::_Swap) {
_RANGES swap(*static_cast<_Ty1&&>(_Val1), *static_cast<_Ty2&&>(_Val2));
} else if constexpr (_Choice<_Ty1, _Ty2>._Strategy == _St::_Exchange) {

Repeating things like _Choice<_Rng>._Strategy and _Choice<_Ty1, _Ty2>._Strategy for each if constexpr branch is verbose and hard to read. (It's also slightly prone to error; if we keep saying _Choice<_Ty&>._Strategy, we might forget the & somewhere.)

When I implemented the Spaceship CPOs in <compare>, I used an easy way to simplify the code - extracting a constexpr variable. This looks like:

STL/stl/inc/compare

Lines 392 to 395 in 2b4cf99

constexpr _St _Strat = _Choice<_Ty1&, _Ty2&>._Strategy;
if constexpr (_Strat == _St::_Adl) {
return static_cast<strong_ordering>(/* ADL */ strong_order(_Left, _Right));
} else if constexpr (_Strat == _St::_Floating) {

This technique doesn't eliminate all verbosity (any occurrences in requires or noexcept can't use the variable), but it's a strict improvement. I think we should apply this to the <ranges> and <xutility> code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementSomething can be improvedfixedSomething works now, yay!rangesC++20/23 ranges

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions