Skip to content

Commit 636eefe

Browse files
committed
more changes
1 parent 5f4dfe0 commit 636eefe

File tree

1 file changed

+63
-32
lines changed

1 file changed

+63
-32
lines changed

any_view.md

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "`any_view`"
3-
document: P3411R1
4-
date: 2024-12-29
3+
document: P3411R2
4+
date: 2025-02-03
55
audience: SG9, LEWG
66
author:
77
- name: Hui Xie
@@ -18,6 +18,15 @@ toc-depth: 2
1818

1919
# Revision History
2020

21+
## R2
22+
23+
- Add `constexpr` support
24+
- Add initial wording
25+
- Move-only by default
26+
- Second reference implementation
27+
- Various fixes
28+
- Added default constructor and `operator bool`
29+
2130
## R1
2231

2332
- Performance tests update
@@ -219,30 +228,7 @@ template <class Element,
219228
class Ref = Element &,
220229
class RValueRef = @*rvalue-ref-t*@<Ref>,
221230
class Diff = ptrdiff_t>
222-
class any_view {
223-
class iterator; // exposition-only
224-
class sentinel; // exposition-only
225-
226-
public:
227-
template <class Range>
228-
constexpr any_view(Range &&range);
229-
230-
constexpr any_view(const any_view &)
231-
requires(bool(Opts & any_view_options::copyable));
232-
233-
constexpr any_view(any_view &&) noexcept;
234-
235-
constexpr any_view &operator=(const any_view &)
236-
requires(bool(Opts & any_view_options::copyable));
237-
238-
constexpr any_view &operator=(any_view &&) noexcept;
239-
240-
constexpr iterator begin();
241-
constexpr sentinel end();
242-
243-
constexpr @*make-unsigned-like-t*@<Diff> size() const
244-
requires(bool(Opts & any_view_options::sized));
245-
};
231+
class any_view;
246232

247233
template <class Element, any_view_options Opts, class Ref, class RValueRef,
248234
class Diff>
@@ -459,6 +445,26 @@ user has to follow the same order of the options that are defined in `any_view_o
459445

460446
An implementation of this approach would look like this: [link](https://godbolt.org/z/4dGYneWxx)
461447

448+
## SG9 Decision
449+
450+
In Hagenberg, SG9 voted these designs
451+
452+
> I like the following template parameter design:
453+
>
454+
> - Proposed in P3411R1 (flags + defaulted template parameters)
455+
> - Alternative 1 (variadic named template parameters)
456+
> - Alternative 2 (custom traits with potentially some standard library provided default traits (e.g. the tags))
457+
> - Alternative 3 (options aggregate type using type as values/reflection and designated initializers)
458+
459+
| Option | Approval votes |
460+
|---------------|----------------|
461+
| Proposed | 10 |
462+
| Alternative 1 | 5 |
463+
| Alternative 2 | 5 |
464+
| Alternative 3 | 4 |
465+
466+
SG9 Recommended moving forward with the proposed design.
467+
462468
# Other Design Considerations
463469

464470
## Why don't follow range-v3's design where first template parameter is `range_reference_t`?
@@ -494,13 +500,23 @@ more general purpose utility in ranges library. Therefore, the authors recommend
494500
## `constexpr` Support
495501

496502
We require `constexpr` because there is no strong reason not to provide it. Even when providing SBO at runtime, there is no need to provide such an optimization at compile-time as well, given that the conditions for the optimization are implementation-dependent, and experience shows this support is easy enough to add.
497-
Both of our two reference implementations have proper `constexpr` support.
503+
Both of our two reference implementations have proper `constexpr` support. SG9 also recommended in Hagenberg to support `constexpr`
498504

499505
## Move-only `view` Support
500506

501507
Move-only `view` is worth supporting as we generally support them in `ranges`. We propose to have a configuration template parameter `any_view_options::copyable` to make the `any_view` conditionally copyable. This removes the need to have another type as we did for `move_only_function`.
502-
503508
We also propose that by default, `any_view` is move-only and to make it copyable, the user needs to explicitly provide this template parameter `any_view_options::copyable`.
509+
On R1 version, this paper proposed to make `any_view` copyable by default.
510+
511+
In Hagenberg, SG9 recommended to make it move-only by default with the votes:
512+
513+
> As proposed, any_view<T> is copyable by default, requiring a flag to allow type-erasing move-only types.
514+
We want to change it to be move-only by default, requiring a flag to make it copyable and prohibit type-erasure of move-only types.
515+
516+
|SF |F |N |A |SA|
517+
|---|---|---|---|--|
518+
|4 |5 |1 |0 |1 |
519+
504520

505521
## Move-only `iterator` Support
506522

@@ -522,7 +538,15 @@ For simplicity, the authors propose to make `any_view` unconditionally non-const
522538
## `common_range` support
523539

524540
Unconditionally making `any_view` a `common_range` is not an option. This would exclude most of the Standard Library `view`s. Adding a configuration template parameter to make `any_view` conditionally `common_range` is overkill. After all, if users need `common_range`, they can use `my_any_view | views::common`. Furthermore, supporting this turns out to add substantial complexity in the implementation.
525-
The authors believe that adding `common_range` support is not worth the added complexity.
541+
The authors believe that adding `common_range` support is not worth the added complexity. This is also confirmed with the votes in SG9 in Hagenberg.
542+
543+
> As proposed, any_view<T> is never a common range.
544+
We want to have a flag to make it a common range if that flag is set.
545+
546+
|SF |F |N |A |SA|
547+
|---|---|---|---|--|
548+
|0 |1 |4 |2 |0 |
549+
526550

527551
## `borrowed_range` support
528552

@@ -537,7 +561,7 @@ Therefore, we recommend conditional support for `borrowed_range`. However, since
537561

538562
We propose providing the strong exception safety guarantee in the following operations: swap, copy-assignment, move-assignment and move-construction. This means that if the operation fails, the two `any_view` objects will be in their original states.
539563
If the underlying view's move constructor (or move-assignment operator) is not `noexcept`, the only way to achieve the strong exception safety guarantee is to avoid calling these operations altogether, which requires `any_view` to hold its underlying object on the heap so it can implement these operations by swapping pointers.
540-
This means that any implementation of `any_view` will have an empty state, and a "moved-from" `any_view` will be in that state.
564+
This means that any implementation of `any_view` will have an empty state, and a "moved-from" heap allocated `any_view` will be in that state. Therefore, the authors propose to add default constructor to `any_view`, which results in an `any_view` object in such state. What's more, we need `operator bool` to test if an `any_view` object is in this state.
541565

542566
## ABI Stability
543567

@@ -808,7 +832,7 @@ We can see the `any_view` version is 4 times faster. This is a very common patte
808832

809833
`any_view` has been implemented in [@rangev3], with equivalent semantics as
810834
proposed here. The authors also implemented a version that directly follows the
811-
proposed wording below without any issue [@ours] and [bemanproject].
835+
proposed wording below without any issue [@ours] and [@bemanproject].
812836

813837
# Wording
814838

@@ -834,6 +858,9 @@ namespace std::ranges {
834858
copyable = 128
835859
};
836860

861+
constexpr any_view_options operator|(any_view_options, any_view_options) noexcept;
862+
constexpr any_view_options operator&(any_view_options, any_view_options) noexcept;
863+
837864
template <class T>
838865
using @*rvalue-ref-t*@ = @*see below*@; // exposition-only
839866

@@ -871,7 +898,7 @@ Add the following subclause to [range.utility]{.sref}
871898
872899
[2]{.pnum} Recommended practice: Implementations should avoid the use of dynamically allocated memory for a small contained value.
873900
874-
[Note 1:Such small-object optimization can only be applied to a type `T` for which `is_nothrow_move_constructible_v<T>` is `true`. — end note]
901+
[Note 1: Such small-object optimization can only be applied to a type `T` for which `is_nothrow_move_constructible_v<T>` is `true`. — end note]
875902
876903
877904
#### ?.?.?.3 Class template `any_view` [range.any.class] {-}
@@ -887,6 +914,7 @@ class any_view {
887914
class @*sentinel*@; // exposition-only
888915
public:
889916
// [range.any.ctor], constructors, assignment, and destructor
917+
constexpr any_view();
890918
template <class Rng> requires @*see below*@
891919
constexpr any_view(Rng&& rng);
892920
constexpr any_view(const any_view &) requires @*see below*@;
@@ -902,6 +930,8 @@ public:
902930
constexpr @*sentinel*@ end();
903931
904932
constexpr @*make-unsigned-like-t*@<Diff> size() const requires @*see below*@;
933+
934+
constexpr explicit operator bool() const;
905935
};
906936
```
907937

@@ -992,6 +1022,7 @@ references:
9921022
- family: Roberts
9931023
given: Patrick
9941024
URL: https://github.com/bemanproject/any_view
1025+
9951026
---
9961027

9971028
<style>

0 commit comments

Comments
 (0)