Magnitude.st
author Claus Gittinger <cg@exept.de>
Wed, 19 Jun 2002 14:08:24 +0200
changeset 6582 a9e74bc8c901
parent 6073 a2b1c61dae18
child 8178 a7ee1b47775b
permissions -rw-r--r--
ansi error: to:by:do: with 0 increment.

"
 COPYRIGHT (c) 1988 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

"{ Package: 'stx:libbasic' }"

Object subclass:#Magnitude
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Magnitude-General'
!

!Magnitude class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1988 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    This is an abstract class definining common methods for
    Objects which can be compared by a kind of greater realation.

    [author:]
        Claus Gittinger
"
! !

!Magnitude methodsFor:'comparing'!

< aMagnitude
    "Compare the receiver with the argument and return true if the
     receiver is less than the argument. Otherwise return false."

    ^ (aMagnitude > self)
!

<= aMagnitude
    "Compare the receiver with the argument and return true if the
     receiver is less than or equal to the argument. Otherwise return false."

    ^ (self > aMagnitude) not
!

= aMagnitude
    "Compare the receiver with the argument and return true if the
     receiver is equal to the argument. Otherwise return false."

    ^ self subclassResponsibility
!

> aMagnitude
    "Compare the receiver with the argument and return true if the
     receiver is greater than the argument. Otherwise return false."

    ^ self subclassResponsibility
!

>= aMagnitude
    "Compare the receiver with the argument and return true if the
     receiver is greater than or equal to the argument.
     Otherwise return false."

    ^ (aMagnitude > self) not
!

clampBetween:min and:max
    "return the receiver if its between min .. max,
     or min if its less than min, or max of its greater than max.
     This is only a lazy-typers helper for: ((something min:max) max:min)"

    (self > max) ifTrue:[^ max].
    (self < min) ifTrue:[^ min].
    ^ self

    "
     1 clampBetween:2 and:5  
     3 clampBetween:2 and:5  
     6 clampBetween:2 and:5  
    "

    "Modified: 19.4.1996 / 14:58:12 / cg"
!

max:aMagnitude
    "return the receiver or the argument, whichever has greater magnitude"

    (self > aMagnitude) ifTrue:[^ self].
    ^ aMagnitude

    "
     1 max: 2
     1 max: 2.0
     2.0 max: 1.0
     2.0 max: 2
    "
!

min:aMagnitude
    "return the receiver or the argument, whichever has lesser magnitude"

    (self < aMagnitude) ifTrue:[^ self].
    ^ aMagnitude

    "
     1 min: 2
     1 min: 2.0
     2.0 min: 1.0
     2.0 min: 2
    "
! !

!Magnitude methodsFor:'iteration'!

downTo:stop do:aBlock
    "For each element of the interval from the receiver down to the argument stop,
     evaluate aBlock, passing the number as argument."

    ^ self to:stop by:-1 do:aBlock

    "
     10 downTo:1 do:[:i | Transcript showCR:i].
    "
!

to:stop by:incr do:aBlock
    "For each element of the interval from the receiver up to the argument stop, incrementing
     by step, evaluate aBlock passing the element as argument."

    |tmp|

    tmp := self.
    (incr >= 0) ifTrue:[
        [tmp <= stop] whileTrue:[
            aBlock value:tmp.
            tmp := tmp+incr
        ]
    ] ifFalse:[
        [tmp >= stop] whileTrue:[
            aBlock value:tmp.
            tmp := tmp+incr
        ]
    ]

    "
     1 to:10 do:[:i | Transcript showCR:i].
     1 to:10 by:2 do:[:i | Transcript showCR:i].
     10 to:1 by:-1 do:[:i | Transcript showCR:i].
    "
!

to:stop by:incr doWithBreak:aBlock
    "For each element of the interval from the receiver up to the argument stop, incrementing
     by step, evaluate aBlock passing the element as argument.
     Pass a break argument, to allow for premature exit of the loop."

    |tmp break|

    break := [^ self].
    tmp := self.
    (incr > 0) ifTrue:[
	[tmp <= stop] whileTrue:[
	    aBlock value:tmp value:break.
	    tmp := tmp+incr
	]
    ] ifFalse:[
	[tmp >= stop] whileTrue:[
	    aBlock value:tmp value:break.
	    tmp := tmp+incr
	]
    ]

    "
     1 to:100 by:5 doWithBreak:[:index :break |
	Transcript showCR:index printString.
	index > 50 ifTrue:[
	    break value
	].
     ]
    "
!

to:stop by:incr doWithExit:aBlock
    "For each element of the interval from the receiver up to the argument stop, incrementing
     by step, evaluate aBlock passing the element as argument.
     Pass a break argument, to allow for premature exit of the loop."

    |tmp exit|

    exit := [:exitValue | ^ exitValue].
    tmp := self.
    (incr > 0) ifTrue:[
        [tmp <= stop] whileTrue:[
            aBlock value:tmp value:exit.
            tmp := tmp+incr
        ]
    ] ifFalse:[
        [tmp >= stop] whileTrue:[
            aBlock value:tmp value:exit.
            tmp := tmp+incr
        ]
    ]

    "
     1 to:100 by:5 doWithExit:[:index :exit |
        Transcript showCR:index printString.
        index > 50 ifTrue:[
            exit value:nil
        ].
     ]
    "
!

to:stop do:aBlock
    "For each element of the interval from the receiver up to the argument stop,
     evaluate aBlock, passing the number as argument."

    |tmp|

    tmp := self.
    [tmp <= stop] whileTrue:[
        aBlock value:tmp.
        tmp := tmp+1
    ]

    "
     1 to:10 do:[:i | Transcript showCR:i].
     1 to:10 by:2 do:[:i | Transcript showCR:i].
     10 to:1 by:-1 do:[:i | Transcript showCR:i].
    "
!

to:stop doWithBreak:aBlock
    "For each element of the interval from the receiver up to the argument stop,
     evaluate aBlock, passing the number as argument.
     Pass a break argument, to allow for premature exit of the loop."

    |tmp break|

    break := [^ self].
    tmp := self.
    [tmp <= stop] whileTrue:[
	aBlock value:tmp value:break.
	tmp := tmp+1
    ]

    "
     1 to:10 doWithBreak:[:index :break |
	Transcript showCR:index printString.
	index > 5 ifTrue:[
	    break value
	].
     ]
    "
!

to:stop doWithExit:aBlock
    "For each element of the interval from the receiver up to the argument stop,
     evaluate aBlock, passing the number as argument.
     An exitBlock is passed as second argument, which allows for the loop to be terminated early."

    |exit tmp|

    exit := [:exitValue | ^exitValue].
    tmp := self.
    [tmp <= stop] whileTrue:[
        aBlock value:tmp value:exit.
        tmp := tmp+1
    ]

    "
     1 to:10 doWithExit:[:index :exit |
        index == 5 ifTrue:[
            exit value:nil
        ].
        Transcript showCR:index.
     ].
    "
! !

!Magnitude methodsFor:'testing'!

between:min and:max
    "return whether the receiver is less than or equal to the argument max
     and greater than or equal to the argument min."

    (self < min) ifTrue:[^ false].
    (self > max) ifTrue:[^ false].
    ^ true

    "
     1.2 between:1 and:2
     (3/2) between:1 and:2
     (3/2) between:0 and:1
    "
!

in:anInterval
    "return whether the receiver is within the interval bounds"

    (self < anInterval start) ifTrue:[^ false].
    (self > anInterval stop) ifTrue:[^ false].
    ^ true

    "
     1.2 in:(1 to: 2)
     (3/2) in:(1 to: 2)
     (3/2) in:(0 to: 1)
    "
! !

!Magnitude class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libbasic/Magnitude.st,v 1.17 2002-06-19 12:08:24 cg Exp $'
! !