root/trunk/src/tutorials/examples/templates/iterator.d

Revision 6, 5.9 kB (checked in by jcc7, 3 years ago)

Made more progress in developing convertToWiki and added some files.

Line 
1 /*
2  * Copyright (c) 2004
3  * Sean Kelly
4  *
5  * Permission to use, copy, modify, distribute and sell this software
6  * and its documentation for any purpose is hereby granted without fee,
7  * provided that the above copyright notice appear in all copies and
8  * that both that copyright notice and this permission notice appear
9  * in supporting documentation.  Author makes no representations about
10  * the suitability of this software for any purpose. It is provided
11  * "as is" without express or implied warranty.
12  */
13
14
15 //
16 // simple list type
17 //
18 // this is defined kind of oddly to get around scoping problems
19 //
20 template List( Ty )
21 {
22 public:
23     alias Ty        Value;
24     alias size_t    Size;
25
26
27     class Node
28     {
29     public:
30         alias List!(Ty).Value   Value;
31    
32         this()
33         {
34             prev = this;
35             next = this;
36         }
37
38         this( Value v )
39         {
40             val = v;
41             this();
42         }
43
44     private:
45         Value   val;
46         Node    prev,
47                 next;
48     }
49
50
51     class Iterator
52     {
53     public:
54         alias List!(Ty).Value   Value;
55    
56         this( Node n )
57         {
58             ref = n;
59         }
60
61         Iterator opAddAssign( int unused )
62         {
63             ref = ref.next;
64             return this;
65         }
66 /*
67         Iterator opPostInc()
68         {
69             iterator tmp( ref );
70             ref = ref.next;
71             return tmp;
72         }
73 */
74         Iterator opSubAssign( int unused )
75         {
76             ref = ref.prev;
77             return this;
78         }
79 /*
80         Iterator opPostDec()
81         {
82             iterator tmp( ref );
83             ref = ref.prev;
84             return tmp;
85         }
86 */
87         int opEquals( Iterator rhs )
88         {
89             return ref == rhs.ref;
90         }
91
92         void val( Value v )
93         {
94             ref.val = v;
95         }
96
97         Value val()
98         {
99             return ref.val;
100         }
101        
102     private:
103         Node    ref;
104     }
105
106
107     class Container
108     {
109     public:
110         alias List!(Ty).Iterator Iterator;
111         alias List!(Ty).Value    Value;
112         alias List!(Ty).Size     Size;
113        
114         this()
115         {
116             m_head  = new Node();
117             m_size  = 0;
118         }
119    
120         Size size()
121         {
122             return m_size;
123         }
124    
125         bit empty()
126         {
127             return m_size == 0;
128         }
129    
130         Iterator begin()
131         {
132             return new Iterator( m_head.next );
133         }
134    
135         Iterator end()
136         {
137             return new Iterator( m_head );
138         }
139
140         Value front()
141         {
142             return m_head.next.val;
143         }
144
145         Value back()
146         {
147             return m_head.prev.val;
148         }
149
150         void pushFront( Value val )
151         {
152             insert( begin(), val );
153         }
154
155         void pushBack( Value val )
156         {
157             insert( end(), val );
158         }
159
160         Iterator insert( Iterator pos, Value val )
161         {
162             Node n = new Node( val );
163             n.next = pos.ref;
164             n.prev = pos.ref.prev;
165             pos.ref.prev.next = n;
166             pos.ref.prev = n;
167             ++m_size;
168             return --pos;
169         }
170
171     protected:
172         Node    m_head;
173         Size    m_size;
174     }
175 }
176
177
178 //
179 // default iterator definitions that apply
180 // to all user-defined containers
181 //
182 template IterImpl( Ty )
183 {
184     alias Ty            Container;
185     alias Ty.Iterator   Iterator;   
186     alias Ty.Value      Value;
187     alias Ty.Size       Size;
188
189     Iterator begin( Container cont )
190     {
191         return cont.begin();
192     }
193
194     Iterator end( Container cont )
195     {
196         return cont.end();
197     }
198 }
199
200
201 //
202 // iterator specialization for primitive array
203 //
204 template IterImpl( Ty : Ty[] )
205 {
206     alias Ty[]      Container;
207     alias Ty        Value;
208     alias size_t    Size;
209    
210     class Iterator
211     {
212     public:
213         this( Ty* pos )
214         {
215             m_pos = pos;
216         }
217
218         Iterator opAddAssign( int unused )
219         {
220             if( m_pos )
221                 ++m_pos;
222             return this;
223         }
224
225         Iterator opSubAssign( int unused )
226         {
227             if( m_pos )
228                 --m_pos;
229             return this;
230         }
231
232         int opEquals( Iterator rhs )
233         {
234             return m_pos == rhs.m_pos;
235         }
236
237         void val( Value val )
238         {
239             if( m_pos )
240                 *m_pos = val;
241         }
242
243         Value val()
244         {
245             return m_pos ? *m_pos : Ty.init;
246         }
247    
248     private:
249         Value*  m_pos;
250     }
251
252     Iterator begin( Container cont )
253     {
254         return new Iterator( cont.length ? &cont[0] : null );
255     }
256
257     Iterator end( Container cont )
258     {
259         return new Iterator( cont.length ? &cont[0] + cont.length : null );
260     }
261 }
262
263
264 //
265 // convenience wrappers to reduce type length
266 //
267 template Iterator( Ty )
268 {
269     alias IterImpl!(Ty).Iterator Iterator;
270 }
271
272
273 template begin( Ty )
274 {
275     alias IterImpl!(Ty).begin begin;
276 }
277
278
279 template end( Ty )
280 {
281     alias IterImpl!(Ty).end end;
282 }
283
284
285 //
286 // slightly lame sample algorithm that only works for int value types
287 //
288 template print( Iter )
289 {
290     void print( Iter begin, Iter end )
291     {
292         for( ; begin != end; ++begin )
293             printf( "%d\n", begin.val );
294     }
295 }
296
297
298 int main( char[][] args )
299 {
300     alias List!(int).Container  IntList;
301     alias int[]                 IntArray;
302
303     IntList     list    = new IntList();
304     IntArray    array;
305
306     list.insert( list.begin(), 1 );
307     list.insert( list.begin(), 2 );
308     list.insert( list.begin(), 3 );
309    
310     array.length = 3;
311     array[0] = 7;
312     array[1] = 8;
313     array[2] = 9;
314
315     Iterator!(IntList)  l_begin = begin!(IntList)( list ),
316                         l_end   = end!(IntList)( list );
317    
318     Iterator!(IntArray) a_begin = begin!(IntArray)( array ),
319                         a_end   = end!(IntArray)( array );
320
321     print!(Iterator!(IntList))( l_begin, l_end );
322     printf( "\n" );
323     print!(Iterator!(IntArray))( a_begin, a_end );
324     return 0;
325 }
Note: See TracBrowser for help on using the browser.