Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/tools/build/v2/util/sequence.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: 7.9 KB
Line 
1# Copyright 2001, 2002, 2003 Dave Abrahams
2# Copyright 2006 Rene Rivera
3# Copyright 2002, 2003 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
7import assert ;
8import numbers ;
9import modules ;
10
11# Note that algorithms in this module execute largely in the caller's
12# module namespace, so that local rules can be used as function
13# objects. Also note that most predicates can be multi-element
14# lists. In that case, all but the first element are prepended to the
15# first argument which is passed to the rule named by the first
16# element.
17
18# Return the elements e of $(sequence) for which [ $(predicate) e ]
19# has a non-null value.
20rule filter ( predicate + : sequence * )
21{
22    local caller = [ CALLER_MODULE ] ;
23    local result ;
24
25    for local e in $(sequence)
26    {
27        if [ modules.call-in $(caller) : $(predicate) $(e) ]
28        {
29            result += $(e) ;
30        }
31    }
32    return $(result) ;
33}
34
35# return a new sequence consisting of [ $(function) $(e) ] for each
36# element e of $(sequence).
37rule transform ( function + : sequence * )
38{
39    local caller = [ CALLER_MODULE ] ;
40    local result ;
41
42    for local e in $(sequence)
43    {
44        result += [ modules.call-in $(caller) : $(function) $(e) ] ;
45    }
46    return $(result) ;
47}
48
49rule reverse ( s * )
50{
51    local r ;
52    for local x in $(s)
53    {
54        r = $(x) $(r) ;
55    }
56    return $(r) ;
57}
58
59
60rule less ( a b )
61{
62    if $(a) < $(b)
63    {
64        return true ;
65    }
66}
67
68# insertion-sort s using the BinaryPredicate ordered.
69rule insertion-sort ( s * : ordered * )
70{
71    if ! $(ordered)
72    {
73        return [ SORT $(s) ] ;
74    }
75    else
76    {           
77        local caller = [ CALLER_MODULE ] ;
78        ordered ?= sequence.less ;
79        local result = $(s[1]) ;
80        if $(ordered) = sequence.less
81        {
82            local head tail ;
83            for local x in $(s[2-])
84            {
85                head = ;
86                tail = $(result) ;
87                while $(tail) && ( $(tail[1]) < $(x) )
88                {
89                    head += $(tail[1]) ;
90                    tail = $(tail[2-]) ;
91                }
92                result = $(head) $(x) $(tail) ;
93            }
94        }
95        else
96        {
97            for local x in $(s[2-])
98            {
99                local head tail ;
100                tail = $(result) ;
101                while $(tail) && [ modules.call-in $(caller) : $(ordered) $(tail[1]) $(x) ]
102                {
103                    head += $(tail[1]) ;
104                    tail = $(tail[2-]) ;
105                }
106                result = $(head) $(x) $(tail) ;
107            }
108        }
109       
110        return $(result) ;
111    }   
112}
113
114# merge two ordered sequences using the BinaryPredicate ordered.
115rule merge ( s1 * : s2 * : ordered * )
116{
117    ordered ?= sequence.less ;
118    local result__ ;
119    local caller = [ CALLER_MODULE ] ;
120
121    while $(s1) && $(s2) {
122        if [ modules.call-in $(caller) : $(ordered) $(s1[1]) $(s2[1]) ]
123        {
124            result__ += $(s1[1]) ;
125            s1 = $(s1[2-]) ;
126        }
127        else if [ modules.call-in $(caller) : $(ordered) $(s2[1]) $(s1[1]) ]
128        {
129            result__ += $(s2[1]) ;
130            s2 = $(s2[2-]) ;
131        }
132        else
133        {           
134            s2 = $(s2[2-]) ;
135        }
136       
137    }
138    result__ += $(s1) ;
139    result__ += $(s2) ;
140
141    return $(result__) ;
142}
143
144# join the elements of s into one long string. If joint is supplied,
145# it is used as a separator.
146rule join ( s * : joint ? )
147{
148    joint ?= "" ;
149    return $(s:J=$(joint)) ;
150}
151
152# Find the length of any sequence.
153rule length ( s * )
154{
155    local result = 0 ;
156    for local i in $(s)
157    {
158        result = [ CALC $(result) + 1 ] ;
159    }
160    return $(result) ;
161}
162
163rule unique ( list * : stable ? )
164{
165    local result ;
166    local prev ;
167    if $(stable)
168    {
169        for local f in $(list)
170        {
171            if ! $(f) in $(result)
172            {
173                result += $(f) ;
174            }
175        }
176    }
177    else
178    {
179        for local i in [ SORT $(list) ]
180        {
181            if $(i) != $(prev)
182            {
183                result += $(i) ;
184            }
185            prev = $(i) ;
186        }
187    }
188    return $(result) ;
189}
190
191# Returns the maximum number in 'elements'. Uses 'ordered' for comparisons,
192# or 'numbers.less' is none is provided.
193rule max-element ( elements + : ordered ? )
194{
195    ordered ?= numbers.less ;
196
197    local max = $(elements[1]) ;
198    for local e in $(elements[2-])
199    {
200        if [ $(ordered) $(max) $(e) ]
201        {
202            max = $(e) ;
203        }
204    }
205    return $(max) ;           
206}
207
208# Returns all of 'elements' for which corresponding element in parallel
209# list 'rank' is equal to the maximum value in 'rank'.
210rule select-highest-ranked ( elements * : ranks * )
211{
212    if $(elements)
213    {       
214        local max-rank = [ max-element $(ranks) ] ;
215        local result ;
216        while $(elements)
217        {
218            if $(ranks[1]) = $(max-rank)
219            {
220                result += $(elements[1]) ;
221            }
222            elements = $(elements[2-]) ;
223            ranks = $(ranks[2-]) ;
224        }
225        return $(result) ;
226    }   
227}
228NATIVE_RULE sequence : select-highest-ranked ;
229
230
231local rule __test__ ( )
232{
233    # use a unique module so we can test the use of local rules.
234    module sequence.__test__
235    {
236        import assert ;
237        import sequence ;
238       
239        local rule is-even ( n )
240        {
241            if $(n) in 0 2 4 6 8
242            {
243                return true ;
244            }
245        }
246
247        assert.result 4 6 4 2 8
248          : sequence.filter is-even : 1 4 6 3 4 7 2 3 8 ;
249
250        # test that argument binding works
251        local rule is-equal-test ( x y )
252        {
253            if $(x) = $(y)
254            {
255                return true ;
256            }
257        }
258
259        assert.result 3 3 3 : sequence.filter is-equal-test 3 : 1 2 3 4 3 5 3 5 7 ;
260
261        local rule append-x ( n )
262        {
263            return $(n)x ;
264        }
265
266        assert.result 1x 2x 3x : sequence.transform append-x : 1 2 3 ;
267
268        local rule repeat2 ( x )
269        {
270            return $(x) $(x) ;
271        }
272
273        assert.result 1 1 2 2 3 3 : sequence.transform repeat2 : 1 2 3 ;
274
275        local rule test-greater ( a b )
276        {
277            if $(a) > $(b)
278            {
279                return true ;
280            }
281        }
282        assert.result 1 2 3 4 5 6 7 8 9 : sequence.insertion-sort 9 6 5 3 8 7 1 2 4 ;
283        assert.result 9 8 7 6 5 4 3 2 1 : sequence.insertion-sort 9 6 5 3 8 7 1 2 4 : test-greater ;
284        assert.result 1 2 3 4 5 6 :  sequence.merge 1 3 5 : 2 4 6 ;
285        assert.result 6 5 4 3 2 1 :  sequence.merge 5 3 1 : 6 4 2 : test-greater ;
286        assert.result 1 2 3 : sequence.merge 1 2 3 : ;
287        assert.result 1 : sequence.merge 1 : 1 ;
288
289        assert.result foo-bar-baz : sequence.join foo bar baz : - ;
290        assert.result substandard : sequence.join sub stan dard ;
291        assert.result 3.0.1 : sequence.join 3.0.1 : - ;
292
293        assert.result 0 : sequence.length ;
294        assert.result 3 : sequence.length a b c ;
295        assert.result 17 : sequence.length 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 ;
296
297        assert.result 1 : sequence.length a ;
298        assert.result 10 : sequence.length a b c d e f g h i j ;
299        assert.result 11 : sequence.length a b c d e f g h i j k ;
300        assert.result 12 : sequence.length a b c d e f g h i j k l ;
301
302        local p2 = x ;
303        for local i in 1 2 3 4 5 6 7 8
304        {
305          p2 = $(p2) $(p2) ;
306        }
307        assert.result 256 : sequence.length $(p2) ;
308
309        assert.result 1 2 3 4 5
310          : sequence.unique 1 2 3 2 4 3 3 5 5 5 ;
311               
312        assert.result 5
313          : sequence.max-element 1 3 5 0 4 ;
314       
315        assert.result e-3 h-3
316          : sequence.select-highest-ranked e-1 e-3 h-3 m-2 : 1 3 3 2 ;
317       
318        assert.result 7 6 5 4 3 2 1 : sequence.reverse 1 2 3 4 5 6 7 ;
319    }
320}
Note: See TracBrowser for help on using the repository browser.