Skip to content

Commit f0f6681

Browse files
authored
Merge pull request #150 from dlang-community/fix_ref_returns
Fix #148 merged-on-behalf-of: Brian Schott <Hackerpilot@users.noreply.github.com>
2 parents 4dcbcb9 + da7d8ae commit f0f6681

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed

src/containers/cyclicbuffer.d

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,23 +226,23 @@ struct CyclicBuffer(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange
226226
auto ref front(this This)() nothrow pure @property @safe
227227
{
228228
version (assert) if (empty) onRangeError();
229-
alias ET = ContainerElementType!(This, T);
229+
alias ET = ContainerElementType!(This, T, true);
230230
return cast(ET) storage[start];
231231
}
232232

233233
/// Accesses to the item at the end of the buffer.
234234
auto ref back(this This)() nothrow pure @property @safe
235235
{
236236
version (assert) if (empty) onRangeError();
237-
alias ET = ContainerElementType!(This, T);
237+
alias ET = ContainerElementType!(This, T, true);
238238
return cast(ET) storage[end];
239239
}
240240

241241
/// buffer[i]
242242
auto ref opIndex(this This)(size_t i) nothrow pure @safe
243243
{
244244
version (assert) if (i >= length) onRangeError();
245-
alias ET = ContainerElementType!(This, T);
245+
alias ET = ContainerElementType!(This, T, true);
246246
return cast(ET) storage[(start + i) % $];
247247
}
248248

src/containers/hashmap.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ struct HashMap(K, V, Allocator = Mallocator, alias hashFunction = generateHash!K
116116
import std.conv : text;
117117
import std.exception : enforce;
118118

119-
alias CET = ContainerElementType!(This, V);
119+
alias CET = ContainerElementType!(This, V, true);
120120
size_t i;
121121
auto n = find(key, i);
122122
enforce(n !is null, "'" ~ text(key) ~ "' not found in HashMap");

src/containers/internal/element_type.d

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@
77

88
module containers.internal.element_type;
99

10-
template ContainerElementType(ContainerType, ElementType)
10+
/**
11+
* Figures out the types that should be shown to users of the containers when
12+
* functions such as front and opIndex are called.
13+
*
14+
* Params:
15+
* ContainerType = The container type, usually taken from a `this This`
16+
* template argument
17+
* ElementType = The type of the elements of the container.
18+
* isRef = If the type is being determined for a function that returns `ref`
19+
*/
20+
template ContainerElementType(ContainerType, ElementType, bool isRef = false)
1121
{
1222
import std.traits : isMutable, hasIndirections, PointerTarget, isPointer, Unqual;
1323

@@ -52,10 +62,12 @@ template ContainerElementType(ContainerType, ElementType)
5262
}
5363

5464
static if (isMutable!ContainerType)
65+
{
5566
alias ContainerElementType = ElementType;
67+
}
5668
else
5769
{
58-
static if (hasIndirections!ElementType)
70+
static if (isRef || hasIndirections!ElementType)
5971
alias ContainerElementType = ET!(is(ContainerType == const), ElementType);
6072
else
6173
alias ContainerElementType = ElementType;

test/compile_test.d

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,13 @@ private void checkSliceFunctionality(Type, Container)(ref Container container)
340340

341341
private void checkIndexFunctionality(Type, KeyType, Container)(ref Container container)
342342
{
343+
import std.traits : hasFunctionAttributes;
344+
343345
static assert(__traits(compiles, {container[KeyType.init];}));
344-
static assert(is(typeof(container[KeyType.init]) == Type));
346+
// The tests here will expect the wrong thing for opIndex implementations
347+
// that return by ref.
348+
static if (!hasFunctionAttributes!(Container.opIndex!Container, "ref"))
349+
static assert(is(typeof(container[KeyType.init]) == Type));
345350
static assert(is(typeof(container.length) == size_t));
346351
assert(container.length == 0);
347352
}

0 commit comments

Comments
 (0)