Hi,

I think it's possible to implement a contiguous iterator in the shape of struct { T* ptr; bool is_end; }; and still satisfy the semantic constraints.

The only operation that would require a complete type is `to_address` , which you don't use in your examples.

It's still not necessarily a good idea though.

Cheers,
Lénárd



On 16 August 2024 13:00:12 BST, Piotr Nycz via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Hi,

I have a small request(bug fix? improvement) to existing (probably accepted already) proposals to C++26 about std::optional class.

I am pretty sure (I tested it) that contiguous_iterator as specified in this paper Give std::optional Range Support is too restrictive as for next proposal - std::optional<T&>
In my opinion it should be just input_iterator. 

The main reason is that for input_iterator I wouldn't need to have T defined - it can still be forward declared - thus compilation time will not have to increase - nor I have to add any extra includes when changing from:

struct Some;
void func(Some&);
std::optional<Some&> a = get();

if (a) func(*a); 

to:

...
for (auto& v: a) func(v);

The other reasons - who would care if the iterator type to 0-or-1 range is contiguous or not, then no need to complicate...

I have such an optional to reference type in most of projects I am working on, and when we tried to add  contiguous  range support - it failed to compile pretty seriously because of quite a lot of compile time optimization based on forward declarations.

In practice it is also easier to implement input iterator, not to mention less code to write:

struct input_iterator
{
    T* ptr;
    ...
    input_iterator& operator++() { ptr = nullptr; return *this; }
};
class optional<T&>
{
     T* ptr;
      contiguous_iterator begin() const { return ptr; }
      contiguous_iterator end() const { return nullptr; }
};

comparing to:

struct contiguous_iterator
{
    T* ptr;
    ...
    contiguous_iterator& operator++() { ++ptr; return *this; } // the line that requires T to be defined
    // who would need --, -, +, etc...
};
class optional<T&>
{
     T* ptr;
      contiguous_iterator begin() const { return ptr; }
      contiguous_iterator end() const { return ptr + has_value(); } // the next line that requires T to be defined
};

--
BR,
Piotr Nycz