Add std::views::indices(n)
Revision History
- Since R0
-
- Move
upto
from the std::ranges
namespace into std::views
- Use a more convincing example
- Incorporate with the current
iota
wording in the standard
- Since R1
-
- Change the name
views::upto
to views::indices
.
- Use the
is-integer-like
exposition-only constraint rather than the std::integral
(is-integer-like
allows implementation-defined types and removes bool).
- Since R2
-
Abstract
We propose adding std::views::indices(n)
to the C++ Standard Library as a range adaptor that generates a sequence of integers from 0
to n-1
.
Motivation
Currently, iota(0, ranges::size(rng))
does not compile due to mismatched types (see point 1 in Background section). Then, users need to write a workaround like iota(range_size_t<decltype(rng)>{}, ranges::size(rng))
, which is not straightforward and cumbersome. An example illustrating this issue is available at x8nWxqE9v:
std::views::indices(n)
eases this pattern by providing a straightforward method to generate integer sequences, improving readability and killing arcane code.
Implementation and Usage
Usage:
Implementation: hsP97jKzv
Prior Art
Two preceding proposals have provided fundation for std::views::indices(n)
:
-
P2214R2: A Plan for C++26 Ranges highlights the issue with views::iota(0, r.size())
not compiling due to mismatched types. std::ranges::views::iota
requires both arguments to be of the same type, or at least commonly comparable. This becomes problematic when comparing int
(often 32-bit) with std::size_t
(often 64-bit), which is usually wider on 64-bit systems. The same example from above Motivation section can be viewed at x8nWxqE9v.
-
P1894R0: Proposal of std::upto, std::indices and std::enumerate proposed an implementation (see below) that our proposal refines. Our approach offers a more consistent interface, fitting seamlessly with existing standard library.
Technical Decisions
-
Limiting to is-integer-like
: is-integer-like
allows implementation-defined types and removes bool.
-
Lambda-based Approach: Using a lambda is consistent with the established range adaptor patterns. Moreover, the use of constexpr
allows for the evaluation to occur at compile-time.
-
Leveraging Existing iota_view
Instead of Creating a New indices_view
: Introducing indices_view
would mean adding a component similar to what already exists, causing confusion and maintainability issues for users. By leveraging iota_view
, we simplify the implementation and reuse of what the current C++ Standard Library offers. Additionally, any future optimizations to iota_view
will automatically benefit std::views::indices
. Therefore, by extending iota_view
, std::views::indices
becomes more maintainable, efficient, and simple.
Wording
Add a new paragraph under [range.iota.overview]:
26.6.4.1 Overview [range.iota.overview]
The name views::indices
denotes a customization point object ([customization.point.object]). Given subexpression E
, let T
be remove_cvref_t<decltype((E))>
. views::indices(E)
is expression-equivalent to views::iota(T(0), E)
if T
models is-integer-like
, and ill-formed otherwise.
Modify [ranges.syn] as follows:
// [range.iota], iota view
[...]
namespace views { inline constexpr unspecified iota = unspecified; }
inline constexpr unspecified iota = unspecified;
inline constexpr unspecified indices = unspecified;
}
Feature test macro
Add __cpp_lib_ranges_indices
to [version.syn]:
#define __cpp_lib_ranges_indices 202XXXL // also in <ranges>
References
Zhihao Yuan <[email protected]>
Add std::views::indices(n)
Revision History
upto
from thestd::ranges
namespace intostd::views
iota
wording in the standardviews::upto
toviews::indices
.is-integer-like
exposition-only constraint rather than thestd::integral
(is-integer-like
allows implementation-defined types and removes bool).Abstract
We propose adding
std::views::indices(n)
to the C++ Standard Library as a range adaptor that generates a sequence of integers from0
ton-1
.Motivation
Currently,
iota(0, ranges::size(rng))
does not compile due to mismatched types (see point 1 in Background section). Then, users need to write a workaround likeiota(range_size_t<decltype(rng)>{}, ranges::size(rng))
, which is not straightforward and cumbersome. An example illustrating this issue is available at x8nWxqE9v:C++23
P3060
std::views::indices(n)
eases this pattern by providing a straightforward method to generate integer sequences, improving readability and killing arcane code.Implementation and Usage
Usage:
Implementation: hsP97jKzv
Prior Art
Two preceding proposals have provided fundation for
std::views::indices(n)
:P2214R2: A Plan for C++26 Ranges[1] highlights the issue with
views::iota(0, r.size())
not compiling due to mismatched types.std::ranges::views::iota
requires both arguments to be of the same type, or at least commonly comparable. This becomes problematic when comparingint
(often 32-bit) withstd::size_t
(often 64-bit), which is usually wider on 64-bit systems. The same example from above Motivation section can be viewed at x8nWxqE9v.P1894R0: Proposal of std::upto, std::indices and std::enumerate[2] proposed an implementation (see below) that our proposal refines. Our approach offers a more consistent interface, fitting seamlessly with existing standard library.
Technical Decisions
Limiting to
is-integer-like
:is-integer-like
allows implementation-defined types and removes bool.Lambda-based Approach: Using a lambda is consistent with the established range adaptor patterns. Moreover, the use of
constexpr
allows for the evaluation to occur at compile-time.Leveraging Existing
iota_view
Instead of Creating a Newindices_view
: Introducingindices_view
would mean adding a component similar to what already exists, causing confusion and maintainability issues for users. By leveragingiota_view
, we simplify the implementation and reuse of what the current C++ Standard Library offers. Additionally, any future optimizations toiota_view
will automatically benefitstd::views::indices
. Therefore, by extendingiota_view
,std::views::indices
becomes more maintainable, efficient, and simple.Wording
Add a new paragraph under [range.iota.overview]:
Modify [ranges.syn] as follows:
Feature test macro
Add
__cpp_lib_ranges_indices
to [version.syn]:References
P2214R2 A Plan for C++26 Ranges. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2760r0.html ↩︎
P1894R0 Proposal of std::upto, std::indices and std::enumerate. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1894r0.pdf ↩︎