phobos/std/internal/test/dummyrange.d
Dragos Carp d698887729 Remove obsolete TypeTuple references
Replace following names:
std.typetuple      -> std.meta
TypeTuple          -> AliasSeq
ParameterTypeTuple -> Parameters
FieldTypeTuple     -> Fields

std.traits requires more work than search/replace and is left unchanged.
2015-10-13 20:37:44 +02:00

241 lines
5.6 KiB
D

/**
For testing only.
Used with the dummy ranges for testing higher order ranges.
*/
module std.internal.test.dummyrange;
import std.meta;
import std.typecons;
import std.range.primitives;
enum RangeType
{
Input,
Forward,
Bidirectional,
Random
}
enum Length
{
Yes,
No
}
enum ReturnBy
{
Reference,
Value
}
// Range that's useful for testing other higher order ranges,
// can be parametrized with attributes. It just dumbs down an array of
// numbers 1..10.
struct DummyRange(ReturnBy _r, Length _l, RangeType _rt)
{
// These enums are so that the template params are visible outside
// this instantiation.
enum r = _r;
enum l = _l;
enum rt = _rt;
uint[] arr = [1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U];
void reinit()
{
// Workaround for DMD bug 4378
arr = [1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U];
}
void popFront()
{
arr = arr[1..$];
}
@property bool empty() const
{
return arr.length == 0;
}
static if(r == ReturnBy.Reference)
{
@property ref inout(uint) front() inout
{
return arr[0];
}
@property void front(uint val)
{
arr[0] = val;
}
}
else
{
@property uint front() const
{
return arr[0];
}
}
static if(rt >= RangeType.Forward)
{
@property typeof(this) save()
{
return this;
}
}
static if(rt >= RangeType.Bidirectional)
{
void popBack()
{
arr = arr[0..$ - 1];
}
static if(r == ReturnBy.Reference)
{
@property ref inout(uint) back() inout
{
return arr[$ - 1];
}
@property void back(uint val)
{
arr[$ - 1] = val;
}
}
else
{
@property uint back() const
{
return arr[$ - 1];
}
}
}
static if(rt >= RangeType.Random)
{
static if(r == ReturnBy.Reference)
{
ref inout(uint) opIndex(size_t index) inout
{
return arr[index];
}
void opIndexAssign(uint val, size_t index)
{
arr[index] = val;
}
}
else
{
uint opIndex(size_t index) const
{
return arr[index];
}
}
typeof(this) opSlice(size_t lower, size_t upper)
{
auto ret = this;
ret.arr = arr[lower..upper];
return ret;
}
}
static if(l == Length.Yes)
{
@property size_t length() const
{
return arr.length;
}
alias opDollar = length;
}
}
enum dummyLength = 10;
alias AllDummyRanges = AliasSeq!(
DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Forward),
DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Bidirectional),
DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random),
DummyRange!(ReturnBy.Reference, Length.No, RangeType.Forward),
DummyRange!(ReturnBy.Reference, Length.No, RangeType.Bidirectional),
DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Input),
DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Forward),
DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Bidirectional),
DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random),
DummyRange!(ReturnBy.Value, Length.No, RangeType.Input),
DummyRange!(ReturnBy.Value, Length.No, RangeType.Forward),
DummyRange!(ReturnBy.Value, Length.No, RangeType.Bidirectional)
);
/**
Tests whether forward, bidirectional and random access properties are
propagated properly from the base range(s) R to the higher order range
H. Useful in combination with DummyRange for testing several higher
order ranges.
*/
template propagatesRangeType(H, R...)
{
static if(allSatisfy!(isRandomAccessRange, R))
enum bool propagatesRangeType = isRandomAccessRange!H;
else static if(allSatisfy!(isBidirectionalRange, R))
enum bool propagatesRangeType = isBidirectionalRange!H;
else static if(allSatisfy!(isForwardRange, R))
enum bool propagatesRangeType = isForwardRange!H;
else
enum bool propagatesRangeType = isInputRange!H;
}
template propagatesLength(H, R...)
{
static if(allSatisfy!(hasLength, R))
enum bool propagatesLength = hasLength!H;
else
enum bool propagatesLength = !hasLength!H;
}
/**
Reference type input range
*/
class ReferenceInputRange(T)
{
import std.array : array;
this(Range)(Range r) if (isInputRange!Range) {_payload = array(r);}
final @property ref T front(){return _payload.front;}
final void popFront(){_payload.popFront();}
final @property bool empty(){return _payload.empty;}
protected T[] _payload;
}
/**
Reference forward range
*/
class ReferenceForwardRange(T) : ReferenceInputRange!T
{
this(Range)(Range r) if (isInputRange!Range) {super(r);}
final @property ReferenceForwardRange save()
{return new ReferenceForwardRange!T(_payload);}
}
//Infinite input range
class ReferenceInfiniteInputRange(T)
{
this(T first = T.init) {_val = first;}
final @property T front(){return _val;}
final void popFront(){++_val;}
enum bool empty = false;
protected T _val;
}
//Infinite forward range
class ReferenceInfiniteForwardRange(T) : ReferenceInfiniteInputRange!T
{
this(T first = T.init) {super(first);}
final @property ReferenceInfiniteForwardRange save()
{return new ReferenceInfiniteForwardRange!T(_val);}
}