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 ) );