From ea264712c14ccc0907bc67a37828fffb260fedfa Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Fri, 16 Aug 2002 13:58:23 +0000 Subject: [PATCH] New rules. * new/assert.jam (in, not-in): New rules. * new/class.jam (is-instance): New rule. * new/utility.jam (str, equal, less): New rules. * new/container.jam (container.str, container.sort, container.equal): New rules. [SVN r14923] --- src/kernel/class.jam | 7 ++++ src/util/assert.jam | 19 ++++++++++ src/util/container.jam | 54 ++++++++++++++++++++++++++++ src/util/utility.jam | 82 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+) diff --git a/src/kernel/class.jam b/src/kernel/class.jam index 58a3c997b..e045406b8 100644 --- a/src/kernel/class.jam +++ b/src/kernel/class.jam @@ -268,6 +268,13 @@ rule is-derived ( class : bases + ) return $(found) ; } +# Returns true if the 'value' is a class instance. +rule is-instance ( value # The value to check + ) +{ + return [ MATCH "(object@).*" : $(value) ] ; +} + # Check if the given value is of the given type. # rule is-a ( diff --git a/src/util/assert.jam b/src/util/assert.jam index 4f6567967..24525d998 100644 --- a/src/util/assert.jam +++ b/src/util/assert.jam @@ -91,3 +91,22 @@ rule false ( rule-name args * : * ) } } +# assert that 'element' is present in 'list'. +rule "in" ( element : list * ) +{ + if ! $(element) in $(list) + { + error-skip-frames 3 assertion failure: expecting $(element) in + "[" $(list) "]" ; + } +} + +# assert that 'element' is not present in 'list'. +rule not-in ( element : list * ) +{ + if $(element) in $(list) + { + error-skip-frames 3 assertion failure: did not expect $(element) in + "[" $(list) "]" ; + } +} \ No newline at end of file diff --git a/src/util/container.jam b/src/util/container.jam index d31770510..79c239edf 100644 --- a/src/util/container.jam +++ b/src/util/container.jam @@ -7,6 +7,7 @@ import class : * ; import sequence ; +import utility ; # Base for container objects. This lets us construct recursive structures. @@ -199,9 +200,49 @@ rule vector ( return [ range 1 : $(size) ] $(size) ; } } + + # Returns the textual representation of content. + rule str ( ) + { + return "[" [ sequence.transform utility.str : $(self.value) ] "]" ; + } + + # Sorts the vector inplace, calling 'utility.less' for + # comparisons. + rule sort ( ) + { + self.value = + [ sequence.insertion-sort $(self.value) : utility.less ] ; + } + + # Returns true if content is equal to the content of other vector. + # Uses 'utility.equal' for comparison. + rule equal ( another ) + { + local mismatch ; + if [ size ] = [ $(another).size ] + { + for local i in [ indices ] + { + if ! [ utility.equal [ at $(i) ] [ $(another).at $(i) ] ] + { + mismatch = true ; + } + } + } + if ! $(mismatch) + { + return true ; + } + } } class vector : node ; +module class@vector +{ + import numbers : range ; +} + local rule __test__ ( ) { import assert ; @@ -209,9 +250,11 @@ local rule __test__ ( ) local l = [ new vector ] ; assert.result 0 : $(l).size ; assert.result : $(l).indices ; + assert.result "[" "]" : $(l).str ; $(l).push-back b ; $(l).push-front a ; assert.result 1 2 : $(l).indices ; + assert.result "[" a b "]" : $(l).str ; assert.result a : $(l).front ; assert.result b : $(l).back ; $(l).insert 2 : d ; @@ -242,9 +285,20 @@ local rule __test__ ( ) local l3 = [ new vector ] ; $(l3).push-back [ new vector 1 2 3 4 5 ] ; $(l3).push-back [ new vector a b c ] ; + assert.result "[" "[" 1 2 3 4 5 "]" "[" a b c "]" "]" : $(l3).str ; $(l3).push-back [ new vector [ new vector x y z ] [ new vector 7 8 9 ] ] ; assert.result 1 : $(l3).at 1 : 1 ; assert.result b : $(l3).at 2 : 2 ; assert.result a b c : $(l3).get-at 2 ; assert.result 7 8 9 : $(l3).get-at 3 : 2 ; + + local l4 = [ new vector 4 3 6 ] ; + $(l4).sort ; + assert.result 3 4 6 : $(l4).get ; + + assert.false $(l4).equal $(l3) ; + local l5 = [ new vector 3 4 6 ] ; + assert.true $(l4).equal $(l5) ; + local l6 = [ new vector [ new vector 1 2 3 ] ] ; + assert.true $(l6).equal [ new vector [ new vector 1 2 3 ] ] ; } diff --git a/src/util/utility.jam b/src/util/utility.jam index 018bb70a8..8d2150c5f 100644 --- a/src/util/utility.jam +++ b/src/util/utility.jam @@ -3,6 +3,8 @@ # all copies. This software is provided "as is" without express or implied # warranty, and with no claim as to its suitability for any purpose. +import class : is-instance ; + rule ungrist ( names * ) { local result ; @@ -26,9 +28,89 @@ rule caller-file ( ) return $(bt[9]) ; } +# Returns the textual representation of argument. If it is a class +# instance, class its 'str' method. Otherwise, returns the argument. +rule str ( value ) +{ + if [ is-instance $(value) ] + { + return [ $(value).str ] ; + } + else + { + return $(value) ; + } +} + +# Tests if 'a' is equal to 'b'. If 'a' is a class instance, +# calls its 'equal' method. Uses ordinary jam's comparison otherwise. +rule equal ( a b ) +{ + if [ is-instance $(a) ] + { + return [ $(a).equal $(b) ] ; + } + else + { + if $(a) = $(b) + { + return true ; + } + } +} + +# Tests if 'a' is less than 'b'. If 'a' is a class instance, +# calls its 'less' method. Uses ordinary jam's comparison otherwise. +rule less ( a b ) +{ + if [ is-instance $(a) ] + { + return [ $(a).less $(b) ] ; + } + else + { + if $(a) < $(b) + { + return true ; + } + } +} + local rule __test__ ( ) { import assert ; + import class : class new ; assert.result foo bar : ungrist ; + + assert.result 123 : str 123 ; + + local rule test-class__ ( ) + { + rule str ( ) + { + return "str-test-class" ; + } + + rule less ( a ) + { + return "yes, of course!" ; + } + + rule equal ( a ) + { + return "not sure" ; + } + } + class test-class__ ; + + assert.result "str-test-class" : str [ new test-class__ ] ; + assert.true less 1 2 ; + assert.false less 2 1 ; + assert.result "yes, of course!" : less [ new test-class__ ] 1 ; + assert.true equal 1 1 ; + assert.false equal 1 2 ; + assert.result "not sure" : equal [ new test-class__ ] 1 ; } + +