## digitalmars.D.learn - Help me write "saveAll"

• monarch_dodra (49/49) Dec 21 2012 There are a lot of algorithms in std.algorithm that operate on
• H. S. Teoh (7/19) Dec 21 2012 What about using a mixin? I know it's ugly, but at least you don't have
• monarch_dodra (3/23) Dec 21 2012 Hum. That's a solution I guess. I'm tying to see if I can't get
• Joshua Niehus (17/28) Dec 21 2012 Sorry if im misunderstanding, but doesn't filter do this?
• monarch_dodra (15/46) Dec 21 2012 I think there may be some misunderstanding. It's more like this;
• Timon Gehr (4/24) Dec 21 2012 Use a phobos tuple?
"monarch_dodra" <monarchdodra gmail.com> writes:
```There are a lot of algorithms in std.algorithm that operate on
"foo(Range, Needles...)(Range range, Needles needles)".

Needles can be anything, in particular, either an "element" or a
"range".

The thing is that every now and then, you want to save the
entirety of (the ranges) inside needles. EG, I want to be able to
write:
foo(range, needles.saveAll);

I'm having trouble. I did two iterations:

//----
auto saveAll(Ranges...)(Ranges ranges)  property
{
auto ret = ranges;
foreach (Index, Type; Ranges)
static if (isForwardRange!Type)
ret[Index] = ranges[Index];
return ret;
}
//----
This doesn't work, because: Error: functions cannot return a tuple
So that's that.

The next try was:
//----
void saveAll(Ranges...)(in Ranges iRanges, ref Ranges oRanges)
property
{
TypeTuple!Ranges ret = ranges;
foreach (Index, Type; Ranges)
static if (isForwardRange!Type)
ret[Index] = ranges[Index];
return ret;
}
//----
This doesn't either, because a function can't have double varargs
arguments. It's ambiguous...

So this left me with the option of just inlining into the code:
//----
Needles savedNeedles = needles;
foreach (Index, Type; Needles)
static if (isForwardRange!Type)
savedNeedles[Index] = needles[Index];
size_t r = startsWith!pred(haystack, savedNeedles);
//----
It works, but is kind of ugly, I'd have really wanted to be able
to just write:
//----
size_t r = startsWith!pred(haystack, needles.saveAll);
//----

Any thought on how do get this working?
```
Dec 21 2012
"H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
```On Fri, Dec 21, 2012 at 06:01:13PM +0100, monarch_dodra wrote:
There are a lot of algorithms in std.algorithm that operate on
"foo(Range, Needles...)(Range range, Needles needles)".

Needles can be anything, in particular, either an "element" or a
"range".

The thing is that every now and then, you want to save the entirety
of (the ranges) inside needles. EG, I want to be able to write:
foo(range, needles.saveAll);

I'm having trouble. I did two iterations:

[...]
Any thought on how do get this working?

What about using a mixin? I know it's ugly, but at least you don't have
to copy-n-paste lots of boilerplate every time.

T

--
LINUX = Lousy Interface for Nefarious Unix Xenophobes.
```
Dec 21 2012
"monarch_dodra" <monarchdodra gmail.com> writes:
```On Friday, 21 December 2012 at 17:27:32 UTC, H. S. Teoh wrote:
On Fri, Dec 21, 2012 at 06:01:13PM +0100, monarch_dodra wrote:
There are a lot of algorithms in std.algorithm that operate on
"foo(Range, Needles...)(Range range, Needles needles)".

Needles can be anything, in particular, either an "element" or
a
"range".

The thing is that every now and then, you want to save the
entirety
of (the ranges) inside needles. EG, I want to be able to write:
foo(range, needles.saveAll);

I'm having trouble. I did two iterations:

[...]
Any thought on how do get this working?

What about using a mixin? I know it's ugly, but at least you
don't have
to copy-n-paste lots of boilerplate every time.

T

Hum. That's a solution I guess. I'm tying to see if I can't get
something to work with Tuple and ParameterTypeTuple...
```
Dec 21 2012
"Joshua Niehus" <jm.niehus gmail.com> writes:
```On Friday, 21 December 2012 at 17:01:14 UTC, monarch_dodra wrote:
There are a lot of algorithms in std.algorithm that operate on
"foo(Range, Needles...)(Range range, Needles needles)".

Needles can be anything, in particular, either an "element" or
a "range".

The thing is that every now and then, you want to save the
entirety of (the ranges) inside needles. EG, I want to be able
to write:
foo(range, needles.saveAll);
[...snip...]
Any thought on how do get this working?
size_t r = startsWith!pred(haystack, needles.saveAll);

Sorry if im misunderstanding, but doesn't filter do this?
Example:
import std.stdio, std.algorithm, std.range;
void main() {
auto x = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
];
//haystack               // needle          //
needle
auto y = x.filter!(a => (a == [4, 5, 6] || a == [7, 8,
9])).array;
y.writeln;
}
```
Dec 21 2012
"monarch_dodra" <monarchdodra gmail.com> writes:
```On Friday, 21 December 2012 at 20:38:34 UTC, Joshua Niehus wrote:
On Friday, 21 December 2012 at 17:01:14 UTC, monarch_dodra
wrote:
There are a lot of algorithms in std.algorithm that operate on
"foo(Range, Needles...)(Range range, Needles needles)".

Needles can be anything, in particular, either an "element" or
a "range".

The thing is that every now and then, you want to save the
entirety of (the ranges) inside needles. EG, I want to be able
to write:
foo(range, needles.saveAll);
[...snip...]
Any thought on how do get this working?
size_t r = startsWith!pred(haystack, needles.saveAll);

Sorry if im misunderstanding, but doesn't filter do this?
Example:
import std.stdio, std.algorithm, std.range;
void main() {
auto x = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
];
//haystack               // needle          //
needle
auto y = x.filter!(a => (a == [4, 5, 6] || a == [7, 8,
9])).array;
y.writeln;
}

I think there may be some misunderstanding. It's more like this;

//----
[1, 2, 3, 4].find(4, 7, [1, 3], [2, 3]);
//----
Here, as you can see, the 4 needles are:
4: Element
7: Element
[1, 3]: Range
[2, 3]: Range

In your example, you are just comparing elements: The elements
themselves happen to be ranges, but that is irrelevant in the
iteration scheme, they remain *elements* in the search.

In my example, Filter can't operate the Needle "[1, 3]", because
it contains multiple elements.
```
Dec 21 2012
Timon Gehr <timon.gehr gmx.ch> writes:
```On 12/21/2012 06:01 PM, monarch_dodra wrote:
There are a lot of algorithms in std.algorithm that operate on
"foo(Range, Needles...)(Range range, Needles needles)".

Needles can be anything, in particular, either an "element" or a "range".

The thing is that every now and then, you want to save the entirety of
(the ranges) inside needles. EG, I want to be able to write:
foo(range, needles.saveAll);

I'm having trouble. I did two iterations:

//----
auto saveAll(Ranges...)(Ranges ranges)  property
{
auto ret = ranges;
foreach (Index, Type; Ranges)
static if (isForwardRange!Type)
ret[Index] = ranges[Index];
return ret;
}
//----
This doesn't work, because: Error: functions cannot return a tuple
So that's that.
...

Use a phobos tuple?

return tuple(ret)

The caller can use .expand.
```
Dec 21 2012
"monarch_dodra" <monarchdodra gmail.com> writes:
```On Saturday, 22 December 2012 at 02:58:16 UTC, Timon Gehr wrote:
On 12/21/2012 06:01 PM, monarch_dodra wrote:
There are a lot of algorithms in std.algorithm that operate on
"foo(Range, Needles...)(Range range, Needles needles)".

Needles can be anything, in particular, either an "element" or
a "range".

The thing is that every now and then, you want to save the
entirety of
(the ranges) inside needles. EG, I want to be able to write:
foo(range, needles.saveAll);

I'm having trouble. I did two iterations:

//----
auto saveAll(Ranges...)(Ranges ranges)  property
{
auto ret = ranges;
foreach (Index, Type; Ranges)
static if (isForwardRange!Type)
ret[Index] = ranges[Index];
return ret;
}
//----
This doesn't work, because: Error: functions cannot return a
tuple
So that's that.
...

Use a phobos tuple?

return tuple(ret)

The caller can use .expand.

Victory! It works that way!

//----
auto saveAll(Stuff...)(Stuff stuff)
{
Stuff ret = stuff;
foreach(ref v; ret)
++v;
return tuple(ret);
}

void foo(Stuff...)(Stuff stuff)
{
bar(stuff.saveAll().expand);
}

void bar(Stuff...)(Stuff stuff)
{
foreach (v; stuff)
v.writeln();
}

void main()
{
foo(1, 2, 3);
}
//----

The only limitation is that I can't declare it as a property. I
get:
main.d(11): Error: properties can only have zero, one, or two
parameter

I'd say that a bug (or at least, an unnecessary restriction), but
I can live with it.

Thankyou!
```
Dec 22 2012