Mercurial > projects > ldc
comparison tango/tango/core/Tuple.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /** | |
2 * The tuple module defines a template struct used for arbitrary data grouping. | |
3 * | |
4 * Copyright: Copyright (C) 2005-2006 Sean Kelly. All rights reserved. | |
5 * License: BSD style: $(LICENSE) | |
6 * Authors: Walter Bright, Sean Kelly | |
7 */ | |
8 module tango.core.Tuple; | |
9 | |
10 | |
11 /** | |
12 * A Tuple is a an aggregate of typed values. Tuples are useful for returning | |
13 * a set of values from a function or for passing a set of parameters to a | |
14 * function. | |
15 * | |
16 * NOTE: Since the transition from user-defined to built-in tuples, the ability | |
17 * to return tuples from a function has been lost. Until this issue is | |
18 * addressed within the language, tuples must be enclosed in a struct | |
19 * if they are to be returned from a function. | |
20 * | |
21 * Example: | |
22 * ---------------------------------------------------------------------- | |
23 * | |
24 * alias Tuple!(int, real) T1; | |
25 * alias Tuple!(int, long) T2; | |
26 * struct Wrap( Vals... ) | |
27 * { | |
28 * Vals val; | |
29 * } | |
30 * | |
31 * Wrap!(T2) func( T1 val ) | |
32 * { | |
33 * Wrap!(T2) ret; | |
34 * ret.val[0] = val[0]; | |
35 * ret.val[1] = val[0] * cast(long) val[1]; | |
36 * return ret; | |
37 * } | |
38 * | |
39 * ---------------------------------------------------------------------- | |
40 * | |
41 * This is the original tuple example, and demonstates what should be possible | |
42 * with tuples. Hopefully, language support will be added for this feature | |
43 * soon. | |
44 * | |
45 * Example: | |
46 * ---------------------------------------------------------------------- | |
47 * | |
48 * alias Tuple!(int, real) T1; | |
49 * alias Tuple!(int, long) T2; | |
50 * | |
51 * T2 func( T1 val ) | |
52 * { | |
53 * T2 ret; | |
54 * ret[0] = val[0]; | |
55 * ret[1] = val[0] * cast(long) val[1]; | |
56 * return ret; | |
57 * } | |
58 * | |
59 * | |
60 * // tuples may be composed | |
61 * alias Tuple!(int) IntTuple; | |
62 * alias Tuple!(IntTuple, long) RetTuple; | |
63 * | |
64 * // tuples are equivalent to a set of function parameters of the same type | |
65 * RetTuple t = func( 1, 2.3 ); | |
66 * | |
67 * ---------------------------------------------------------------------- | |
68 */ | |
69 template Tuple( TList... ) | |
70 { | |
71 alias TList Tuple; | |
72 } | |
73 | |
74 | |
75 /** | |
76 * Returns the index of the first occurrence of T in TList or Tlist.length if | |
77 * not found. | |
78 */ | |
79 template IndexOf( T, TList... ) | |
80 { | |
81 static if( TList.length == 0 ) | |
82 const size_t IndexOf = 0; | |
83 else static if( is( T == TList[0] ) ) | |
84 const size_t IndexOf = 0; | |
85 else | |
86 const size_t IndexOf = 1 + IndexOf!( T, TList[1 .. $] ); | |
87 } | |
88 | |
89 | |
90 /** | |
91 * Returns a Tuple with the first occurrence of T removed from TList. | |
92 */ | |
93 template Remove( T, TList... ) | |
94 { | |
95 static if( TList.length == 0 ) | |
96 alias TList Remove; | |
97 else static if( is( T == TList[0] ) ) | |
98 alias TList[1 .. $] Remove; | |
99 else | |
100 alias Tuple!( TList[0], Remove!( T, TList[1 .. $] ) ) Remove; | |
101 } | |
102 | |
103 | |
104 /** | |
105 * Returns a Tuple with all occurrences of T removed from TList. | |
106 */ | |
107 template RemoveAll( T, TList... ) | |
108 { | |
109 static if( TList.length == 0 ) | |
110 alias TList RemoveAll; | |
111 else static if( is( T == TList[0] ) ) | |
112 alias .RemoveAll!( T, TList[1 .. $] ) RemoveAll; | |
113 else | |
114 alias Tuple!( TList[0], .RemoveAll!( T, TList[1 .. $] ) ) RemoveAll; | |
115 } | |
116 | |
117 | |
118 /** | |
119 * Returns a Tuple with the first offuccrence of T replaced with U. | |
120 */ | |
121 template Replace( T, U, TList... ) | |
122 { | |
123 static if( TList.length == 0 ) | |
124 alias TList Replace; | |
125 else static if( is( T == TList[0] ) ) | |
126 alias Tuple!(U, TList[1 .. $]) Replace; | |
127 else | |
128 alias Tuple!( TList[0], Replace!( T, U, TList[1 .. $] ) ) Replace; | |
129 } | |
130 | |
131 | |
132 /** | |
133 * Returns a Tuple with all occurrences of T replaced with U. | |
134 */ | |
135 template ReplaceAll( T, U, TList... ) | |
136 { | |
137 static if( TList.length == 0 ) | |
138 alias TList ReplaceAll; | |
139 else static if( is( T == TList[0] ) ) | |
140 alias Tuple!( U, ReplaceAll!( T, U, TList[1 .. $] ) ) ReplaceAll; | |
141 else | |
142 alias Tuple!( TList[0], ReplaceAll!( T, U, TList[1 .. $] ) ) ReplaceAll; | |
143 } | |
144 | |
145 | |
146 /** | |
147 * Returns a Tuple with the types from TList declared in reverse order. | |
148 */ | |
149 template Reverse( TList... ) | |
150 { | |
151 static if( TList.length == 0 ) | |
152 alias TList Reverse; | |
153 else | |
154 alias Tuple!( Reverse!( TList[1 .. $]), TList[0] ) Reverse; | |
155 } | |
156 | |
157 | |
158 /** | |
159 * Returns a Tuple with all duplicate types removed. | |
160 */ | |
161 template Unique( TList... ) | |
162 { | |
163 static if( TList.length == 0 ) | |
164 alias TList Unique; | |
165 else | |
166 alias Tuple!( TList[0], | |
167 Unique!( RemoveAll!( TList[0], | |
168 TList[1 .. $] ) ) ) Unique; | |
169 } | |
170 | |
171 | |
172 /** | |
173 * Returns the type from TList that is the most derived from T. If no such | |
174 * type is found then T will be returned. | |
175 */ | |
176 template MostDerived( T, TList... ) | |
177 { | |
178 static if( TList.length == 0 ) | |
179 alias T MostDerived; | |
180 else static if( is( TList[0] : T ) ) | |
181 alias MostDerived!( TList[0], TList[1 .. $] ) MostDerived; | |
182 else | |
183 alias MostDerived!( T, TList[1 .. $] ) MostDerived; | |
184 } | |
185 | |
186 | |
187 /** | |
188 * Returns a Tuple with the types sorted so that the most derived types are | |
189 * ordered before the remaining types. | |
190 */ | |
191 template DerivedToFront( TList... ) | |
192 { | |
193 static if( TList.length == 0 ) | |
194 alias TList DerivedToFront; | |
195 else | |
196 alias Tuple!( MostDerived!( TList[0], TList[1 .. $] ), | |
197 DerivedToFront!( ReplaceAll!( MostDerived!( TList[0], TList[1 .. $] ), | |
198 TList[0], | |
199 TList[1 .. $] ) ) ) DerivedToFront; | |
200 } | |
201 | |
202 | |
203 /* | |
204 * A brief test of the above templates. | |
205 */ | |
206 static assert( 0 == IndexOf!(int, int, float, char)); | |
207 static assert( 1 == IndexOf!(float, int, float, char)); | |
208 static assert( 3 == IndexOf!(double, int, float, char)); | |
209 | |
210 static assert( is( Remove!(int, int, float, int) == Remove!(void, float, int) ) ); | |
211 static assert( is( RemoveAll!(int, int, float, int) == Remove!(void, float) ) ); | |
212 static assert( is( Remove!(float, int, float, int) == Remove!(void, int, int) ) ); | |
213 static assert( is( Remove!(double, int, float, int) == Remove!(void, int, float, int) ) ); | |
214 | |
215 static assert( is( Replace!(int, char, int, float, int) == Remove!(void, char, float, int) ) ); | |
216 static assert( is( ReplaceAll!(int, char, int, float, int) == Remove!(void, char, float, char) ) ); | |
217 static assert( is( Replace!(float, char, int, float, int) == Remove!(void, int, char, int) ) ); | |
218 static assert( is( Replace!(double, char, int, float, int) == Remove!(void, int, float, int) ) ); | |
219 | |
220 static assert( is( Reverse!(float, float[], double, char, int) == | |
221 Unique!(int, char, double, float[], char, int, float, double) ) ); | |
222 | |
223 static assert( is( MostDerived!(int, long, short) == short ) ); |