Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to repeat a statement N times (simple loop)

Tags:

loops

d

I need to perform an action N times. What is the best way in D to do it?

for(uint i=0; i<N; i++)
   action();

foreach(uint i; 0.. N)
   action();

maybe something better? Ideally I'd want something like Groovy's / Ruby's times e.g

N.times {
   action();
}

is it possible?

like image 483
Parobay Avatar asked May 30 '14 09:05

Parobay


2 Answers

Yes, it is possible

import std.stdio;
import std.traits;

void foo()
{
    writeln("Do It!");
}

void times(T,N)(N n, T action) if (isCallable!T && isIntegral!N)
{
    static if (ParameterTypeTuple!action.length == 1 
           && isIntegral!(ParameterTypeTuple!action[0]))
        foreach (i; 0 .. n)
            action(i);
    else
        foreach (i; 0 .. n)
            action();
}

void main(string[] args)
{
    10.times(&foo);
    10.times({writeln("Do It!");});
    10.times((uint n){writeln(n + 1, " Round");});
}

version with arguments support:

import std.stdio;
import std.traits;

void foo()
{
    writeln("Do It!");
}

struct Step {
    alias n this;
    size_t n;
    this(size_t i)
    {
        n = i + 1;
    }
}

struct Index {
    alias n this;
    size_t n;
}

void times(T,N,A...)(N n, T action, A args) if (isCallable!T && isIntegral!N)
{
    alias PTTAction = ParameterTypeTuple!action;
    static if (PTTAction.length >= 1)
    {
        alias FP = PTTAction[0];
        static if (is(Index == FP) || is(Step == FP))
            foreach (i; 0 .. n)
                action(FP(i), args);
        else
            action(args);
    }
    else
        foreach (i; 0 .. n)
            action();
}

void main(string[] args)
{
    10.times(&foo);
    10.times({writeln("Do It!");});
    10.times((Step n){writeln(n, " Step");});
    10.times((Index n, string msg){writeln(n, msg);}, " Index");
    stdin.readln;
}

UPDATE:

for better performance you could use alias template parametr for action:

void times(alias action,N)(N n) if (isCallable!action && isIntegral!N)
{
    static if (ParameterTypeTuple!action.length == 1 
           && isIntegral!(ParameterTypeTuple!action[0]))
        foreach (i; 0 .. n)
            action(i);
    else
        foreach (i; 0 .. n)
            action();
}

void main(string[] args)
{
    10.times!(foo);
    10.times!({writeln("Do It!");});
    10.times!((uint n){writeln(n + 1, " Round");});
}
like image 111
Kozzi11 Avatar answered Sep 28 '22 18:09

Kozzi11


Perhaps something like this?

void loop(int n, void delegate() func)
{
    foreach (i; 0 .. n)
    {
        func();
    }
}

Usage:

loop(10, {        
    writeln("Hello World!");
});
like image 34
Bauss Avatar answered Sep 28 '22 16:09

Bauss