Re: Calling assumeSorted on const(std.container.Array)

2023-03-26 Thread Olivier Prat via Digitalmars-d-learn
On Sunday, 26 March 2023 at 02:16:15 UTC, Steven Schveighoffer 
wrote:

On 3/25/23 9:45 AM, Olivier Prat wrote:


[...]


It's because a Range keeps a copy of the array (Array is a 
reference counted type). Since that is labeled `const`, then 
editing the Range is forbidden.


Inside SortedRange, it has this, which is causing the issue:

```d
static if (isForwardRange!Range)
@property auto save()
{
// Avoid the constructor
typeof(this) result = this;
result._input = _input.save;
return result;
}
```

Overwriting the input isn't possible here, because it contains 
a const member.


Now, this possibly could be fixed with something like:

`return typeof(this)(_input.save);`

But it might just push the error to another place.

The whole thing is kind of ugly.

There is a note inside the Array Range which says it's trying 
to work around some old bug that is now marked as "works for 
me", so maybe that can be reexamined.


https://github.com/dlang/phobos/blob/17b1a11afd74f9f8a69af93d77d4548a557e1b89/std/container/array.d#L137

-Steve


Thanks to both of you for the answers. It confirms my 
investigation and my workaround is to cast the const ranges into 
their non const versions, when I encounter these issues. Not very 
pretty.


Re: Calling assumeSorted on const(std.container.Array)

2023-03-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 3/25/23 9:45 AM, Olivier Prat wrote:

Would someone explain the exact nature of this error as I fail to 
understand as how just telling that an Array ConstRange is assumed to be 
sorted actually modifies anything??


It's because a Range keeps a copy of the array (Array is a reference 
counted type). Since that is labeled `const`, then editing the Range is 
forbidden.


Inside SortedRange, it has this, which is causing the issue:

```d
static if (isForwardRange!Range)
@property auto save()
{
// Avoid the constructor
typeof(this) result = this;
result._input = _input.save;
return result;
}
```

Overwriting the input isn't possible here, because it contains a const 
member.


Now, this possibly could be fixed with something like:

`return typeof(this)(_input.save);`

But it might just push the error to another place.

The whole thing is kind of ugly.

There is a note inside the Array Range which says it's trying to work 
around some old bug that is now marked as "works for me", so maybe that 
can be reexamined.


https://github.com/dlang/phobos/blob/17b1a11afd74f9f8a69af93d77d4548a557e1b89/std/container/array.d#L137

-Steve


Re: Calling assumeSorted on const(std.container.Array)

2023-03-25 Thread Ali Çehreli via Digitalmars-d-learn

On 3/25/23 09:31, Olivier Prat wrote:

On Saturday, 25 March 2023 at 13:45:36 UTC, Olivier Prat wrote:
I'm trying to call assumeSorted on a const(Array) using this code 
snippet:


[...]


In a similar fashion, a number of methods in SortedRange do not compile 
if called on a const(SortedRange) or immutable(SortedRange), such as 
length, or front. Is this on purpose?


There are a number of interesting points in your original post but I 
couldn't find time to answer all of those.


I can inject this for now: :) assumeSorted returns a range object. The 
concept of a const range object is flawed because by nature iteration of 
a range happens by mutating it: For example, popBack has to do that.


So, it's normal that any range algorithm will assume a non-const object.

Ali



Re: Calling assumeSorted on const(std.container.Array)

2023-03-25 Thread Olivier Prat via Digitalmars-d-learn

On Saturday, 25 March 2023 at 13:45:36 UTC, Olivier Prat wrote:
I'm trying to call assumeSorted on a const(Array) using this 
code snippet:


[...]


In a similar fashion, a number of methods in SortedRange do not 
compile if called on a const(SortedRange) or 
immutable(SortedRange), such as length, or front. Is this on 
purpose?


Calling assumeSorted on const(std.container.Array)

2023-03-25 Thread Olivier Prat via Digitalmars-d-learn
I'm trying to call assumeSorted on a const(Array) using this code 
snippet:


void test(T)(const ref Array!T a)
{
auto b = a[].assumeSorted;
writeln(b);
}

void main() {
Array!int a = [1, 5, 7, 8, 15, 100];
test(a);
}

Unfortunately, I keep having a compilation error:
/dlang/dmd/linux/bin64/../../src/phobos/std/range/package.d(10871): Error: 
cannot modify struct instance `result._input` of type 
`RangeT!(const(Array!int))` because it contains `const` or `immutable` members
/dlang/dmd/linux/bin64/../../src/phobos/std/range/package.d(10918): Error: 
cannot modify struct instance `result._input` of type 
`RangeT!(const(Array!int))` because it contains `const` or `immutable` members
/dlang/dmd/linux/bin64/../../src/phobos/std/range/package.d(11500): Error: template instance 
`std.range.SortedRange!(RangeT!(const(Array!int)), "a < b", 
SortedRangeOptions.assumeSorted)` error instantiating
onlineapp.d(10):instantiated from here: `assumeSorted!("a 
< b", RangeT!(const(Array!int)))`

onlineapp.d(17):instantiated from here: `test!int`

Would someone explain the exact nature of this error as I fail to 
understand as how just telling that an Array ConstRange is 
assumed to be sorted actually modifies anything??