OpenJDK / jdk / jdk
changeset 4502:18f387917b89
6903754: (bf) Improve floating-point buffer comparison
Summary: Describe the exact behavior of {Double,Float}Buffer.{equals,compareTo}; fix non-anti-symmetric behavior of compareTo
Reviewed-by: alanb
Contributed-by: jessewilson@google.com
author | martin |
---|---|
date | Tue, 08 Dec 2009 12:41:01 -0800 |
parents | 1f9c2400b8c5 |
children | e0f798017197 7758bdd54629 |
files | jdk/make/java/nio/genBuffer.sh jdk/src/share/classes/java/nio/X-Buffer.java.template jdk/test/java/nio/Buffer/Basic-X.java.template jdk/test/java/nio/Buffer/BasicByte.java jdk/test/java/nio/Buffer/BasicChar.java jdk/test/java/nio/Buffer/BasicDouble.java jdk/test/java/nio/Buffer/BasicFloat.java jdk/test/java/nio/Buffer/BasicInt.java jdk/test/java/nio/Buffer/BasicLong.java jdk/test/java/nio/Buffer/BasicShort.java jdk/test/java/nio/Buffer/genBasic.sh |
diffstat | 11 files changed, 631 insertions(+), 107 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/make/java/nio/genBuffer.sh Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/make/java/nio/genBuffer.sh Tue Dec 08 12:41:01 2009 -0800 @@ -44,6 +44,7 @@ case $type in char) fulltype=character;; + int) fulltype=integer;; *) fulltype=$type;; esac @@ -54,6 +55,11 @@ long | double) LBPV=3;; esac +case $type in + float|double) floatingPointOrIntegralType=floatingPointType;; + *) floatingPointOrIntegralType=integralType;; +esac + typesAndBits() { type="$1"; BO="$2" @@ -101,6 +107,7 @@ $SPP <$SRC >$DST \ -K$type \ + -K$floatingPointOrIntegralType \ -Dtype=$type \ -DType=$Type \ -Dfulltype=$fulltype \
--- a/jdk/src/share/classes/java/nio/X-Buffer.java.template Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/src/share/classes/java/nio/X-Buffer.java.template Tue Dec 08 12:41:01 2009 -0800 @@ -32,24 +32,24 @@ #end[char] /** - * $A$ $fulltype$ buffer. + * $A$ $type$ buffer. * * <p> This class defines {#if[byte]?six:four} categories of operations upon - * $fulltype$ buffers: + * $type$ buffers: * * <ul> * * <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and * {@link #put($type$) </code><i>put</i><code>} methods that read and write - * single $fulltype$s; </p></li> + * single $type$s; </p></li> * * <li><p> Relative {@link #get($type$[]) </code><i>bulk get</i><code>} - * methods that transfer contiguous sequences of $fulltype$s from this buffer + * methods that transfer contiguous sequences of $type$s from this buffer * into an array; {#if[!byte]?and}</p></li> * * <li><p> Relative {@link #put($type$[]) </code><i>bulk put</i><code>} - * methods that transfer contiguous sequences of $fulltype$s from $a$ - * $fulltype$ array{#if[char]?, a string,} or some other $fulltype$ + * methods that transfer contiguous sequences of $type$s from $a$ + * $type$ array{#if[char]?, a string,} or some other $type$ * buffer into this buffer;{#if[!byte]? and} </p></li> * #if[byte] @@ -67,22 +67,22 @@ * * <li><p> Methods for {@link #compact </code>compacting<code>}, {@link * #duplicate </code>duplicating<code>}, and {@link #slice - * </code>slicing<code>} $a$ $fulltype$ buffer. </p></li> + * </code>slicing<code>} $a$ $type$ buffer. </p></li> * * </ul> * - * <p> $Fulltype$ buffers can be created either by {@link #allocate + * <p> $Type$ buffers can be created either by {@link #allocate * </code><i>allocation</i><code>}, which allocates space for the buffer's * #if[byte] * * content, or by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an - * existing $fulltype$ array {#if[char]?or string} into a buffer. + * existing $type$ array {#if[char]?or string} into a buffer. * #else[byte] * * content, by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an existing - * $fulltype$ array {#if[char]?or string} into a buffer, or by creating a + * $type$ array {#if[char]?or string} into a buffer, or by creating a * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer. * #end[byte] @@ -189,12 +189,12 @@ * #if[!byte] * - * <p> Like a byte buffer, $a$ $fulltype$ buffer is either <a + * <p> Like a byte buffer, $a$ $type$ buffer is either <a * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A - * $fulltype$ buffer created via the <tt>wrap</tt> methods of this class will - * be non-direct. $A$ $fulltype$ buffer created as a view of a byte buffer will + * $type$ buffer created via the <tt>wrap</tt> methods of this class will + * be non-direct. $A$ $type$ buffer created as a view of a byte buffer will * be direct if, and only if, the byte buffer itself is direct. Whether or not - * $a$ $fulltype$ buffer is direct may be determined by invoking the {@link + * $a$ $type$ buffer is direct may be determined by invoking the {@link * #isDirect isDirect} method. </p> * #end[!byte] @@ -287,7 +287,7 @@ #if[byte] /** - * Allocates a new direct $fulltype$ buffer. + * Allocates a new direct $type$ buffer. * * <p> The new buffer's position will be zero, its limit will be its * capacity, its mark will be undefined, and each of its elements will be @@ -295,9 +295,9 @@ * {@link #hasArray </code>backing array<code>} is unspecified. * * @param capacity - * The new buffer's capacity, in $fulltype$s + * The new buffer's capacity, in $type$s * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer * * @throws IllegalArgumentException * If the <tt>capacity</tt> is a negative integer @@ -309,7 +309,7 @@ #end[byte] /** - * Allocates a new $fulltype$ buffer. + * Allocates a new $type$ buffer. * * <p> The new buffer's position will be zero, its limit will be its * capacity, its mark will be undefined, and each of its elements will be @@ -318,9 +318,9 @@ * offset<code>} will be zero. * * @param capacity - * The new buffer's capacity, in $fulltype$s + * The new buffer's capacity, in $type$s * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer * * @throws IllegalArgumentException * If the <tt>capacity</tt> is a negative integer @@ -332,9 +332,9 @@ } /** - * Wraps $a$ $fulltype$ array into a buffer. + * Wraps $a$ $type$ array into a buffer. * - * <p> The new buffer will be backed by the given $fulltype$ array; + * <p> The new buffer will be backed by the given $type$ array; * that is, modifications to the buffer will cause the array to be modified * and vice versa. The new buffer's capacity will be * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit @@ -356,7 +356,7 @@ * <tt>array.length - offset</tt>. * The new buffer's limit will be set to <tt>offset + length</tt>. * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer * * @throws IndexOutOfBoundsException * If the preconditions on the <tt>offset</tt> and <tt>length</tt> @@ -373,9 +373,9 @@ } /** - * Wraps $a$ $fulltype$ array into a buffer. + * Wraps $a$ $type$ array into a buffer. * - * <p> The new buffer will be backed by the given $fulltype$ array; + * <p> The new buffer will be backed by the given $type$ array; * that is, modifications to the buffer will cause the array to be modified * and vice versa. The new buffer's capacity and limit will be * <tt>array.length</tt>, its position will be zero, and its mark will be @@ -386,7 +386,7 @@ * @param array * The array that will back this buffer * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer */ public static $Type$Buffer wrap($type$[] array) { return wrap(array, 0, array.length); @@ -486,7 +486,7 @@ #end[char] /** - * Creates a new $fulltype$ buffer whose content is a shared subsequence of + * Creates a new $type$ buffer whose content is a shared subsequence of * this buffer's content. * * <p> The content of the new buffer will start at this buffer's current @@ -495,17 +495,17 @@ * values will be independent. * * <p> The new buffer's position will be zero, its capacity and its limit - * will be the number of $fulltype$s remaining in this buffer, and its mark + * will be the number of $type$s remaining in this buffer, and its mark * will be undefined. The new buffer will be direct if, and only if, this * buffer is direct, and it will be read-only if, and only if, this buffer * is read-only. </p> * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer */ public abstract $Type$Buffer slice(); /** - * Creates a new $fulltype$ buffer that shares this buffer's content. + * Creates a new $type$ buffer that shares this buffer's content. * * <p> The content of the new buffer will be that of this buffer. Changes * to this buffer's content will be visible in the new buffer, and vice @@ -517,12 +517,12 @@ * and only if, this buffer is direct, and it will be read-only if, and * only if, this buffer is read-only. </p> * - * @return The new $fulltype$ buffer + * @return The new $type$ buffer */ public abstract $Type$Buffer duplicate(); /** - * Creates a new, read-only $fulltype$ buffer that shares this buffer's + * Creates a new, read-only $type$ buffer that shares this buffer's * content. * * <p> The content of the new buffer will be that of this buffer. Changes @@ -537,7 +537,7 @@ * <p> If this buffer is itself read-only then this method behaves in * exactly the same way as the {@link #duplicate duplicate} method. </p> * - * @return The new, read-only $fulltype$ buffer + * @return The new, read-only $type$ buffer */ public abstract $Type$Buffer asReadOnlyBuffer(); @@ -545,10 +545,10 @@ // -- Singleton get/put methods -- /** - * Relative <i>get</i> method. Reads the $fulltype$ at this buffer's + * Relative <i>get</i> method. Reads the $type$ at this buffer's * current position, and then increments the position. </p> * - * @return The $fulltype$ at the buffer's current position + * @return The $type$ at the buffer's current position * * @throws BufferUnderflowException * If the buffer's current position is not smaller than its limit @@ -558,11 +558,11 @@ /** * Relative <i>put</i> method <i>(optional operation)</i>. * - * <p> Writes the given $fulltype$ into this buffer at the current + * <p> Writes the given $type$ into this buffer at the current * position, and then increments the position. </p> * * @param $x$ - * The $fulltype$ to be written + * The $type$ to be written * * @return This buffer * @@ -575,13 +575,13 @@ public abstract $Type$Buffer put($type$ $x$); /** - * Absolute <i>get</i> method. Reads the $fulltype$ at the given + * Absolute <i>get</i> method. Reads the $type$ at the given * index. </p> * * @param index - * The index from which the $fulltype$ will be read + * The index from which the $type$ will be read * - * @return The $fulltype$ at the given index + * @return The $type$ at the given index * * @throws IndexOutOfBoundsException * If <tt>index</tt> is negative @@ -592,14 +592,14 @@ /** * Absolute <i>put</i> method <i>(optional operation)</i>. * - * <p> Writes the given $fulltype$ into this buffer at the given + * <p> Writes the given $type$ into this buffer at the given * index. </p> * * @param index - * The index at which the $fulltype$ will be written + * The index at which the $type$ will be written * * @param $x$ - * The $fulltype$ value to be written + * The $type$ value to be written * * @return This buffer * @@ -618,14 +618,14 @@ /** * Relative bulk <i>get</i> method. * - * <p> This method transfers $fulltype$s from this buffer into the given - * destination array. If there are fewer $fulltype$s remaining in the + * <p> This method transfers $type$s from this buffer into the given + * destination array. If there are fewer $type$s remaining in the * buffer than are required to satisfy the request, that is, if * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no - * $fulltype$s are transferred and a {@link BufferUnderflowException} is + * $type$s are transferred and a {@link BufferUnderflowException} is * thrown. * - * <p> Otherwise, this method copies <tt>length</tt> $fulltype$s from this + * <p> Otherwise, this method copies <tt>length</tt> $type$s from this * buffer into the given array, starting at the current position of this * buffer and at the given offset in the array. The position of this * buffer is then incremented by <tt>length</tt>. @@ -638,26 +638,26 @@ * for (int i = off; i < off + len; i++) * dst[i] = src.get(); </pre> * - * except that it first checks that there are sufficient $fulltype$s in + * except that it first checks that there are sufficient $type$s in * this buffer and it is potentially much more efficient. </p> * * @param dst - * The array into which $fulltype$s are to be written + * The array into which $type$s are to be written * * @param offset - * The offset within the array of the first $fulltype$ to be + * The offset within the array of the first $type$ to be * written; must be non-negative and no larger than * <tt>dst.length</tt> * * @param length - * The maximum number of $fulltype$s to be written to the given + * The maximum number of $type$s to be written to the given * array; must be non-negative and no larger than * <tt>dst.length - offset</tt> * * @return This buffer * * @throws BufferUnderflowException - * If there are fewer than <tt>length</tt> $fulltype$s + * If there are fewer than <tt>length</tt> $type$s * remaining in this buffer * * @throws IndexOutOfBoundsException @@ -677,7 +677,7 @@ /** * Relative bulk <i>get</i> method. * - * <p> This method transfers $fulltype$s from this buffer into the given + * <p> This method transfers $type$s from this buffer into the given * destination array. An invocation of this method of the form * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation * @@ -687,7 +687,7 @@ * @return This buffer * * @throws BufferUnderflowException - * If there are fewer than <tt>length</tt> $fulltype$s + * If there are fewer than <tt>length</tt> $type$s * remaining in this buffer */ public $Type$Buffer get($type$[] dst) { @@ -700,15 +700,15 @@ /** * Relative bulk <i>put</i> method <i>(optional operation)</i>. * - * <p> This method transfers the $fulltype$s remaining in the given source - * buffer into this buffer. If there are more $fulltype$s remaining in the + * <p> This method transfers the $type$s remaining in the given source + * buffer into this buffer. If there are more $type$s remaining in the * source buffer than in this buffer, that is, if * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>, - * then no $fulltype$s are transferred and a {@link + * then no $type$s are transferred and a {@link * BufferOverflowException} is thrown. * * <p> Otherwise, this method copies - * <i>n</i> = <tt>src.remaining()</tt> $fulltype$s from the given + * <i>n</i> = <tt>src.remaining()</tt> $type$s from the given * buffer into this buffer, starting at each buffer's current position. * The positions of both buffers are then incremented by <i>n</i>. * @@ -723,14 +723,14 @@ * buffer and it is potentially much more efficient. </p> * * @param src - * The source buffer from which $fulltype$s are to be read; + * The source buffer from which $type$s are to be read; * must not be this buffer * * @return This buffer * * @throws BufferOverflowException * If there is insufficient space in this buffer - * for the remaining $fulltype$s in the source buffer + * for the remaining $type$s in the source buffer * * @throws IllegalArgumentException * If the source buffer is this buffer @@ -752,14 +752,14 @@ /** * Relative bulk <i>put</i> method <i>(optional operation)</i>. * - * <p> This method transfers $fulltype$s into this buffer from the given - * source array. If there are more $fulltype$s to be copied from the array + * <p> This method transfers $type$s into this buffer from the given + * source array. If there are more $type$s to be copied from the array * than remain in this buffer, that is, if * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no - * $fulltype$s are transferred and a {@link BufferOverflowException} is + * $type$s are transferred and a {@link BufferOverflowException} is * thrown. * - * <p> Otherwise, this method copies <tt>length</tt> $fulltype$s from the + * <p> Otherwise, this method copies <tt>length</tt> $type$s from the * given array into this buffer, starting at the given offset in the array * and at the current position of this buffer. The position of this buffer * is then incremented by <tt>length</tt>. @@ -776,14 +776,14 @@ * buffer and it is potentially much more efficient. </p> * * @param src - * The array from which $fulltype$s are to be read + * The array from which $type$s are to be read * * @param offset - * The offset within the array of the first $fulltype$ to be read; + * The offset within the array of the first $type$ to be read; * must be non-negative and no larger than <tt>array.length</tt> * * @param length - * The number of $fulltype$s to be read from the given array; + * The number of $type$s to be read from the given array; * must be non-negative and no larger than * <tt>array.length - offset</tt> * @@ -813,7 +813,7 @@ * Relative bulk <i>put</i> method <i>(optional operation)</i>. * * <p> This method transfers the entire content of the given source - * $fulltype$ array into this buffer. An invocation of this method of the + * $type$ array into this buffer. An invocation of this method of the * form <tt>dst.put(a)</tt> behaves in exactly the same way as the * invocation * @@ -837,15 +837,15 @@ /** * Relative bulk <i>put</i> method <i>(optional operation)</i>. * - * <p> This method transfers $fulltype$s from the given string into this - * buffer. If there are more $fulltype$s to be copied from the string than + * <p> This method transfers $type$s from the given string into this + * buffer. If there are more $type$s to be copied from the string than * remain in this buffer, that is, if * <tt>end - start</tt> <tt>></tt> <tt>remaining()</tt>, - * then no $fulltype$s are transferred and a {@link + * then no $type$s are transferred and a {@link * BufferOverflowException} is thrown. * * <p> Otherwise, this method copies - * <i>n</i> = <tt>end</tt> - <tt>start</tt> $fulltype$s + * <i>n</i> = <tt>end</tt> - <tt>start</tt> $type$s * from the given string into this buffer, starting at the given * <tt>start</tt> index and at the current position of this buffer. The * position of this buffer is then incremented by <i>n</i>. @@ -862,15 +862,15 @@ * buffer and it is potentially much more efficient. </p> * * @param src - * The string from which $fulltype$s are to be read + * The string from which $type$s are to be read * * @param start - * The offset within the string of the first $fulltype$ to be read; + * The offset within the string of the first $type$ to be read; * must be non-negative and no larger than * <tt>string.length()</tt> * * @param end - * The offset within the string of the last $fulltype$ to be read, + * The offset within the string of the last $type$ to be read, * plus one; must be non-negative and no larger than * <tt>string.length()</tt> * @@ -921,7 +921,7 @@ // -- Other stuff -- /** - * Tells whether or not this buffer is backed by an accessible $fulltype$ + * Tells whether or not this buffer is backed by an accessible $type$ * array. * * <p> If this method returns <tt>true</tt> then the {@link #array() array} @@ -936,7 +936,7 @@ } /** - * Returns the $fulltype$ array that backs this + * Returns the $type$ array that backs this * buffer <i>(optional operation)</i>. * * <p> Modifications to this buffer's content will cause the returned @@ -993,17 +993,17 @@ /** * Compacts this buffer <i>(optional operation)</i>. * - * <p> The $fulltype$s between the buffer's current position and its limit, + * <p> The $type$s between the buffer's current position and its limit, * if any, are copied to the beginning of the buffer. That is, the - * $fulltype$ at index <i>p</i> = <tt>position()</tt> is copied - * to index zero, the $fulltype$ at index <i>p</i> + 1 is copied - * to index one, and so forth until the $fulltype$ at index + * $type$ at index <i>p</i> = <tt>position()</tt> is copied + * to index zero, the $type$ at index <i>p</i> + 1 is copied + * to index one, and so forth until the $type$ at index * <tt>limit()</tt> - 1 is copied to index * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>. * The buffer's position is then set to <i>n+1</i> and its limit is set to * its capacity. The mark, if defined, is discarded. * - * <p> The buffer's position is set to the number of $fulltype$s copied, + * <p> The buffer's position is set to the number of $type$s copied, * rather than to zero, so that an invocation of this method can be * followed immediately by an invocation of another relative <i>put</i> * method. </p> @@ -1032,7 +1032,7 @@ public abstract $Type$Buffer compact(); /** - * Tells whether or not this $fulltype$ buffer is direct. </p> + * Tells whether or not this $type$ buffer is direct. </p> * * @return <tt>true</tt> if, and only if, this buffer is direct */ @@ -1098,6 +1098,13 @@ * * <li><p> The two sequences of remaining elements, considered * independently of their starting positions, are pointwise equal. +#if[floatingPointType] + * This method considers two $type$ elements {@code a} and {@code b} + * to be equal if + * {@code (a == b) || ($Fulltype$.isNaN(a) && $Fulltype$.isNaN(b))}. + * The values {@code -0.0} and {@code +0.0} are considered to be + * equal, unlike {@link $Fulltype$#equals(Object)}. +#end[floatingPointType] * </p></li> * * </ol> @@ -1118,24 +1125,37 @@ if (this.remaining() != that.remaining()) return false; int p = this.position(); - for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) { - $type$ v1 = this.get(i); - $type$ v2 = that.get(j); - if (v1 != v2) { - if ((v1 != v1) && (v2 != v2)) // For float and double - continue; + for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) + if (!equals(this.get(i), that.get(j))) return false; - } - } return true; } + private static boolean equals($type$ x, $type$ y) { +#if[floatingPointType] + return (x == y) || ($Fulltype$.isNaN(x) && $Fulltype$.isNaN(y)); +#else[floatingPointType] + return x == y; +#end[floatingPointType] + } + /** * Compares this buffer to another. * * <p> Two $type$ buffers are compared by comparing their sequences of * remaining elements lexicographically, without regard to the starting * position of each sequence within its corresponding buffer. +#if[floatingPointType] + * Pairs of {@code $type$} elements are compared as if by invoking + * {@link $Fulltype$#compare($type$,$type$)}, except that + * {@code -0.0} and {@code 0.0} are considered to be equal. + * {@code $Fulltype$.NaN} is considered by this method to be equal + * to itself and greater than all other {@code $type$} values + * (including {@code $Fulltype$.POSITIVE_INFINITY}). +#else[floatingPointType] + * Pairs of {@code $type$} elements are compared as if by invoking + * {@link $Fulltype$#compare($type$,$type$)}. +#end[floatingPointType] * * <p> A $type$ buffer is not comparable to any other type of object. * @@ -1145,20 +1165,23 @@ public int compareTo($Type$Buffer that) { int n = this.position() + Math.min(this.remaining(), that.remaining()); for (int i = this.position(), j = that.position(); i < n; i++, j++) { - $type$ v1 = this.get(i); - $type$ v2 = that.get(j); - if (v1 == v2) - continue; - if ((v1 != v1) && (v2 != v2)) // For float and double - continue; - if (v1 < v2) - return -1; - return +1; + int cmp = compare(this.get(i), that.get(j)); + if (cmp != 0) + return cmp; } return this.remaining() - that.remaining(); } - + private static int compare($type$ x, $type$ y) { +#if[floatingPointType] + return ((x < y) ? -1 : + (x > y) ? +1 : + (x == y) ? 0 : + $Fulltype$.isNaN(x) ? ($Fulltype$.isNaN(y) ? 0 : +1) : -1); +#else[floatingPointType] + return $Fulltype$.compare(x, y); +#end[floatingPointType] + } // -- Other char stuff -- @@ -1326,7 +1349,7 @@ } /** - * Appends the specified $fulltype$ to this + * Appends the specified $type$ to this * buffer <i>(optional operation)</i>. * * <p> An invocation of this method of the form <tt>dst.append($x$)</tt> @@ -1336,7 +1359,7 @@ * dst.put($x$) </pre> * * @param $x$ - * The 16-bit $fulltype$ to append + * The 16-bit $type$ to append * * @return This buffer * @@ -1362,10 +1385,10 @@ /** * Retrieves this buffer's byte order. * - * <p> The byte order of $a$ $fulltype$ buffer created by allocation or by + * <p> The byte order of $a$ $type$ buffer created by allocation or by * wrapping an existing <tt>$type$</tt> array is the {@link * ByteOrder#nativeOrder </code>native order<code>} of the underlying - * hardware. The byte order of $a$ $fulltype$ buffer created as a <a + * hardware. The byte order of $a$ $type$ buffer created as a <a * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the * byte buffer at the moment that the view is created. </p> *
--- a/jdk/test/java/nio/Buffer/Basic-X.java.template Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/test/java/nio/Buffer/Basic-X.java.template Tue Dec 08 12:41:01 2009 -0800 @@ -38,6 +38,26 @@ extends Basic { + private static final $type$[] VALUES = { + $Fulltype$.MIN_VALUE, + ($type$) -1, + ($type$) 0, + ($type$) 1, + $Fulltype$.MAX_VALUE, +#if[float] + $Fulltype$.NEGATIVE_INFINITY, + $Fulltype$.POSITIVE_INFINITY, + $Fulltype$.NaN, + ($type$) -0.0, +#end[float] +#if[double] + $Fulltype$.NEGATIVE_INFINITY, + $Fulltype$.POSITIVE_INFINITY, + $Fulltype$.NaN, + ($type$) -0.0, +#end[double] + }; + private static void relGet($Type$Buffer b) { int n = b.capacity(); $type$ v; @@ -309,6 +329,12 @@ #end[byte] + private static void fail(String problem, + $Type$Buffer xb, $Type$Buffer yb, + $type$ x, $type$ y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for ($type$ x : VALUES) { + $Type$Buffer xb = $Type$Buffer.wrap(new $type$[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for ($type$ y : VALUES) { + $Type$Buffer yb = $Type$Buffer.wrap(new $type$[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != $Fulltype$.compare(x, y)) { +#if[float] + if (x == 0.0 && y == 0.0) continue; +#end[float] +#if[double] + if (x == 0.0 && y == 0.0) continue; +#end[double] + fail("Incorrect results for $Type$Buffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for $Type$Buffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicByte.java Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/test/java/nio/Buffer/BasicByte.java Tue Dec 08 12:41:01 2009 -0800 @@ -38,6 +38,26 @@ extends Basic { + private static final byte[] VALUES = { + Byte.MIN_VALUE, + (byte) -1, + (byte) 0, + (byte) 1, + Byte.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(ByteBuffer b) { int n = b.capacity(); byte v; @@ -309,6 +329,12 @@ + private static void fail(String problem, + ByteBuffer xb, ByteBuffer yb, + byte x, byte y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (byte x : VALUES) { + ByteBuffer xb = ByteBuffer.wrap(new byte[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (byte y : VALUES) { + ByteBuffer yb = ByteBuffer.wrap(new byte[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Byte.compare(x, y)) { + + + + + + + fail("Incorrect results for ByteBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for ByteBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicChar.java Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/test/java/nio/Buffer/BasicChar.java Tue Dec 08 12:41:01 2009 -0800 @@ -38,6 +38,26 @@ extends Basic { + private static final char[] VALUES = { + Character.MIN_VALUE, + (char) -1, + (char) 0, + (char) 1, + Character.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(CharBuffer b) { int n = b.capacity(); char v; @@ -309,6 +329,12 @@ + private static void fail(String problem, + CharBuffer xb, CharBuffer yb, + char x, char y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (char x : VALUES) { + CharBuffer xb = CharBuffer.wrap(new char[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (char y : VALUES) { + CharBuffer yb = CharBuffer.wrap(new char[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Character.compare(x, y)) { + + + + + + + fail("Incorrect results for CharBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for CharBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicDouble.java Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/test/java/nio/Buffer/BasicDouble.java Tue Dec 08 12:41:01 2009 -0800 @@ -38,6 +38,26 @@ extends Basic { + private static final double[] VALUES = { + Double.MIN_VALUE, + (double) -1, + (double) 0, + (double) 1, + Double.MAX_VALUE, + + + + + + + + Double.NEGATIVE_INFINITY, + Double.POSITIVE_INFINITY, + Double.NaN, + (double) -0.0, + + }; + private static void relGet(DoubleBuffer b) { int n = b.capacity(); double v; @@ -309,6 +329,12 @@ + private static void fail(String problem, + DoubleBuffer xb, DoubleBuffer yb, + double x, double y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (double x : VALUES) { + DoubleBuffer xb = DoubleBuffer.wrap(new double[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (double y : VALUES) { + DoubleBuffer yb = DoubleBuffer.wrap(new double[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Double.compare(x, y)) { + + + + + if (x == 0.0 && y == 0.0) continue; + + fail("Incorrect results for DoubleBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for DoubleBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicFloat.java Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/test/java/nio/Buffer/BasicFloat.java Tue Dec 08 12:41:01 2009 -0800 @@ -38,6 +38,26 @@ extends Basic { + private static final float[] VALUES = { + Float.MIN_VALUE, + (float) -1, + (float) 0, + (float) 1, + Float.MAX_VALUE, + + Float.NEGATIVE_INFINITY, + Float.POSITIVE_INFINITY, + Float.NaN, + (float) -0.0, + + + + + + + + }; + private static void relGet(FloatBuffer b) { int n = b.capacity(); float v; @@ -309,6 +329,12 @@ + private static void fail(String problem, + FloatBuffer xb, FloatBuffer yb, + float x, float y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (float x : VALUES) { + FloatBuffer xb = FloatBuffer.wrap(new float[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (float y : VALUES) { + FloatBuffer yb = FloatBuffer.wrap(new float[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Float.compare(x, y)) { + + if (x == 0.0 && y == 0.0) continue; + + + + + fail("Incorrect results for FloatBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for FloatBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicInt.java Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/test/java/nio/Buffer/BasicInt.java Tue Dec 08 12:41:01 2009 -0800 @@ -38,6 +38,26 @@ extends Basic { + private static final int[] VALUES = { + Integer.MIN_VALUE, + (int) -1, + (int) 0, + (int) 1, + Integer.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(IntBuffer b) { int n = b.capacity(); int v; @@ -309,6 +329,12 @@ + private static void fail(String problem, + IntBuffer xb, IntBuffer yb, + int x, int y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (int x : VALUES) { + IntBuffer xb = IntBuffer.wrap(new int[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (int y : VALUES) { + IntBuffer yb = IntBuffer.wrap(new int[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Integer.compare(x, y)) { + + + + + + + fail("Incorrect results for IntBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for IntBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicLong.java Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/test/java/nio/Buffer/BasicLong.java Tue Dec 08 12:41:01 2009 -0800 @@ -38,6 +38,26 @@ extends Basic { + private static final long[] VALUES = { + Long.MIN_VALUE, + (long) -1, + (long) 0, + (long) 1, + Long.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(LongBuffer b) { int n = b.capacity(); long v; @@ -309,6 +329,12 @@ + private static void fail(String problem, + LongBuffer xb, LongBuffer yb, + long x, long y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (long x : VALUES) { + LongBuffer xb = LongBuffer.wrap(new long[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (long y : VALUES) { + LongBuffer yb = LongBuffer.wrap(new long[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Long.compare(x, y)) { + + + + + + + fail("Incorrect results for LongBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for LongBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b);
--- a/jdk/test/java/nio/Buffer/BasicShort.java Tue Dec 08 12:40:30 2009 +0000 +++ b/jdk/test/java/nio/Buffer/BasicShort.java Tue Dec 08 12:41:01 2009 -0800 @@ -38,6 +38,26 @@ extends Basic { + private static final short[] VALUES = { + Short.MIN_VALUE, + (short) -1, + (short) 0, + (short) 1, + Short.MAX_VALUE, + + + + + + + + + + + + + }; + private static void relGet(ShortBuffer b) { int n = b.capacity(); short v; @@ -309,6 +329,12 @@ + private static void fail(String problem, + ShortBuffer xb, ShortBuffer yb, + short x, short y) { + fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); + } + private static void tryCatch(Buffer b, Class ex, Runnable thunk) { boolean caught = false; try { @@ -522,6 +548,42 @@ if (b.compareTo(b2) <= 0) fail("Comparison to lesser buffer <= 0", b, b2); + // Check equals and compareTo with interesting values + for (short x : VALUES) { + ShortBuffer xb = ShortBuffer.wrap(new short[] { x }); + if (xb.compareTo(xb) != 0) { + fail("compareTo not reflexive", xb, xb, x, x); + } + if (! xb.equals(xb)) { + fail("equals not reflexive", xb, xb, x, x); + } + for (short y : VALUES) { + ShortBuffer yb = ShortBuffer.wrap(new short[] { y }); + if (xb.compareTo(yb) != - yb.compareTo(xb)) { + fail("compareTo not anti-symmetric", + xb, yb, x, y); + } + if ((xb.compareTo(yb) == 0) != xb.equals(yb)) { + fail("compareTo inconsistent with equals", + xb, yb, x, y); + } + if (xb.compareTo(yb) != Short.compare(x, y)) { + + + + + + + fail("Incorrect results for ShortBuffer.compareTo", + xb, yb, x, y); + } + if (xb.equals(yb) != ((x == y) || ((x != x) && (y != y)))) { + fail("Incorrect results for ShortBuffer.equals", + xb, yb, x, y); + } + } + } + // Sub, dup relPut(b);