Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
January 29, 2016 opApply @safety | ||||
---|---|---|---|---|
| ||||
I want to create an opApply for a type. I've marked my code @safe, because everything I wrote was @safe. The body of opApply is @safe, but it calls a delegate that may or may not be @safe. How do I make it so I can iterate through this type safely and systemly? I want to support iteration like: foreach (string key, string value; collection) {} foreach (size_t i, string key, string value; collection) {} |
January 29, 2016 Re: opApply @safety | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Wright | On 1/29/16 12:44 PM, Chris Wright wrote:
> I want to create an opApply for a type.
>
> I've marked my code @safe, because everything I wrote was @safe. The body
> of opApply is @safe, but it calls a delegate that may or may not be @safe.
>
> How do I make it so I can iterate through this type safely and systemly?
Likely an overload. Tag the delegate as being @safe or not.
-Steve
|
January 29, 2016 Re: opApply @safety | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Fri, 29 Jan 2016 14:00:08 -0500, Steven Schveighoffer wrote:
> On 1/29/16 12:44 PM, Chris Wright wrote:
>> I want to create an opApply for a type.
>>
>> I've marked my code @safe, because everything I wrote was @safe. The body of opApply is @safe, but it calls a delegate that may or may not be @safe.
>>
>> How do I make it so I can iterate through this type safely and systemly?
>
> Likely an overload. Tag the delegate as being @safe or not.
>
> -Steve
That's handy. It works. I can make it so someone can call:
foo.opApply((i, k, v) @safe => 0);
foo.opApply((i, k, v) @system => 0);
And that works.
However, if you have:
@safe void bar() {
foreach(i, k, v; foo) {
}
}
the compiler complains:
opapplysafe.d(12): Error: foo.opApply matches more than one declaration:
opapplysafe.d(2): @safe int(int delegate(int, string, string) @safe
dg)
and:
opapplysafe.d(5): @system int(int delegate(int, string, string)
@system dg)
Guess I'll file a bug.
|
January 29, 2016 Re: opApply @safety | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Wright | On 1/29/16 3:08 PM, Chris Wright wrote:
> On Fri, 29 Jan 2016 14:00:08 -0500, Steven Schveighoffer wrote:
>
>> On 1/29/16 12:44 PM, Chris Wright wrote:
>>> I want to create an opApply for a type.
>>>
>>> I've marked my code @safe, because everything I wrote was @safe. The
>>> body of opApply is @safe, but it calls a delegate that may or may not
>>> be @safe.
>>>
>>> How do I make it so I can iterate through this type safely and
>>> systemly?
>>
>> Likely an overload. Tag the delegate as being @safe or not.
>>
>> -Steve
>
> That's handy. It works. I can make it so someone can call:
> foo.opApply((i, k, v) @safe => 0);
> foo.opApply((i, k, v) @system => 0);
>
> And that works.
>
> However, if you have:
> @safe void bar() {
> foreach(i, k, v; foo) {
> }
> }
>
> the compiler complains:
>
> opapplysafe.d(12): Error: foo.opApply matches more than one declaration:
> opapplysafe.d(2): @safe int(int delegate(int, string, string) @safe
> dg)
> and:
> opapplysafe.d(5): @system int(int delegate(int, string, string)
> @system dg)
>
> Guess I'll file a bug.
>
Definitely seems like a bug.
As a workaround, you can name the opApply functions:
struct S
{
int opApply(int delegate(int, string, string) @safe dg) @safe {...}
int unsafeApply(int delegate(int, string, string) dg) {...}
}
foreach(i, k, v; foo.unsafeApply) {...}
though that's... ugly.
-Steve
|
January 29, 2016 Re: opApply @safety | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Wright | On Friday, 29 January 2016 at 17:44:34 UTC, Chris Wright wrote: > I want to create an opApply for a type. > > I've marked my code @safe, because everything I wrote was @safe. The body of opApply is @safe, but it calls a delegate that may or may not be @safe. > > How do I make it so I can iterate through this type safely and systemly? > > I want to support iteration like: > > foreach (string key, string value; collection) {} > foreach (size_t i, string key, string value; collection) {} You can implement an input range and annotate all the primitives as @safe. Then if there's only an input range in your agregate, DMD will auto-detect that it must use it in foreach(): http://dlang.org/spec/statement.html#foreach-with-ranges in the worst case (range not implementable directly but only as a getter in .range() or .opSlice() you'll have to change the style a bit and consume the range explicitly in a typical "while (!stuff.empty) {...}" |
January 30, 2016 Re: opApply @safety | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | On Fri, 29 Jan 2016 23:35:35 +0000, Basile B. wrote:
> You can implement an input range and annotate all the primitives as @safe.
I hadn't realized that if front() returns a tuple, it's automatically expanded. Works for me.
|
Copyright © 1999-2021 by the D Language Foundation