Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
February 10, 2016 Automatic range creation for class or struct? | ||||
---|---|---|---|---|
| ||||
Hi! I have class (or struct) which realises .length() and .opIndex(size_t) methods. It is possible to create from this class some sort of range using template from std? (I mean that internal counter, .popFront(), .empty() etc methods should be added by template.) |
February 10, 2016 Re: Automatic range creation for class or struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peka | On Wednesday, 10 February 2016 at 00:05:36 UTC, Peka wrote:
> Hi!
>
> I have class (or struct) which realises .length() and .opIndex(size_t) methods.
>
> It is possible to create from this class some sort of range using template from std? (I mean that internal counter, .popFront(), .empty() etc methods should be added by template.)
I don't think anything like that exists in phobos but it's not hard to pull it out using mixin templates:
mixin template Rangify(T)
if (__traits(hasMember, T, "length")
&& __traits(hasMember, T, "opIndex")) {
ulong _counter;
bool empty() {
return _counter == this.length;
}
auto front() {
return this[_counter];
}
auto popFront() {
_counter++;
}
}
struct S {
int[] arr;
mixin Rangify!S;
auto length() {
return arr.length;
}
int opIndex(size_t i) {
return arr[i];
}
}
void main(string[] args) {
import std.stdio: writeln;
auto s = S();
s.arr = [1, 2, 3];
foreach (x ; s)
writeln(x);
}
|
February 10, 2016 Re: Automatic range creation for class or struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to cym13 | On Wednesday, 10 February 2016 at 00:22:46 UTC, cym13 wrote: > On Wednesday, 10 February 2016 at 00:05:36 UTC, Peka wrote: >> Hi! >> >> I have class (or struct) which realises .length() and .opIndex(size_t) methods. >> >> It is possible to create from this class some sort of range using template from std? (I mean that internal counter, .popFront(), .empty() etc methods should be added by template.) > > I don't think anything like that exists in phobos I need definitive answer. > but it's not hard to pull it out using mixin templates: Sure! Thanks a lot, but I want to use std lib as much as possible |
February 10, 2016 Re: Automatic range creation for class or struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peka | >> I don't think anything like that exists in phobos
>
> I need definitive answer.
I need a precise answer.
(sorry, google translator :з)
|
February 10, 2016 Re: Automatic range creation for class or struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peka | On Wednesday, 10 February 2016 at 00:27:54 UTC, Peka wrote:
>>> I don't think anything like that exists in phobos
>>
>> I need definitive answer.
>
> I need a precise answer.
>
> (sorry, google translator :з)
"Definitive" is good, maybe even better in the context.
I should have been clearer, sorry. When I said "I don't think" I actually meant "I've searched the docs and sources and haven't found anything even remotely similar". I'll never be 100% percent sure that it isn't there though, you're free to read phobos to confirm it.
|
February 09, 2016 Re: Automatic range creation for class or struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to cym13 | On 02/09/2016 04:22 PM, cym13 wrote:
> On Wednesday, 10 February 2016 at 00:05:36 UTC, Peka wrote:
>> Hi!
>>
>> I have class (or struct) which realises .length() and .opIndex(size_t)
>> methods.
>>
>> It is possible to create from this class some sort of range using
>> template from std? (I mean that internal counter, .popFront(),
>> .empty() etc methods should be added by template.)
>
> I don't think anything like that exists in phobos but it's not hard to
> pull it out using mixin templates:
>
>
> mixin template Rangify(T)
> if (__traits(hasMember, T, "length")
> && __traits(hasMember, T, "opIndex")) {
>
> ulong _counter;
>
> bool empty() {
> return _counter == this.length;
> }
>
> auto front() {
> return this[_counter];
> }
>
> auto popFront() {
> _counter++;
> }
> }
>
> struct S {
> int[] arr;
>
> mixin Rangify!S;
>
> auto length() {
> return arr.length;
> }
>
> int opIndex(size_t i) {
> return arr[i];
> }
> }
>
> void main(string[] args) {
> import std.stdio: writeln;
>
> auto s = S();
> s.arr = [1, 2, 3];
>
> foreach (x ; s)
> writeln(x);
> }
>
Actually, your method can work non-intrusively if the template is a function that returns a range (typically Voldemort):
auto rangify(T)(T range)
if (__traits(hasMember, T, "length")
&& __traits(hasMember, T, "opIndex")) {
struct Range {
T range;
ulong _counter;
bool empty() {
return _counter == range.length;
}
auto front() {
return range[_counter];
}
auto popFront() {
_counter++;
}
}
return Range(range); // <-- Now returns a Voldemort object
}
struct S { // <-- No mixin needed
int[] arr;
auto length() {
return arr.length;
}
int opIndex(size_t i) {
return arr[i];
}
}
void main(string[] args) {
import std.stdio: writeln;
auto s = S();
s.arr = [1, 2, 3];
foreach (x ; s.rangify) // <-- CHANGED
writeln(x);
}
Ali
|
February 10, 2016 Re: Automatic range creation for class or struct? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peka | On Wednesday, 10 February 2016 at 00:05:36 UTC, Peka wrote: > Hi! > > I have class (or struct) which realises .length() and .opIndex(size_t) methods. > > It is possible to create from this class some sort of range using template from std? (I mean that internal counter, .popFront(), .empty() etc methods should be added by template.) See: https://issues.dlang.org/show_bug.cgi?id=5351 |
Copyright © 1999-2021 by the D Language Foundation