1 // Written in the D programming language.
2 /**
3 This module provides the necessary utility methods, to be used only internally
4 Copyright: Copyright 2019 Ernesto Castellotti <erny.castell@gmail.com>
5 License:   $(HTTP https://www.mozilla.org/en-US/MPL/2.0/, Mozilla Public License - Version 2.0).
6 Authors:   $(HTTP github.com/ErnyTech, Ernesto Castellotti)
7 */
8 module dlist.baselist;
9 
10 mixin template ListOperatorOverload(T) {
11     @nogc final auto opBinary(string op)(T elem) if(op == "+" || op == "~") {
12         add(elem);
13         return this;
14     }
15 
16     @nogc final auto opBinary(string op)(T[] otherArray) if(op == "+" || op == "~") {
17         addAll(otherArray);
18         return this;
19     }
20 
21     @nogc final auto opBinary(string op)(List!T otherList) if(op == "+" || op == "~") {
22         addAll(otherList);
23         return this;
24     }
25 
26     @nogc final ref auto opIndex(ulong index) {
27         return getRef(index);
28     }
29 
30     @nogc final auto opSlice(this T)(size_t a, size_t b) {
31         return subArray(a, b);
32     }
33 
34     @nogc final auto opSlice(this T)() {
35         return opSlice!(T)(0, length);
36     }
37 
38     final int opApply(scope int delegate(ref T) operations) {
39         return opApply(operations);
40     }
41 
42     @nogc final int opApply(scope int delegate(ref T) @nogc operations) {
43         return opApply(operations);
44     }
45 
46     final int opApply(scope int delegate(ulong index, ref T) operations) {
47         return implOpApplyIndex(operations);
48     }
49 
50     @nogc final int opApply(scope int delegate(ulong index, ref T) @nogc operations) {
51         return implOpApplyIndex(operations);
52     }
53 
54     final int implOpApply(O)(O operations) {
55         int result = 0;
56 
57         foreach(elem; toArray) {
58             result = operations(elem);
59 
60             if(result) {
61                 break;
62             }
63         }
64 
65         return result;
66     }
67 
68     final int implOpApplyIndex(O)(O operations) {
69         int result = 0;
70 
71         foreach(i, elem; toArray) {
72             result = operations(i, elem);
73 
74             if(result) {
75                 break;
76             }
77         }
78 
79         return result;
80     }
81 
82     final int opApplyReverse(int delegate(ref T) operations) {
83         return implOpApplyReverse(operations);
84     }
85 
86     @nogc final int opApplyReverse(int delegate(ref T) @nogc operations) {
87         return implOpApplyReverse(operations);
88     }
89 
90     final int opApplyReverse(scope int delegate(ulong index, ref T) operations) {
91        return implOpApplyReverseIndex(operations);
92     }
93 
94     @nogc final int opApplyReverse(scope int delegate(ulong index, ref T) @nogc operations) {
95        return implOpApplyReverseIndex(operations);
96     }
97 
98     final int implOpApplyReverse(O)(O operations) {
99         int result = 0;
100 
101         foreach_reverse(elem; toArray) {
102             result = operations(elem);
103 
104             if(result) {
105                 break;
106             }
107         }
108 
109         return result;
110     }
111 
112     final int implOpApplyReverseIndex(O)(O operations) {
113         int result = 0;
114 
115         foreach_reverse(i, elem; toArray) {
116             result = operations(i, elem);
117 
118             if(result) {
119                 break;
120             }
121         }
122 
123         return result;
124     }
125 
126     @nogc final auto opOpAssign(string op)(T elem) if(op == "+" || op == "~") {
127         add(elem);
128         return this;
129     }
130 
131     @nogc final auto opOpAssign(string op)(T[] otherArray) if(op == "+" || op == "~") {
132         addAll(elem);
133         return this;
134     }
135 
136     @nogc final auto opOpAssign(string op)(List!T otherList) if(op == "+" || op == "~") {
137         addAll(otherList);
138         return this;
139     }
140 }
141 
142 mixin template AllocatorInit(Allocator) {
143     import stdx.allocator.common : stateSize;
144 
145 	static if (stateSize!Allocator == 0) {
146 		alias allocator = Allocator.instance;
147     } else {
148 		Allocator allocator;
149     }
150 }
151 
152 mixin template UseGC(T) {
153 	import std.traits : hasIndirections;
154 	enum useGC = hasIndirections!T;
155 }