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