Thread overview
Returning range of inout objects from inout method
Jul 25, 2020
FreeSlave
Jul 25, 2020
FreeSlave
July 25, 2020
I want to be able to return a range of const objects from the const object and a range mutable objects from the mutable object.

inout comes to mind, but not applicable in this case, because inout must be applied to the return type as whole, which does not make much sense for the range. Defining range of inout objects does not work too. See the example.

import std.range;
class A
{
    string name;
}

class B
{
    A[] _actions;
    ForwardRange!(inout(A)) byAction() inout { // can't instance this type
        import std.algorithm : filter;
        return inputRangeObject(_actions.filter!(a => a !is null && a.name.length));
    }
}

So how can I achieve the intended effect without code duplication? (like making separate mutable and const versions of the method).
July 25, 2020
On 7/25/20 8:26 AM, FreeSlave wrote:
> I want to be able to return a range of const objects from the const object and a range mutable objects from the mutable object.
> 
> inout comes to mind, but not applicable in this case, because inout must be applied to the return type as whole, which does not make much sense for the range. Defining range of inout objects does not work too. See the example.
> 
> import std.range;
> class A
> {
>      string name;
> }
> 
> class B
> {
>      A[] _actions;
>      ForwardRange!(inout(A)) byAction() inout { // can't instance this type
>          import std.algorithm : filter;
>          return inputRangeObject(_actions.filter!(a => a !is null && a.name.length));
>      }
> }
> 
> So how can I achieve the intended effect without code duplication? (like making separate mutable and const versions of the method).

You can't exactly. The limitation that inout cannot be applied to a struct member is a crappy limitation, one which I wish I never advocated for.

The only way to do this without code duplication (but with generated code duplication) is to template the byAction function on the type of `this`:

auto byAction(this This)() { /* same implementation */ }

Note that this ONLY works if your base range type is an array. If you have a custom range type, you need to parameterize that based on the constness of `This`.

-Steve
July 25, 2020
On Saturday, 25 July 2020 at 14:19:15 UTC, Steven Schveighoffer wrote:
>
> The only way to do this without code duplication (but with generated code duplication) is to template the byAction function on the type of `this`:
>
> auto byAction(this This)() { /* same implementation */ }
>
> Note that this ONLY works if your base range type is an array. If you have a custom range type, you need to parameterize that based on the constness of `This`.
>
> -Steve

Thanks. I thought this template is useful only in inheritance.
Is constness of member function inferred automatically in this case?
July 25, 2020
On 7/25/20 3:16 PM, FreeSlave wrote:
> On Saturday, 25 July 2020 at 14:19:15 UTC, Steven Schveighoffer wrote:
>>
>> The only way to do this without code duplication (but with generated code duplication) is to template the byAction function on the type of `this`:
>>
>> auto byAction(this This)() { /* same implementation */ }
>>
>> Note that this ONLY works if your base range type is an array. If you have a custom range type, you need to parameterize that based on the constness of `This`.
>>
> 
> Thanks. I thought this template is useful only in inheritance.
> Is constness of member function inferred automatically in this case?

In this case, yes. I don't know actually if this is documented.

-Steve
July 25, 2020
On 7/25/20 4:07 PM, Steven Schveighoffer wrote:
> On 7/25/20 3:16 PM, FreeSlave wrote:
>> On Saturday, 25 July 2020 at 14:19:15 UTC, Steven Schveighoffer wrote:
>>>
>>> The only way to do this without code duplication (but with generated code duplication) is to template the byAction function on the type of `this`:
>>>
>>> auto byAction(this This)() { /* same implementation */ }
>>>
>>> Note that this ONLY works if your base range type is an array. If you have a custom range type, you need to parameterize that based on the constness of `This`.
>>>
>>
>> Thanks. I thought this template is useful only in inheritance.
>> Is constness of member function inferred automatically in this case?
> 
> In this case, yes. I don't know actually if this is documented.

It should be now.

https://github.com/dlang/dlang.org/pull/2835

-Steve