Re: Lazy range, extract only Nth element, set range size constraint?

2017-07-09 Thread ag0aep6g via Digitalmars-d-learn

On 07/09/2017 11:51 PM, biocyberman wrote:

Following is the code for a more generalized Fibonacci range.

Questions:

1. How do I get only the value of the Nth (i.e. N = 25) element in an 
idiomatic way?


As you've only got an input range, you have to popFront the 24 values 
that come before. You can use std.range.drop:



import std.range : drop;
auto twentyfifth = fib.drop(24).front;


But if you're not sure that the range actually has 25 elements, you 
should check `empty`, of course:



import std.range : popFrontN;
fib.popFrontN(24); /* or fib = fib.drop(24); */
if (!fib.empty)
{
auto twentyfifth = fib.front;
}


2. Can I set constraints in the range so that user gets warning if he 
asks for Nth element greater than a limit, say N> 30;


You can keep track of N in FibonacciRange and when it hits 30 you throw 
an exception or print a message or just set `empty` to true.


You can't make it a compilation warning/error as far as I can tell.

or if the actually 
range value at N is greater than datatype limit (e.g. max long)?


You can use std.experimental.checkedint to detect it at run time:


private bool _empty = false;
bool empty() const @property { return _empty; }

void popFront()
{
import std.experimental.checkedint : checked, Throw;
long tmp = 0;
try tmp = (checked!Throw(first)*multifactor + second).get;
catch (Throw.CheckFailure e) _empty = true;
first = second;
second = tmp;
}


(There may be a smarter way than making the operation throw an exception 
and catching that.)


Lazy range, extract only Nth element, set range size constraint?

2017-07-09 Thread biocyberman via Digitalmars-d-learn

Following is the code for a more generalized Fibonacci range.

Questions:

1. How do I get only the value of the Nth (i.e. N = 25) element 
in an idiomatic way?


2. Can I set constraints in the range so that user gets warning 
if he asks for Nth element greater than a limit, say N> 30; or if 
the actually range value at N is greater than datatype limit 
(e.g. max long)? Maybe this should be done outside of the range, 
i.e. do check before accessing the range?


#!/usr/bin/env rdmd
import std.stdio : writeln;
long multifactor = 4;
int elemth = 25;

struct FibonacciRange
{
  long first = 1;
  long second = 1;

  bool empty() const @property
  {
   // how to stop at n = 30?
return false;
  }

  void popFront()
  {
long tmp = 0;
tmp = first*multifactor + second;
first = second;
second = tmp;
  }

  long front() const @property
  {
return first;
  }
}

void main()
{
import std.range : take;
import std.array : array;

FibonacciRange fib;

auto fib10 = take(fib, elemth);
long[] the10Fibs = array(fib10);
}