www.digitalmars.com         C & C++   DMDScript  

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

reply "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
next sibling parent reply "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
parent "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
prev sibling next sibling parent reply "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
parent "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
prev sibling parent reply 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
parent "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