diff --git a/lib/modules/Val.pmod/Range.pike b/lib/modules/Val.pmod/Range.pike index 9206a5dc31b1766c929f9470bad9e4a7b13ccb27..25e01e22d671698bf218321d6670b7b18ac36cda 100644 --- a/lib/modules/Val.pmod/Range.pike +++ b/lib/modules/Val.pmod/Range.pike @@ -2,7 +2,8 @@ #pragma strict_types //! Generic lightweight range type. Supports any values for lower -//! and upper boundaries that implement the @expr{`<@} lfun. +//! and upper boundaries that implement @[lfun::`<()] and @[lfun::`-@()], +//! and preferrably also cast to @expr{int@} and @expr{string@}. //! @note //! Can only contain a single contiguous range. //! @note @@ -11,17 +12,19 @@ constant is_range = 1; +protected typedef int|float|string|object value_type; + //! The lower inclusive boundary. -mixed from; +value_type from; //! The upper exclusive boundary. -mixed till; +value_type till; -array(mixed) _encode() { +array(value_type) _encode() { return ({from, till}); } -void _decode(array(mixed) x) { +void _decode(array(value_type) x) { from = x[0]; till = x[1]; } @@ -41,7 +44,7 @@ protected int __hash() { //! by filling in @expr{Math.inf@}. //! @seealso //! @[Math.inf] -protected variant void create(mixed from, mixed till) { +protected variant void create(value_type from, value_type till) { if (from >= till) { from = Math.inf; till = -Math.inf; @@ -57,9 +60,9 @@ protected variant void create() { } //! Difference -protected mixed `-(mixed that) { - this_program n = this_program(max(from, ([object]that)->from), - min(till, ([object]that)->till)); +protected this_program `-(this_program that) { + this_program n = this_program(max(from, that->from), + min(till, that->till)); if (!n) return this; if (till == n->till) { @@ -76,38 +79,41 @@ protected mixed `-(mixed that) { } //! Union -protected mixed `+(mixed that) { +protected this_program `+(this_program that) { if (from != ([object]that)->till && ([object]that)->from != till && !(this & ([object]that))) error("Result of range union would not be contiguous\n"); - return this_program(min(from, ([object]that)->from), - max(till, ([object]that)->till)); + return this_program(min(from, that->from), + max(till, that->till)); } //! Intersection -protected mixed `*(mixed that) { - return this_program(max(from, ([object]that)->from), - min(till, ([object]that)->till)); +protected this_program `*(this_program that) { + return this_program(max(from, that->from), + min(till, that->till)); } //! Overlap: have points in common. -protected int(0..1) `&(mixed that) { - return till > ([object]that)->from && ([object]that)->till > from; +protected int(0..1) `&(this_program that) { + return till > that->from && that->till > from; } //! Is adjacent to -protected int(0..1) `|(mixed that) { - return till == ([object]that)->from || from == ([object]that)->till; +//! +//! @fixme +//! This does NOT seem like a good operator for this operation. +protected int(0..1) `|(this_program that) { + return till == that->from || from == that->till; } //! Strictly left of -protected int(0..1) `<<(mixed that) { - return till <= ([object]that)->from; +protected int(0..1) `<<(this_program that) { + return till <= that->from; } //! Strictly right of -protected int(0..1) `>>(mixed that) { - return from >= ([object]that)->till; +protected int(0..1) `>>(this_program that) { + return from >= that->till; } protected int(0..1) `<(mixed that) { @@ -122,12 +128,18 @@ protected int(0..1) `==(mixed that) { //! @returns //! True if range is empty. +//! +//! @seealso +//! @[isempty()] protected inline int(0..1) `!() { return from >= till; } //! @returns //! True if range is empty. +//! +//! @seealso +//! @[`!()] inline int(0..1) isempty() { return !this; } @@ -135,15 +147,18 @@ inline int(0..1) isempty() { //! @param other //! Extends the current range to the smallest range which encompasses //! itself and all other given ranges. +//! +//! @fixme +//! This seems like the operation that @expr{`|()@} ought to do. this_program merge(this_program ... other) { - from = min(from, @other->from); - till = max(till, @other->till); + from = [object(value_type)]min(from, @other->from); + till = [object(value_type)]max(till, @other->till); return this; } //! @returns //! True if this range fully contains another range or element. -int(0..1) contains(mixed other) { +int(0..1) contains(object(this_program)|value_type other) { return objectp(other) && ([object]other)->is_range ? from <= ([object]other)->from && ([object]other)->till <= till : from <= other && other < till;