1 /**
2     Ranges with non copyable elements.
3 
4     License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
5     Authors:   Adam Búš
6 */
7 module btl.traits.range;
8 
9 import std.traits : ReturnType, isAutodecodableString, isAggregateType, lvalueOf;
10 import std.range : empty, popFront, front, popBack, back, save,
11     isInputRange, ElementType, hasLength, isInfinite;
12 
13 
14 
15 
16 /**
17     Same as std.range.isInputRange but support non copyable elements.
18 */
19 public template isBtlInputRange(R){
20     static if(isInputRange!R)
21         enum bool impl = true;
22     else{
23         static ref front_check(R)(R r){
24             return r.front;
25         }
26         enum bool impl = true
27             && is(typeof(R.init) == R)
28             && is(ReturnType!((R r) => r.empty) == bool)
29             && is(typeof(*(return ref R r)@trusted => &r.front))
30             && !is(ReturnType!(front_check!R) == void)
31             && is(typeof((R r) => r.popFront));
32     }
33 
34     enum bool isBtlInputRange = impl;
35 };
36 
37 
38 
39 /**
40     Same as std.range.isForwardRange but support non copyable elements.
41 */
42 public enum bool isBtlForwardRange(R) = isBtlInputRange!R
43     && is(ReturnType!((R r) => r.save) == R);
44 
45 
46 
47 /**
48     Same as std.range.isBidirectionalRange but support non copyable elements.
49 */
50 public enum bool isBtlBidirectionalRange(R) = isBtlForwardRange!R
51     && is(typeof((R r) => r.popBack))
52     && is(ReturnType!((R r) => r.back) == ElementType!R);
53 
54 
55 
56 /**
57     Same as std.range.isRandomAccessRange but support non copyable elements.
58 */
59 public enum bool isBtlRandomAccessRange(R) =
60     is(typeof(lvalueOf!R[1]) == ElementType!R)
61     && !(isAutodecodableString!R && !isAggregateType!R)
62     && isBtlForwardRange!R
63     && (isBtlBidirectionalRange!R || isInfinite!R)
64     && (hasLength!R || isInfinite!R)
65     && (isInfinite!R || !is(typeof(lvalueOf!R[$ - 1]))
66         || is(typeof(lvalueOf!R[$ - 1]) == ElementType!R));
67