Skip to content

Commit

Permalink
Fix inconsistency issues where some range properties are required to …
Browse files Browse the repository at this point in the history
…have @Property because of quirk in typeof for member functions.
  • Loading branch information
schveiguy committed Jun 5, 2015
1 parent 0fd3713 commit ad1eeff
Showing 1 changed file with 38 additions and 6 deletions.
44 changes: 38 additions & 6 deletions std/range/primitives.d
Expand Up @@ -759,7 +759,8 @@ The following code should compile for any forward range.
----
static assert(isInputRange!R);
R r1;
static assert (is(typeof(r1.save) == R));
auto s1 = r1.save;
static assert (is(typeof(s1) == R));
----
Saving a range is not duplicating it; in the example above, $(D r1)
Expand All @@ -777,7 +778,11 @@ template isForwardRange(R)
(inout int = 0)
{
R r1 = R.init;
static assert (is(typeof(r1.save) == R));
// NOTE: we cannot check typeof(r1.save) directly
// because typeof may not check the right type there, and
// because we want to ensure the range can be copied.
auto s1 = r1.save;
static assert (is(typeof(s1) == R));
}));
}

Expand All @@ -787,6 +792,17 @@ template isForwardRange(R)
static assert(!isForwardRange!(int));
static assert( isForwardRange!(int[]));
static assert( isForwardRange!(inout(int)[]));

// BUG 14544
struct R14544
{
int front() { return 0;}
void popFront() {}
bool empty() { return false; }
R14544 save() {return this;}
}

static assert( isForwardRange!R14544 );
}

/**
Expand Down Expand Up @@ -882,7 +898,8 @@ template isRandomAccessRange(R)
isForwardRange!R && isInfinite!R);
R r = R.init;
auto e = r[1];
static assert(is(typeof(e) == typeof(r.front)));
auto f = r.front;
static assert(is(typeof(e) == typeof(f)));
static assert(!isNarrowString!R);
static assert(hasLength!R || isInfinite!R);

Expand All @@ -907,7 +924,8 @@ unittest

R r = [0,1];
auto e = r[1]; // can index
static assert(is(typeof(e) == typeof(r.front))); // same type for indexed and front
auto f = r.front;
static assert(is(typeof(e) == typeof(f))); // same type for indexed and front
static assert(!isNarrowString!R); // narrow strings cannot be indexed as ranges
static assert(hasLength!R || isInfinite!R); // must have length or be infinite

Expand Down Expand Up @@ -953,10 +971,24 @@ unittest
alias opDollar = length;
//int opSlice(uint, uint);
}
struct E
{
bool empty();
E save();
int front();
void popFront();
int back();
void popBack();
ref int opIndex(uint);
size_t length();
alias opDollar = length;
//int opSlice(uint, uint);
}
static assert(!isRandomAccessRange!(A));
static assert(!isRandomAccessRange!(B));
static assert(!isRandomAccessRange!(C));
static assert( isRandomAccessRange!(D));
static assert( isRandomAccessRange!(E));
static assert( isRandomAccessRange!(int[]));
static assert( isRandomAccessRange!(inout(int)[]));
}
Expand Down Expand Up @@ -1354,7 +1386,7 @@ template hasLength(R)
(inout int = 0)
{
R r = R.init;
static assert(is(typeof(r.length) : ulong));
ulong l = r.length;
}));
}

Expand All @@ -1369,7 +1401,7 @@ template hasLength(R)
struct B { size_t length() { return 0; } }
struct C { @property size_t length() { return 0; } }
static assert( hasLength!(A));
static assert(!hasLength!(B));
static assert( hasLength!(B));
static assert( hasLength!(C));
}

Expand Down

0 comments on commit ad1eeff

Please sign in to comment.