Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/tools/build/v2/util/container.jam @ 32

Last change on this file since 32 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 8.2 KB
Line 
1# Copyright 2003 Dave Abrahams
2# Copyright 2002, 2003 Rene Rivera
3# Copyright 2002, 2003, 2004 Vladimir Prus
4# Distributed under the Boost Software License, Version 1.0.
5# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
6
7# Various container classes.
8
9import "class" : * ;
10
11# Base for container objects. This lets us construct recursive structures.
12# That is containers with containers in them, specifically so we can tell
13# literal values from node values.
14#
15class node
16{
17    rule __init__ (
18      value ? # Optional value to set node to initially.
19    )
20    {
21        self.value = $(value) ;
22    }
23       
24    # Set the value of this node, passing nothing will clear it.
25    #
26    rule set ( value * )
27    {
28        self.value = $(value) ;
29    }
30   
31    # Get the value of this node.
32    #
33    rule get ( )
34    {
35        return $(self.value) ;
36    }
37}
38
39
40# A simple vector. Interface mimics the C++ std::vector and std::list,
41# with the exception that indices are one (1) based to follow Jam standard.
42#
43# TODO: Possibly add assertion checks.
44#
45class vector : node
46{
47    import numbers : range ;
48    import utility ;
49    import sequence ;
50       
51    rule __init__ (
52      values * # Initial contents of vector.
53    )
54    {
55        node.__init__ ;
56        self.value = $(values) ;
57    }   
58   
59    # Get the value of the first element.
60    #
61    rule front ( )
62    {
63        return $(self.value[1]) ;
64    }
65   
66    # Get the value of the last element.
67    #
68    rule back ( )
69    {
70        return $(self.value[-1]) ;
71    }
72   
73    # Get the value of the element at the given index, one based.
74    # Access to elements of recursive structures is supported directly.
75    # Specifying additional index values recursively accesses the elements as
76    # containers. For example: [ $(v).at 1 : 2 ] would retrieve the second element
77    # of our first element. This assuming the first element is a container.
78    #
79    rule at (
80        index # The element index, one based.
81        : * # Additional indices to access recursively.
82        )
83    {
84        local r = $(self.value[$(index)]) ;
85        if $(2)
86        {
87            r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
88        }
89        return $(r) ;
90    }
91   
92    # Get the value contained in the given element. This has the same
93    # functionality and interface as "at" but in addition gets the value
94    # of the referenced element, assuming it's a "node".
95    #
96    rule get-at (
97        index # The element index, one based.
98        : * # Additional indices to access recursively.
99        )
100    {
101        local r = $(self.value[$(index)]) ;
102        if $(2)
103        {
104            r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
105        }
106        return [ $(r).get ] ;
107    }
108   
109    # Insert the given value into the front of the vector pushing the
110    # rest of the elements back.
111    #
112    rule push-front (
113        value # Value to become first element.
114        )
115    {
116        self.value = $(value) $(self.value) ;
117    }
118   
119    # Remove the front element from the vector. Does not return the value.
120    # No effect if vector is empty.
121    #
122    rule pop-front ( )
123    {
124        self.value = $(self.value[2-]) ;
125    }
126   
127    # Add the given value at the end of the vector.
128    #
129    rule push-back (
130        value # Value to become back element.
131        )
132    {
133        self.value += $(value) ;
134    }
135   
136    # Remove the back element from the vector. Does not return the value.
137    # No effect if vector is empty.
138    #
139    rule pop-back ( )
140    {
141        self.value = $(self.value[1--2]) ;
142    }
143   
144    # Insert the given value at the given index, one based. The values
145    # at and to the right of the of the index are push back to make room
146    # for the new value.
147    #
148    rule insert (
149        index # The index to insert at, one based.
150        : value # The value to insert.
151        )
152    {
153        local left = $(self.value[1-$(index)]) ;
154        left = $(left[1--2]) ;
155        local right = $(self.value[$(index)-]) ;
156        self.value = $(left) $(value) $(right) ;
157    }
158   
159    # Remove one or more elements from the vector. The range is inclusive,
160    # and not specifying an end is equivalent to the [start,start] range.
161    #
162    rule erase (
163        start # Index of first element ro remove.
164        end ? # Optional, index of last element to remove.
165        )
166    {
167        end ?= $(start) ;
168        local left = $(self.value[1-$(start)]) ;
169        left = $(left[1--2]) ;
170        local right = $(self.value[$(end)-]) ;
171        right = $(right[2-]) ;
172        self.value = $(left) $(right) ;
173    }
174   
175    # Remove all elements from the vector.
176    #
177    rule clear ( )
178    {
179        self.value = ;
180    }
181   
182    # The number of elements in the vector.
183    #
184    rule size ( )
185    {
186        return [ sequence.length $(self.value) ] ;
187    }
188   
189    # Returns "true" if there are NO elements in the vector, empty
190    # otherwise.
191    #
192    rule empty ( )
193    {
194        if ! $(self.value)
195        {
196            return true ;
197        }
198    }
199
200    # Returns the list of all valid indices for this vector.
201    rule indices ( )
202    {
203        if ! [ empty ]
204        {
205            local size = [ size ] ;
206            return [ range 1 : $(size) ] $(size) ;
207        }     
208    }
209
210    # Returns the textual representation of content.
211    rule str ( )
212    {
213        return "[" [ sequence.transform utility.str : $(self.value) ] "]" ;
214    }
215
216    # Sorts the vector inplace, calling 'utility.less' for
217    # comparisons.
218    # NOTE: this rule is unused at the moment.
219    rule sort ( )
220    {
221        self.value =
222            [ sequence.insertion-sort $(self.value) : utility.less ] ;
223    }
224
225    # Returns true if content is equal to the content of other vector.
226    # Uses 'utility.equal' for comparison.
227    rule equal ( another )
228    {       
229        local mismatch ;
230        if [ size ] = [ $(another).size ]
231        {
232            for local i in [ indices ]
233            {
234                if ! [ utility.equal [ at $(i) ] [ $(another).at $(i) ] ]
235                {
236                    mismatch = true ;
237                }
238            }
239        }
240        else
241        {
242            mismatch = true ;
243        }
244                       
245        if ! $(mismatch)
246        {
247            return true ;
248        }
249    }
250}
251
252local rule __test__ ( )
253{
254    import assert ;
255    import "class" : new ;
256   
257    local l = [ new vector ] ;
258    assert.result 0 : $(l).size ;
259    assert.result : $(l).indices ;
260    assert.result "[" "]" : $(l).str ;
261    $(l).push-back b ;
262    $(l).push-front a ;
263    assert.result 1 2 : $(l).indices ;
264    assert.result "[" a b "]" : $(l).str ;
265    assert.result a : $(l).front ;
266    assert.result b : $(l).back ;
267    $(l).insert 2 : d ;
268    $(l).insert 2 : c ;
269    $(l).insert 4 : f ;
270    $(l).insert 4 : e ;
271    $(l).pop-back ;
272    assert.result 5 : $(l).size ;
273    assert.result d : $(l).at 3 ;
274    $(l).pop-front ;
275    assert.result c : $(l).front ;
276    assert.false $(l).empty ;
277    $(l).erase 3 4 ;
278    assert.result 2 : $(l).size ;
279   
280    local l2 = [ new vector q w e r t y ] ;
281    assert.result 6 : $(l2).size ;
282    $(l).push-back $(l2) ;
283    assert.result 3 : $(l).size ;
284    local l2-alias = [ $(l).back ] ;
285    assert.result e : $(l2-alias).at 3 ;
286    $(l).clear ;
287    assert.true $(l).empty ;
288    assert.false $(l2-alias).empty ;
289    $(l2).pop-back ;
290    assert.result t : $(l2-alias).back ;
291   
292    local l3 = [ new vector ] ;
293    $(l3).push-back [ new vector 1 2 3 4 5 ] ;
294    $(l3).push-back [ new vector a b c ] ;
295    assert.result "[" "[" 1 2 3 4 5 "]" "[" a b c "]" "]" : $(l3).str ;
296    $(l3).push-back [ new vector [ new vector x y z ] [ new vector 7 8 9 ] ] ;
297    assert.result 1 : $(l3).at 1 : 1 ;
298    assert.result b : $(l3).at 2 : 2 ;
299    assert.result a b c : $(l3).get-at 2 ;
300    assert.result 7 8 9 : $(l3).get-at 3 : 2 ;
301
302    local l4 = [ new vector 4 3 6 ] ;
303    $(l4).sort ;
304    assert.result 3 4 6 : $(l4).get ;
305
306    assert.false $(l4).equal $(l3) ;
307    local l5 = [ new vector 3 4 6 ] ;
308    assert.true $(l4).equal $(l5) ;
309    # Check that vectors of different sizes are considered non-equal
310    $(l5).pop-back ;   
311    assert.false $(l4).equal $(l5) ;
312    local l6 = [ new vector [ new vector 1 2 3 ] ] ;
313    assert.true $(l6).equal [ new vector [ new vector 1 2 3 ] ] ;
314}
Note: See TracBrowser for help on using the repository browser.