Skip to content

Instantly share code, notes, and snippets.

@JesseKPhillips
Created November 11, 2015 23:11
Show Gist options
  • Save JesseKPhillips/1ab83e52e6e6060b1e84 to your computer and use it in GitHub Desktop.
Save JesseKPhillips/1ab83e52e6e6060b1e84 to your computer and use it in GitHub Desktop.
Provides testing of wrapping a structure into Range interfaces
// Based on: http://he-the-great.livejournal.com/49174.html
import std.range;
import exp = std.experimental.typecons;
interface InputRange(E) {
@property E front();
void popFront();
@property bool empty();
}
interface ForwardRange(E) : InputRange!E {
@property ForwardRange!E save();
}
interface BidirectionalRange(E) : ForwardRange!(E) {
override @property BidirectionalRange!E save();
@property E back();
void popBack();
}
interface HasLength(E) : InputRange!(E) {
@property size_t length();
}
interface RandomAccess(E) : BidirectionalRange!(E), HasLength!(E) {
override @property RandomAccess!E save();
E opIndex(size_t);
override @property size_t length();
alias length opDollar;
}
interface HasSlicing(E) : ForwardRange!(E), HasLength!(E) {
HasSlicing!E opSlice(size_t, size_t);
}
void main() {
auto sall = sFullPower!int();
verifyAll(sall);
auto sr1 = exp.wrap!(InputRange!int)(sall);
verifyInputRange(sr1);
//auto sr2 = exp.wrap!(ForwardRange!int)(sall);
//verifyForwardRange(sr2);
//auto sr3 = exp.wrap!(BidirectionalRange!int)(sall);
//verifyBidirectionalRange(sr3);
//auto sr4 = exp.wrap!(HasLength!int)(sall);
//verifyHasLengthRange(sr4);
//auto sr5 = exp.wrap!(HasSlicing!int)(sall);
//verifyHasSlicingRange(sr5);
}
auto verifyAll(R)(R t) {
static assert(isInputRange!(R));
static assert(isForwardRange!(R));
static assert(isBidirectionalRange!(R));
static assert(isRandomAccessRange!(R));
static assert(hasMobileElements!(R));
static assert(hasLength!(R));
static assert(hasSlicing!(R));
//static assert(hasLvalueElements!(R));
//static assert(hasSwappableElements!(R));
//static assert(hasAssignableElements!(R));
}
auto verifyInputRange(R)(R t) {
static assert(isInputRange!(R));
static assert(!isForwardRange!(R));
static assert(!isBidirectionalRange!(R));
static assert(!isRandomAccessRange!(R));
static assert(!hasLength!(R));
static assert(!hasSlicing!(R));
//static assert(!hasMobileElements!(R));
}
auto verifyForwardRange(R)(R t) {
static assert(isInputRange!(R));
static assert(isForwardRange!(R));
static assert(!isBidirectionalRange!(R));
static assert(!isRandomAccessRange!(R));
static assert(!hasLength!(R));
static assert(!hasSlicing!(R));
}
auto verifyBidirectionalRange(R)(R t) {
static assert(isInputRange!(R));
static assert(isForwardRange!(R));
static assert(isBidirectionalRange!(R));
static assert(!isRandomAccessRange!(R));
static assert(!hasLength!(R));
static assert(!hasSlicing!(R));
}
auto verifyHasLengthRange(R)(R t) {
static assert(isInputRange!(R));
static assert(hasLength!(R));
static assert(!isForwardRange!(R));
static assert(!isBidirectionalRange!(R));
static assert(!isRandomAccessRange!(R));
static assert(!hasSlicing!(R));
}
auto verifyHasSlicingRange(R)(R t) {
static assert(isInputRange!(R));
//static assert(isForwardRange!(R));
static assert(hasLength!(R));
//static assert(hasSlicing!(R));
static assert(!isBidirectionalRange!(R));
static assert(!isRandomAccessRange!(R));
}
struct sFullPower(E) {
E[] r;
@property bool empty() {
return r.empty;
}
@property E front() {
return r.front;
}
@property sFullPower save() {
auto a = sFullPower();
a.r = r;
return a;
}
@property size_t length() {
return r.length;
}
void popFront() {
r.popFront();
}
sFullPower opSlice(size_t lhs, size_t rhs) {
auto a = sFullPower();
a.r = r[lhs..rhs];
return a;
}
@property E back() {
return r.back;
}
void popBack() {
r.back;
}
E opIndex(size_t i) {
return r[i];
}
size_t opDollar() {
return r.length;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment