1 /++ Construction of types. 2 3 Typically used for functional construction of containers. 4 5 These generic factory functions prevents the need for defining separate 6 member factory functions for each container/collection class opposite to 7 what Rust's std.collection types define as `withLength`, `withCapacity`, 8 etc. This adhere's to the dry-principle. 9 10 See: nxt.container and std.container. 11 +/ 12 module nxt.construction; 13 14 import std.range.primitives : isInputRange, ElementType; 15 16 /++ Construct an instance of `T` with capacity `capacity`. 17 +/ 18 T makeOfCapacity(T, Capacity)(Capacity capacity) 19 if (/+is(typeof(T.init.reserve(0))) && +/is(Capacity : size_t)) { 20 T t; 21 t.reserve(capacity); /+ TODO: Check that this allowed in template-restriction +/ 22 return t; 23 } 24 25 /// 26 @safe pure unittest { 27 alias A = int[]; 28 const n = 3; 29 const a = makeOfCapacity!(A)(n); 30 assert(a.capacity == n); 31 } 32 33 /++ Construct an instance of `T` with length `n`. 34 +/ 35 T makeOfLength(T, Length)(Length length) if (is(Length : size_t)) { 36 T t; 37 t.length = length; /+ TODO: Check that this allowed in template-restriction +/ 38 return t; 39 } 40 41 /// 42 @safe pure unittest { 43 alias A = int[]; 44 const n = 3; 45 const a = makeOfLength!(A)(n); 46 assert(a.length == n); 47 } 48 49 /++ Construct an instance of `T` with `elements`. 50 +/ 51 T makeWithElements(T, R)(R elements) if (isInputRange!R) { 52 import std.range.primitives : hasLength; 53 static if (is(typeof(T.init.reserve(0))) && hasLength!R) { 54 // pragma(msg, __FILE__, "(", __LINE__, ",1): Debug: ", T); 55 T t = makeOfCapacity!T(elements.length); 56 } 57 else 58 T t; 59 t ~= elements; // TODO: use `.put` instead? 60 return t; 61 } 62 63 /// 64 @safe pure unittest { 65 alias A = int[]; 66 const elements = [1,2,3]; 67 const a = makeWithElements!(A)(elements); 68 assert(a.capacity == elements.length); 69 assert(a.length == elements.length); 70 } 71 72 /// Returns: shallow duplicate of `a`. 73 T dupShallow(T)(in T a) 74 if (is(typeof(T.init[])) && // `hasSlicing!T` 75 !is(T == const(U)[], U) && // builtin arrays already have `.dup` property 76 __traits(isCopyable, ElementType!T)) { 77 /+ TODO: delay slicing of `a` when T is a static array for compile-time 78 length optimization: +/ 79 return makeWithElements!(T)(a[]); 80 } 81 alias dup = dupShallow; 82 83 /// 84 version (none) 85 @safe pure unittest { 86 alias A = int[]; 87 const elements = [1,2,3]; 88 const a = makeWithElements!(A)(elements); 89 const b = a.dupShallow; 90 assert(a == b); 91 assert(a.ptr !is b.ptr); 92 }