www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to get type returned by e.g. std.algorithm.iteration.filter

reply =?UTF-8?Q?Christian_K=c3=b6stlin?= <christian.koestlin gmail.com> writes:
I would like to join several sorted files into one big sorted file.

For that I came up with this snippet:


import std.stdio;
import std.algorithm;
import std.typecons;
import std.array;
import std.range;

auto byMinimum(Ranges)(Ranges ranges)
{
     auto getNonEmpty()
     {
         return ranges.filter!("!a.empty");
     }

     auto nonEmpty = getNonEmpty;
     struct ByMinimum(Ranges)
     {
         bool empty()
         {
             return nonEmpty.empty;
         }

         auto front()
         {
             auto minRangeAndLine = nonEmpty.map!(range => tuple!("range",
                     "line")(range, range.front)).minElement!("a.line");
             return minRangeAndLine;
         }

         void popFront()
         {
             auto minRangeAndLine = nonEmpty.map!(range => tuple!("range",
                     "line")(range, range.front)).minElement!("a.line");
             minRangeAndLine.range.popFront;
             nonEmpty = getNonEmpty;
         }
     }

     return ByMinimum!(Ranges)();
}

void main(string[] files)
{
     foreach (n; files[1 .. $].map!(name => 
File(name).byLine(No.keepTerminator)).array.byMinimum)
     {
         writeln(n.line);
     }
}


I would like to get rid of the duplication that searches for the range 
with the next minimum in terms of runtime but also in terms of code 
written out. Unfortunately I have no idea how to even store the result 
of this search in an attribute of ByMinimum, as I cannot writeout its type.

Kind regards,
Christian
May 19 2019
parent reply Jacob Carlborg <doob me.com> writes:
On 2019-05-19 15:36, Christian Köstlin wrote:

 Unfortunately I have no idea how to even store the result 
 of this search in an attribute of ByMinimum, as I cannot writeout its type.
In general you can use `typeof(<expression>)`, where `<expression>` is the expression you want to get the type of. -- /Jacob Carlborg
May 19 2019
parent reply =?UTF-8?Q?Christian_K=c3=b6stlin?= <christian.koestlin gmail.com> writes:
On 19.05.19 20:38, Jacob Carlborg wrote:
 On 2019-05-19 15:36, Christian Köstlin wrote:
 
 Unfortunately I have no idea how to even store the result of this 
 search in an attribute of ByMinimum, as I cannot writeout its type.
In general you can use `typeof(<expression>)`, where `<expression>` is the expression you want to get the type of.
Thanks for the hint. The best I could come up with this is: import std.stdio; import std.algorithm; import std.typecons; import std.array; import std.range; import std.traits; auto byMinimum(Ranges)(Ranges ranges) { auto getNonEmpty() { return ranges.filter!("!a.empty"); } auto minimumOfRanges(Ranges)(Ranges ranges) { // dfmt off return ranges .map!(range => tuple!("range", "line")(range, range.front)) .minElement!("a.line"); // dfmt on } auto nonEmpty = getNonEmpty; ReturnType!(minimumOfRanges!(typeof(nonEmpty))) minRangeAndLine; struct ByMinimum(Ranges) { bool empty() { return nonEmpty.empty; } auto front() { minRangeAndLine = minimumOfRanges(nonEmpty); return minRangeAndLine; } void popFront() { minRangeAndLine.range.popFront; nonEmpty = getNonEmpty; } } return ByMinimum!(Ranges)(); } void main(string[] files) { foreach (n; files[1 .. $].map!(name => File(name).byLine(No.keepTerminator)).array.byMinimum) { writeln(n.line); } } Still it looks a little clumsy. Any ideas? -- Christian
May 19 2019
parent =?UTF-8?Q?Christian_K=c3=b6stlin?= <christian.koestlin gmail.com> writes:
Last version using more from the outer template


import std.stdio;
import std.algorithm;
import std.typecons;
import std.array;
import std.range;
import std.traits;

auto byMinimum(Ranges)(Ranges ranges)
{
     auto getNonEmpty()
     {
         return ranges.filter!("!a.empty");
     }

     auto nonEmpty = getNonEmpty;

     auto minimumOfRanges()
     {
         // dfmt off
         return nonEmpty
             .map!(range => tuple!("range", "line")(range, range.front))
             .minElement!("a.line");
         // dfmt on
     }

     ReturnType!(minimumOfRanges) minRangeAndLine;
     struct ByMinimum
     {
         bool empty()
         {
             return nonEmpty.empty;
         }

         auto front()
         {
             minRangeAndLine = minimumOfRanges;
             return minRangeAndLine;
         }

         void popFront()
         {
             nonEmpty = getNonEmpty;
             minRangeAndLine.range.popFront;
         }
     }

     return ByMinimum();
}

void main(string[] files)
{
     foreach (n; files[1 .. $].map!(name => 
File(name).byLine(No.keepTerminator)).array.byMinimum)
     {
         writeln(n.line);
     }
}
May 19 2019