Created
November 11, 2015 23:11
-
-
Save JesseKPhillips/1ab83e52e6e6060b1e84 to your computer and use it in GitHub Desktop.
Provides testing of wrapping a structure into Range interfaces
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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