diff --git a/src/main/java/java/io/Closeable.java b/src/main/java/java/io/Closeable.java new file mode 100644 index 0000000..b4a1c81 --- /dev/null +++ b/src/main/java/java/io/Closeable.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +import java.io.IOException; + +/** + * A {@code Closeable} is a source or destination of data that can be closed. + * The close method is invoked to release resources that the object is + * holding (such as open files). + * + * @since 1.5 + */ +public interface Closeable extends AutoCloseable { + + /** + * Closes this stream and releases any system resources associated + * with it. If the stream is already closed then invoking this + * method has no effect. + * + *

As noted in {@link AutoCloseable#close()}, cases where the + * close may fail require careful attention. It is strongly advised + * to relinquish the underlying resources and to internally + * mark the {@code Closeable} as closed, prior to throwing + * the {@code IOException}. + * + * @throws IOException if an I/O error occurs + */ + public void close() throws IOException; +} diff --git a/src/main/java/java/io/Flushable.java b/src/main/java/java/io/Flushable.java new file mode 100644 index 0000000..fe90fbd --- /dev/null +++ b/src/main/java/java/io/Flushable.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +import java.io.IOException; + +/** + * A Flushable is a destination of data that can be flushed. The + * flush method is invoked to write any buffered output to the underlying + * stream. + * + * @since 1.5 + */ +public interface Flushable { + + /** + * Flushes this stream by writing any buffered output to the underlying + * stream. + * + * @throws IOException If an I/O error occurs + */ + void flush() throws IOException; +} diff --git a/src/main/java/java/io/PrintWriter.java b/src/main/java/java/io/PrintWriter.java new file mode 100644 index 0000000..d269432 --- /dev/null +++ b/src/main/java/java/io/PrintWriter.java @@ -0,0 +1,1237 @@ +/* + * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +import org.cprover.CProver; + +import java.util.Objects; +import java.util.Formatter; +import java.util.Locale; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; + +/** + * Prints formatted representations of objects to a text-output stream. This + * class implements all of the print methods found in {@link + * PrintStream}. It does not contain methods for writing raw bytes, for which + * a program should use unencoded byte streams. + * + *

Unlike the {@link PrintStream} class, if automatic flushing is enabled + * it will be done only when one of the println, printf, or + * format methods is invoked, rather than whenever a newline character + * happens to be output. These methods use the platform's own notion of line + * separator rather than the newline character. + * + *

Methods in this class never throw I/O exceptions, although some of its + * constructors may. The client may inquire as to whether any errors have + * occurred by invoking {@link #checkError checkError()}. + * + * @author Frank Yellin + * @author Mark Reinhold + * @since JDK1.1 + * + * @diffblue.untested + * @diffblue.mock + * This model was automatically generated by the Emptier tool. + */ + +public class PrintWriter extends Writer { + + /** + * The underlying character-output stream of this + * PrintWriter. + * + * @since 1.2 + */ + protected Writer out; + + // DIFFBLUE MODEL LIBRARY - not used in model + // private final boolean autoFlush; + // DIFFBLUE MODEL LIBRARY - not used in model + // private boolean trouble = false; + // DIFFBLUE MODEL LIBRARY - not used in model + // private Formatter formatter; + // DIFFBLUE MODEL LIBRARY - not used in model + // private PrintStream psOut = null; + + /** + * Line separator string. This is the value of the line.separator + * property at the moment that the stream was created. + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private final String lineSeparator; + + /** + * Returns a charset object for the given charset name. + * @throws NullPointerException is csn is null + * @throws UnsupportedEncodingException if the charset is not supported + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static Charset toCharset(String csn) + // throws UnsupportedEncodingException + // { + // Objects.requireNonNull(csn, "charsetName"); + // try { + // return Charset.forName(csn); + // } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) { + // // UnsupportedEncodingException should be thrown + // throw new UnsupportedEncodingException(csn); + // } + // } + + /** + * Creates a new PrintWriter, without automatic line flushing. + * + * @param out A character-output stream + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter (Writer out) { + this(out, false); + } + + /** + * Creates a new PrintWriter. + * + * @param out A character-output stream + * @param autoFlush A boolean; if true, the println, + * printf, or format methods will + * flush the output buffer + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter(Writer out, + boolean autoFlush) { + super(out); + // this.out = out; + // this.autoFlush = autoFlush; + // lineSeparator = java.security.AccessController.doPrivileged( + // new sun.security.action.GetPropertyAction("line.separator")); + } + + /** + * Creates a new PrintWriter, without automatic line flushing, from an + * existing OutputStream. This convenience constructor creates the + * necessary intermediate OutputStreamWriter, which will convert characters + * into bytes using the default character encoding. + * + * @param out An output stream + * + * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream) + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter(OutputStream out) { + // this(out, false); + } + + /** + * Creates a new PrintWriter from an existing OutputStream. This + * convenience constructor creates the necessary intermediate + * OutputStreamWriter, which will convert characters into bytes using the + * default character encoding. + * + * @param out An output stream + * @param autoFlush A boolean; if true, the println, + * printf, or format methods will + * flush the output buffer + * + * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream) + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter(OutputStream out, boolean autoFlush) { + // this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush); + + // // save print stream for error propagation + // if (out instanceof java.io.PrintStream) { + // psOut = (PrintStream) out; + // } + } + + /** + * Creates a new PrintWriter, without automatic line flushing, with the + * specified file name. This convenience constructor creates the necessary + * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter}, + * which will encode characters using the {@linkplain + * java.nio.charset.Charset#defaultCharset() default charset} for this + * instance of the Java virtual machine. + * + * @param fileName + * The name of the file to use as the destination of this writer. + * If the file exists then it will be truncated to zero size; + * otherwise, a new file will be created. The output will be + * written to the file and is buffered. + * + * @throws FileNotFoundException + * If the given string does not denote an existing, writable + * regular file and a new regular file of that name cannot be + * created, or if some other error occurs while opening or + * creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(fileName)} denies write + * access to the file + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter(String fileName) throws FileNotFoundException { + // this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))), + // false); + } + + /* Private constructor */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private PrintWriter(Charset charset, File file) + // throws FileNotFoundException + // { + // this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)), + // false); + // } + + /** + * Creates a new PrintWriter, without automatic line flushing, with the + * specified file name and charset. This convenience constructor creates + * the necessary intermediate {@link java.io.OutputStreamWriter + * OutputStreamWriter}, which will encode characters using the provided + * charset. + * + * @param fileName + * The name of the file to use as the destination of this writer. + * If the file exists then it will be truncated to zero size; + * otherwise, a new file will be created. The output will be + * written to the file and is buffered. + * + * @param csn + * The name of a supported {@linkplain java.nio.charset.Charset + * charset} + * + * @throws FileNotFoundException + * If the given string does not denote an existing, writable + * regular file and a new regular file of that name cannot be + * created, or if some other error occurs while opening or + * creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(fileName)} denies write + * access to the file + * + * @throws UnsupportedEncodingException + * If the named charset is not supported + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter(String fileName, String csn) + throws FileNotFoundException, UnsupportedEncodingException + { + // this(toCharset(csn), new File(fileName)); + } + + /** + * Creates a new PrintWriter, without automatic line flushing, with the + * specified file. This convenience constructor creates the necessary + * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter}, + * which will encode characters using the {@linkplain + * java.nio.charset.Charset#defaultCharset() default charset} for this + * instance of the Java virtual machine. + * + * @param file + * The file to use as the destination of this writer. If the file + * exists then it will be truncated to zero size; otherwise, a new + * file will be created. The output will be written to the file + * and is buffered. + * + * @throws FileNotFoundException + * If the given file object does not denote an existing, writable + * regular file and a new regular file of that name cannot be + * created, or if some other error occurs while opening or + * creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(file.getPath())} + * denies write access to the file + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter(File file) throws FileNotFoundException { + // this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))), + // false); + } + + /** + * Creates a new PrintWriter, without automatic line flushing, with the + * specified file and charset. This convenience constructor creates the + * necessary intermediate {@link java.io.OutputStreamWriter + * OutputStreamWriter}, which will encode characters using the provided + * charset. + * + * @param file + * The file to use as the destination of this writer. If the file + * exists then it will be truncated to zero size; otherwise, a new + * file will be created. The output will be written to the file + * and is buffered. + * + * @param csn + * The name of a supported {@linkplain java.nio.charset.Charset + * charset} + * + * @throws FileNotFoundException + * If the given file object does not denote an existing, writable + * regular file and a new regular file of that name cannot be + * created, or if some other error occurs while opening or + * creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(file.getPath())} + * denies write access to the file + * + * @throws UnsupportedEncodingException + * If the named charset is not supported + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter(File file, String csn) + throws FileNotFoundException, UnsupportedEncodingException + { + // this(toCharset(csn), file); + } + + /** Checks to make sure that the stream has not been closed */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private void ensureOpen() throws IOException { + // if (out == null) + // throw new IOException("Stream closed"); + // } + + /** + * Flushes the stream. + * @see #checkError() + * + * @diffblue.untested + * @diffblue.mock + */ + public void flush() { + // try { + // synchronized (lock) { + // ensureOpen(); + // out.flush(); + // } + // } + // catch (IOException x) { + // trouble = true; + // } + } + + /** + * Closes the stream and releases any system resources associated + * with it. Closing a previously closed stream has no effect. + * + * @see #checkError() + * + * @diffblue.untested + * @diffblue.mock + */ + public void close() { + // try { + // synchronized (lock) { + // if (out == null) + // return; + // out.close(); + // out = null; + // } + // } + // catch (IOException x) { + // trouble = true; + // } + } + + /** + * Flushes the stream if it's not closed and checks its error state. + * + * @return true if the print stream has encountered an error, + * either on the underlying output stream or during a format + * conversion. + * + * @diffblue.untested + * @diffblue.mock + */ + public boolean checkError() { + // if (out != null) { + // flush(); + // } + // if (out instanceof java.io.PrintWriter) { + // PrintWriter pw = (PrintWriter) out; + // return pw.checkError(); + // } else if (psOut != null) { + // return psOut.checkError(); + // } + // return trouble; + return CProver.nondetBoolean(); + } + + /** + * Indicates that an error has occurred. + * + *

This method will cause subsequent invocations of {@link + * #checkError()} to return true until {@link + * #clearError()} is invoked. + * + * @diffblue.untested + * @diffblue.mock + */ + protected void setError() { + // trouble = true; + } + + /** + * Clears the error state of this stream. + * + *

This method will cause subsequent invocations of {@link + * #checkError()} to return false until another write + * operation fails and invokes {@link #setError()}. + * + * @since 1.6 + * + * @diffblue.untested + * @diffblue.mock + */ + protected void clearError() { + // trouble = false; + } + + /* + * Exception-catching, synchronized output operations, + * which also implement the write() methods of Writer + */ + + /** + * Writes a single character. + * @param c int specifying a character to be written. + * + * @diffblue.untested + * @diffblue.mock + */ + public void write(int c) { + // try { + // synchronized (lock) { + // ensureOpen(); + // out.write(c); + // } + // } + // catch (InterruptedIOException x) { + // Thread.currentThread().interrupt(); + // } + // catch (IOException x) { + // trouble = true; + // } + } + + /** + * Writes A Portion of an array of characters. + * @param buf Array of characters + * @param off Offset from which to start writing characters + * @param len Number of characters to write + * + * @diffblue.untested + * @diffblue.mock + */ + public void write(char buf[], int off, int len) { + // try { + // synchronized (lock) { + // ensureOpen(); + // out.write(buf, off, len); + // } + // } + // catch (InterruptedIOException x) { + // Thread.currentThread().interrupt(); + // } + // catch (IOException x) { + // trouble = true; + // } + } + + /** + * Writes an array of characters. This method cannot be inherited from the + * Writer class because it must suppress I/O exceptions. + * @param buf Array of characters to be written + * + * @diffblue.untested + * @diffblue.mock + */ + public void write(char buf[]) { + // write(buf, 0, buf.length); + } + + /** + * Writes a portion of a string. + * @param s A String + * @param off Offset from which to start writing characters + * @param len Number of characters to write + * + * @diffblue.untested + * @diffblue.mock + */ + public void write(String s, int off, int len) { + // try { + // synchronized (lock) { + // ensureOpen(); + // out.write(s, off, len); + // } + // } + // catch (InterruptedIOException x) { + // Thread.currentThread().interrupt(); + // } + // catch (IOException x) { + // trouble = true; + // } + } + + /** + * Writes a string. This method cannot be inherited from the Writer class + * because it must suppress I/O exceptions. + * @param s String to be written + * + * @diffblue.untested + * @diffblue.mock + */ + public void write(String s) { + // write(s, 0, s.length()); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private void newLine() { + // try { + // synchronized (lock) { + // ensureOpen(); + // out.write(lineSeparator); + // if (autoFlush) + // out.flush(); + // } + // } + // catch (InterruptedIOException x) { + // Thread.currentThread().interrupt(); + // } + // catch (IOException x) { + // trouble = true; + // } + // } + + /* Methods that do not terminate lines */ + + /** + * Prints a boolean value. The string produced by {@link + * java.lang.String#valueOf(boolean)} is translated into bytes + * according to the platform's default character encoding, and these bytes + * are written in exactly the manner of the {@link + * #write(int)} method. + * + * @param b The boolean to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void print(boolean b) { + // write(b ? "true" : "false"); + } + + /** + * Prints a character. The character is translated into one or more bytes + * according to the platform's default character encoding, and these bytes + * are written in exactly the manner of the {@link + * #write(int)} method. + * + * @param c The char to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void print(char c) { + // write(c); + } + + /** + * Prints an integer. The string produced by {@link + * java.lang.String#valueOf(int)} is translated into bytes according + * to the platform's default character encoding, and these bytes are + * written in exactly the manner of the {@link #write(int)} + * method. + * + * @param i The int to be printed + * @see java.lang.Integer#toString(int) + * + * @diffblue.untested + * @diffblue.mock + */ + public void print(int i) { + // write(String.valueOf(i)); + } + + /** + * Prints a long integer. The string produced by {@link + * java.lang.String#valueOf(long)} is translated into bytes + * according to the platform's default character encoding, and these bytes + * are written in exactly the manner of the {@link #write(int)} + * method. + * + * @param l The long to be printed + * @see java.lang.Long#toString(long) + * + * @diffblue.untested + * @diffblue.mock + */ + public void print(long l) { + // write(String.valueOf(l)); + } + + /** + * Prints a floating-point number. The string produced by {@link + * java.lang.String#valueOf(float)} is translated into bytes + * according to the platform's default character encoding, and these bytes + * are written in exactly the manner of the {@link #write(int)} + * method. + * + * @param f The float to be printed + * @see java.lang.Float#toString(float) + * + * @diffblue.untested + * @diffblue.mock + */ + public void print(float f) { + // write(String.valueOf(f)); + } + + /** + * Prints a double-precision floating-point number. The string produced by + * {@link java.lang.String#valueOf(double)} is translated into + * bytes according to the platform's default character encoding, and these + * bytes are written in exactly the manner of the {@link + * #write(int)} method. + * + * @param d The double to be printed + * @see java.lang.Double#toString(double) + * + * @diffblue.untested + * @diffblue.mock + */ + public void print(double d) { + // write(String.valueOf(d)); + } + + /** + * Prints an array of characters. The characters are converted into bytes + * according to the platform's default character encoding, and these bytes + * are written in exactly the manner of the {@link #write(int)} + * method. + * + * @param s The array of chars to be printed + * + * @throws NullPointerException If s is null + * + * @diffblue.untested + * @diffblue.mock + */ + public void print(char s[]) { + // write(s); + } + + /** + * Prints a string. If the argument is null then the string + * "null" is printed. Otherwise, the string's characters are + * converted into bytes according to the platform's default character + * encoding, and these bytes are written in exactly the manner of the + * {@link #write(int)} method. + * + * @param s The String to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void print(String s) { + // if (s == null) { + // s = "null"; + // } + // write(s); + } + + /** + * Prints an object. The string produced by the {@link + * java.lang.String#valueOf(Object)} method is translated into bytes + * according to the platform's default character encoding, and these bytes + * are written in exactly the manner of the {@link #write(int)} + * method. + * + * @param obj The Object to be printed + * @see java.lang.Object#toString() + * + * @diffblue.untested + * @diffblue.mock + */ + public void print(Object obj) { + // write(String.valueOf(obj)); + } + + /* Methods that do terminate lines */ + + /** + * Terminates the current line by writing the line separator string. The + * line separator string is defined by the system property + * line.separator, and is not necessarily a single newline + * character ('\n'). + * + * @diffblue.untested + * @diffblue.mock + */ + public void println() { + // newLine(); + } + + /** + * Prints a boolean value and then terminates the line. This method behaves + * as though it invokes {@link #print(boolean)} and then + * {@link #println()}. + * + * @param x the boolean value to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void println(boolean x) { + // synchronized (lock) { + // print(x); + // println(); + // } + } + + /** + * Prints a character and then terminates the line. This method behaves as + * though it invokes {@link #print(char)} and then {@link + * #println()}. + * + * @param x the char value to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void println(char x) { + // synchronized (lock) { + // print(x); + // println(); + // } + } + + /** + * Prints an integer and then terminates the line. This method behaves as + * though it invokes {@link #print(int)} and then {@link + * #println()}. + * + * @param x the int value to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void println(int x) { + // synchronized (lock) { + // print(x); + // println(); + // } + } + + /** + * Prints a long integer and then terminates the line. This method behaves + * as though it invokes {@link #print(long)} and then + * {@link #println()}. + * + * @param x the long value to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void println(long x) { + // synchronized (lock) { + // print(x); + // println(); + // } + } + + /** + * Prints a floating-point number and then terminates the line. This method + * behaves as though it invokes {@link #print(float)} and then + * {@link #println()}. + * + * @param x the float value to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void println(float x) { + // synchronized (lock) { + // print(x); + // println(); + // } + } + + /** + * Prints a double-precision floating-point number and then terminates the + * line. This method behaves as though it invokes {@link + * #print(double)} and then {@link #println()}. + * + * @param x the double value to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void println(double x) { + // synchronized (lock) { + // print(x); + // println(); + // } + } + + /** + * Prints an array of characters and then terminates the line. This method + * behaves as though it invokes {@link #print(char[])} and then + * {@link #println()}. + * + * @param x the array of char values to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void println(char x[]) { + // synchronized (lock) { + // print(x); + // println(); + // } + } + + /** + * Prints a String and then terminates the line. This method behaves as + * though it invokes {@link #print(String)} and then + * {@link #println()}. + * + * @param x the String value to be printed + * + * @diffblue.untested + * @diffblue.mock + */ + public void println(String x) { + // synchronized (lock) { + // print(x); + // println(); + // } + } + + /** + * Prints an Object and then terminates the line. This method calls + * at first String.valueOf(x) to get the printed object's string value, + * then behaves as + * though it invokes {@link #print(String)} and then + * {@link #println()}. + * + * @param x The Object to be printed. + * + * @diffblue.untested + * @diffblue.mock + */ + public void println(Object x) { + // String s = String.valueOf(x); + // synchronized (lock) { + // print(s); + // println(); + // } + } + + /** + * A convenience method to write a formatted string to this writer using + * the specified format string and arguments. If automatic flushing is + * enabled, calls to this method will flush the output buffer. + * + *

An invocation of this method of the form out.printf(format, + * args) behaves in exactly the same way as the invocation + * + *

+     *     out.format(format, args) 
+ * + * @param format + * A format string as described in Format string syntax. + * + * @param args + * Arguments referenced by the format specifiers in the format + * string. If there are more arguments than format specifiers, the + * extra arguments are ignored. The number of arguments is + * variable and may be zero. The maximum number of arguments is + * limited by the maximum dimension of a Java array as defined by + * The Java™ Virtual Machine Specification. + * The behaviour on a + * null argument depends on the conversion. + * + * @throws java.util.IllegalFormatException + * If a format string contains an illegal syntax, a format + * specifier that is incompatible with the given arguments, + * insufficient arguments given the format string, or other + * illegal conditions. For specification of all possible + * formatting errors, see the Details section of the + * formatter class specification. + * + * @throws NullPointerException + * If the format is null + * + * @return This writer + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter printf(String format, Object ... args) { + // return format(format, args); + return CProver.nondetWithoutNull(this); + } + + /** + * A convenience method to write a formatted string to this writer using + * the specified format string and arguments. If automatic flushing is + * enabled, calls to this method will flush the output buffer. + * + *

An invocation of this method of the form out.printf(l, format, + * args) behaves in exactly the same way as the invocation + * + *

+     *     out.format(l, format, args) 
+ * + * @param l + * The {@linkplain java.util.Locale locale} to apply during + * formatting. If l is null then no localization + * is applied. + * + * @param format + * A format string as described in Format string syntax. + * + * @param args + * Arguments referenced by the format specifiers in the format + * string. If there are more arguments than format specifiers, the + * extra arguments are ignored. The number of arguments is + * variable and may be zero. The maximum number of arguments is + * limited by the maximum dimension of a Java array as defined by + * The Java™ Virtual Machine Specification. + * The behaviour on a + * null argument depends on the conversion. + * + * @throws java.util.IllegalFormatException + * If a format string contains an illegal syntax, a format + * specifier that is incompatible with the given arguments, + * insufficient arguments given the format string, or other + * illegal conditions. For specification of all possible + * formatting errors, see the Details section of the + * formatter class specification. + * + * @throws NullPointerException + * If the format is null + * + * @return This writer + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter printf(Locale l, String format, Object ... args) { + // return format(l, format, args); + return CProver.nondetWithoutNull(this); + } + + /** + * Writes a formatted string to this writer using the specified format + * string and arguments. If automatic flushing is enabled, calls to this + * method will flush the output buffer. + * + *

The locale always used is the one returned by {@link + * java.util.Locale#getDefault() Locale.getDefault()}, regardless of any + * previous invocations of other formatting methods on this object. + * + * @param format + * A format string as described in Format string syntax. + * + * @param args + * Arguments referenced by the format specifiers in the format + * string. If there are more arguments than format specifiers, the + * extra arguments are ignored. The number of arguments is + * variable and may be zero. The maximum number of arguments is + * limited by the maximum dimension of a Java array as defined by + * The Java™ Virtual Machine Specification. + * The behaviour on a + * null argument depends on the conversion. + * + * @throws java.util.IllegalFormatException + * If a format string contains an illegal syntax, a format + * specifier that is incompatible with the given arguments, + * insufficient arguments given the format string, or other + * illegal conditions. For specification of all possible + * formatting errors, see the Details section of the + * Formatter class specification. + * + * @throws NullPointerException + * If the format is null + * + * @return This writer + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter format(String format, Object ... args) { + // try { + // synchronized (lock) { + // ensureOpen(); + // if ((formatter == null) + // || (formatter.locale() != Locale.getDefault())) + // formatter = new Formatter(this); + // formatter.format(Locale.getDefault(), format, args); + // if (autoFlush) + // out.flush(); + // } + // } catch (InterruptedIOException x) { + // Thread.currentThread().interrupt(); + // } catch (IOException x) { + // trouble = true; + // } + // return this; + return CProver.nondetWithoutNull(this); + } + + /** + * Writes a formatted string to this writer using the specified format + * string and arguments. If automatic flushing is enabled, calls to this + * method will flush the output buffer. + * + * @param l + * The {@linkplain java.util.Locale locale} to apply during + * formatting. If l is null then no localization + * is applied. + * + * @param format + * A format string as described in Format string syntax. + * + * @param args + * Arguments referenced by the format specifiers in the format + * string. If there are more arguments than format specifiers, the + * extra arguments are ignored. The number of arguments is + * variable and may be zero. The maximum number of arguments is + * limited by the maximum dimension of a Java array as defined by + * The Java™ Virtual Machine Specification. + * The behaviour on a + * null argument depends on the conversion. + * + * @throws java.util.IllegalFormatException + * If a format string contains an illegal syntax, a format + * specifier that is incompatible with the given arguments, + * insufficient arguments given the format string, or other + * illegal conditions. For specification of all possible + * formatting errors, see the Details section of the + * formatter class specification. + * + * @throws NullPointerException + * If the format is null + * + * @return This writer + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter format(Locale l, String format, Object ... args) { + // try { + // synchronized (lock) { + // ensureOpen(); + // if ((formatter == null) || (formatter.locale() != l)) + // formatter = new Formatter(this, l); + // formatter.format(l, format, args); + // if (autoFlush) + // out.flush(); + // } + // } catch (InterruptedIOException x) { + // Thread.currentThread().interrupt(); + // } catch (IOException x) { + // trouble = true; + // } + // return this; + return CProver.nondetWithoutNull(this); + } + + /** + * Appends the specified character sequence to this writer. + * + *

An invocation of this method of the form out.append(csq) + * behaves in exactly the same way as the invocation + * + *

+     *     out.write(csq.toString()) 
+ * + *

Depending on the specification of toString for the + * character sequence csq, the entire sequence may not be + * appended. For instance, invoking the toString method of a + * character buffer will return a subsequence whose content depends upon + * the buffer's position and limit. + * + * @param csq + * The character sequence to append. If csq is + * null, then the four characters "null" are + * appended to this writer. + * + * @return This writer + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter append(CharSequence csq) { + // if (csq == null) + // write("null"); + // else + // write(csq.toString()); + // return this; + return CProver.nondetWithoutNull(this); + } + + /** + * Appends a subsequence of the specified character sequence to this writer. + * + *

An invocation of this method of the form out.append(csq, start, + * end) when csq is not null, behaves in + * exactly the same way as the invocation + * + *

+     *     out.write(csq.subSequence(start, end).toString()) 
+ * + * @param csq + * The character sequence from which a subsequence will be + * appended. If csq is null, then characters + * will be appended as if csq contained the four + * characters "null". + * + * @param start + * The index of the first character in the subsequence + * + * @param end + * The index of the character following the last character in the + * subsequence + * + * @return This writer + * + * @throws IndexOutOfBoundsException + * If start or end are negative, start + * is greater than end, or end is greater than + * csq.length() + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter append(CharSequence csq, int start, int end) { + // CharSequence cs = (csq == null ? "null" : csq); + // write(cs.subSequence(start, end).toString()); + // return this; + return CProver.nondetWithoutNull(this); + } + + /** + * Appends the specified character to this writer. + * + *

An invocation of this method of the form out.append(c) + * behaves in exactly the same way as the invocation + * + *

+     *     out.write(c) 
+ * + * @param c + * The 16-bit character to append + * + * @return This writer + * + * @since 1.5 + * + * @diffblue.untested + * @diffblue.mock + */ + public PrintWriter append(char c) { + // write(c); + // return this; + return CProver.nondetWithoutNull(this); + } + + // DIFFBLUE MODEL LIBRARY + // This method is called by CBMC just after nondeterministic object + // creation, i.e. the constraints that it specifies are only enforced at + // that time and do not have to hold globally. + // We generally want to make sure that all necessary invariants of the class + // are satisfied, and potentially restrict some fields to speed up test + // generation. + @org.cprover.MustNotThrow + protected void cproverNondetInitialize() { + // We have to override this method (rather than simply inheriting it) + // because of TG-5374. + // We also can't override it with a super call because of TG-5370. As a + // workaround, we duplicate the code from the parent method. + CProver.assume(lock != null); + } +} diff --git a/src/main/java/java/io/Writer.java b/src/main/java/java/io/Writer.java new file mode 100644 index 0000000..e53ef0e --- /dev/null +++ b/src/main/java/java/io/Writer.java @@ -0,0 +1,374 @@ +/* + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +import org.cprover.CProver; + + +/** + * Abstract class for writing to character streams. The only methods that a + * subclass must implement are write(char[], int, int), flush(), and close(). + * Most subclasses, however, will override some of the methods defined here in + * order to provide higher efficiency, additional functionality, or both. + * + * @see Writer + * @see BufferedWriter + * @see CharArrayWriter + * @see FilterWriter + * @see OutputStreamWriter + * @see FileWriter + * @see PipedWriter + * @see PrintWriter + * @see StringWriter + * @see Reader + * + * @author Mark Reinhold + * @since JDK1.1 + * + * @diffblue.limitedSupport + * Only the constructors are modelled. + */ + +public abstract class Writer implements Appendable, Closeable, Flushable { + + /** + * Temporary buffer used to hold writes of strings and single characters + */ + private char[] writeBuffer; + + /** + * Size of writeBuffer, must be >= 1 + */ + private static final int WRITE_BUFFER_SIZE = 1024; + + /** + * The object used to synchronize operations on this stream. For + * efficiency, a character-stream object may use an object other than + * itself to protect critical sections. A subclass should therefore use + * the object in this field rather than this or a synchronized + * method. + */ + protected Object lock; + + /** + * Creates a new character-stream writer whose critical sections will + * synchronize on the writer itself. + * + * @diffblue.untested + */ + protected Writer() { + // this.lock = this; + + // DIFFBLUE MODEL LIBRARY + // We are not currently generating tests for concurrency + // so to avoid a recursion, lock is set to a dummy Object. + this.lock = new Object(); + } + + /** + * Creates a new character-stream writer whose critical sections will + * synchronize on the given object. + * + * @param lock + * Object to synchronize on + * + * @diffblue.untested + */ + protected Writer(Object lock) { + if (lock == null) { + throw new NullPointerException(); + } + this.lock = lock; + } + + /** + * Writes a single character. The character to be written is contained in + * the 16 low-order bits of the given integer value; the 16 high-order bits + * are ignored. + * + *

Subclasses that intend to support efficient single-character output + * should override this method. + * + * @param c + * int specifying a character to be written + * + * @throws IOException + * If an I/O error occurs + * + * @diffblue.noSupport + */ + public void write(int c) throws IOException { + // synchronized (lock) { + // if (writeBuffer == null){ + // writeBuffer = new char[WRITE_BUFFER_SIZE]; + // } + // writeBuffer[0] = (char) c; + // write(writeBuffer, 0, 1); + // } + CProver.notModelled(); + } + + /** + * Writes an array of characters. + * + * @param cbuf + * Array of characters to be written + * + * @throws IOException + * If an I/O error occurs + * + * @diffblue.noSupport + */ + public void write(char cbuf[]) throws IOException { + // write(cbuf, 0, cbuf.length); + CProver.notModelled(); + } + + /** + * Writes a portion of an array of characters. + * + * @param cbuf + * Array of characters + * + * @param off + * Offset from which to start writing characters + * + * @param len + * Number of characters to write + * + * @throws IOException + * If an I/O error occurs + */ + abstract public void write(char cbuf[], int off, int len) throws IOException; + + /** + * Writes a string. + * + * @param str + * String to be written + * + * @throws IOException + * If an I/O error occurs + * + * @diffblue.noSupport + */ + public void write(String str) throws IOException { + // write(str, 0, str.length()); + CProver.notModelled(); + } + + /** + * Writes a portion of a string. + * + * @param str + * A String + * + * @param off + * Offset from which to start writing characters + * + * @param len + * Number of characters to write + * + * @throws IndexOutOfBoundsException + * If off is negative, or len is negative, + * or off+len is negative or greater than the length + * of the given string + * + * @throws IOException + * If an I/O error occurs + * + * @diffblue.noSupport + */ + public void write(String str, int off, int len) throws IOException { + // synchronized (lock) { + // char cbuf[]; + // if (len <= WRITE_BUFFER_SIZE) { + // if (writeBuffer == null) { + // writeBuffer = new char[WRITE_BUFFER_SIZE]; + // } + // cbuf = writeBuffer; + // } else { // Don't permanently allocate very large buffers. + // cbuf = new char[len]; + // } + // str.getChars(off, (off + len), cbuf, 0); + // write(cbuf, 0, len); + // } + CProver.notModelled(); + } + + /** + * Appends the specified character sequence to this writer. + * + *

An invocation of this method of the form out.append(csq) + * behaves in exactly the same way as the invocation + * + *

+     *     out.write(csq.toString()) 
+ * + *

Depending on the specification of toString for the + * character sequence csq, the entire sequence may not be + * appended. For instance, invoking the toString method of a + * character buffer will return a subsequence whose content depends upon + * the buffer's position and limit. + * + * @param csq + * The character sequence to append. If csq is + * null, then the four characters "null" are + * appended to this writer. + * + * @return This writer + * + * @throws IOException + * If an I/O error occurs + * + * @since 1.5 + * + * @diffblue.noSupport + */ + public Writer append(CharSequence csq) throws IOException { + // if (csq == null) + // write("null"); + // else + // write(csq.toString()); + // return this; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Appends a subsequence of the specified character sequence to this writer. + * Appendable. + * + *

An invocation of this method of the form out.append(csq, start, + * end) when csq is not null behaves in exactly the + * same way as the invocation + * + *

+     *     out.write(csq.subSequence(start, end).toString()) 
+ * + * @param csq + * The character sequence from which a subsequence will be + * appended. If csq is null, then characters + * will be appended as if csq contained the four + * characters "null". + * + * @param start + * The index of the first character in the subsequence + * + * @param end + * The index of the character following the last character in the + * subsequence + * + * @return This writer + * + * @throws IndexOutOfBoundsException + * If start or end are negative, start + * is greater than end, or end is greater than + * csq.length() + * + * @throws IOException + * If an I/O error occurs + * + * @since 1.5 + * + * @diffblue.noSupport + */ + public Writer append(CharSequence csq, int start, int end) throws IOException { + // CharSequence cs = (csq == null ? "null" : csq); + // write(cs.subSequence(start, end).toString()); + // return this; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Appends the specified character to this writer. + * + *

An invocation of this method of the form out.append(c) + * behaves in exactly the same way as the invocation + * + *

+     *     out.write(c) 
+ * + * @param c + * The 16-bit character to append + * + * @return This writer + * + * @throws IOException + * If an I/O error occurs + * + * @since 1.5 + * + * @diffblue.noSupport + */ + public Writer append(char c) throws IOException { + // write(c); + // return this; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Flushes the stream. If the stream has saved any characters from the + * various write() methods in a buffer, write them immediately to their + * intended destination. Then, if that destination is another character or + * byte stream, flush it. Thus one flush() invocation will flush all the + * buffers in a chain of Writers and OutputStreams. + * + *

If the intended destination of this stream is an abstraction provided + * by the underlying operating system, for example a file, then flushing the + * stream guarantees only that bytes previously written to the stream are + * passed to the operating system for writing; it does not guarantee that + * they are actually written to a physical device such as a disk drive. + * + * @throws IOException + * If an I/O error occurs + */ + abstract public void flush() throws IOException; + + /** + * Closes the stream, flushing it first. Once the stream has been closed, + * further write() or flush() invocations will cause an IOException to be + * thrown. Closing a previously closed stream has no effect. + * + * @throws IOException + * If an I/O error occurs + */ + abstract public void close() throws IOException; + + // DIFFBLUE MODEL LIBRARY + // This method is called by CBMC just after nondeterministic object + // creation, i.e. the constraints that it specifies are only enforced at + // that time and do not have to hold globally. + // We generally want to make sure that all necessary invariants of the class + // are satisfied, and potentially restrict some fields to speed up test + // generation. + @org.cprover.MustNotThrow + protected void cproverNondetInitialize() { + CProver.assume(lock != null); + } +} diff --git a/src/main/java/java/lang/Appendable.java b/src/main/java/java/lang/Appendable.java new file mode 100644 index 0000000..352398e --- /dev/null +++ b/src/main/java/java/lang/Appendable.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang; + +import java.io.IOException; + +/** + * An object to which char sequences and values can be appended. The + * Appendable interface must be implemented by any class whose + * instances are intended to receive formatted output from a {@link + * java.util.Formatter}. + * + *

The characters to be appended should be valid Unicode characters as + * described in Unicode Character + * Representation. Note that supplementary characters may be composed of + * multiple 16-bit char values. + * + *

Appendables are not necessarily safe for multithreaded access. Thread + * safety is the responsibility of classes that extend and implement this + * interface. + * + *

Since this interface may be implemented by existing classes + * with different styles of error handling there is no guarantee that + * errors will be propagated to the invoker. + * + * @since 1.5 + */ + +public interface Appendable { + + /** + * Appends the specified character sequence to this Appendable. + * + *

Depending on which class implements the character sequence + * csq, the entire sequence may not be appended. For + * instance, if csq is a {@link java.nio.CharBuffer} then + * the subsequence to append is defined by the buffer's position and limit. + * + * @param csq + * The character sequence to append. If csq is + * null, then the four characters "null" are + * appended to this Appendable. + * + * @return A reference to this Appendable + * + * @throws IOException + * If an I/O error occurs + */ + Appendable append(CharSequence csq) throws IOException; + + /** + * Appends a subsequence of the specified character sequence to this + * Appendable. + * + *

An invocation of this method of the form out.append(csq, start, + * end) when csq is not null, behaves in + * exactly the same way as the invocation + * + *

+     *     out.append(csq.subSequence(start, end)) 
+ * + * @param csq + * The character sequence from which a subsequence will be + * appended. If csq is null, then characters + * will be appended as if csq contained the four + * characters "null". + * + * @param start + * The index of the first character in the subsequence + * + * @param end + * The index of the character following the last character in the + * subsequence + * + * @return A reference to this Appendable + * + * @throws IndexOutOfBoundsException + * If start or end are negative, start + * is greater than end, or end is greater than + * csq.length() + * + * @throws IOException + * If an I/O error occurs + */ + Appendable append(CharSequence csq, int start, int end) throws IOException; + + /** + * Appends the specified character to this Appendable. + * + * @param c + * The character to append + * + * @return A reference to this Appendable + * + * @throws IOException + * If an I/O error occurs + */ + Appendable append(char c) throws IOException; +} diff --git a/src/main/java/java/lang/AutoCloseable.java b/src/main/java/java/lang/AutoCloseable.java new file mode 100644 index 0000000..414f186 --- /dev/null +++ b/src/main/java/java/lang/AutoCloseable.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang; + +/** + * An object that may hold resources (such as file or socket handles) + * until it is closed. The {@link #close()} method of an {@code AutoCloseable} + * object is called automatically when exiting a {@code + * try}-with-resources block for which the object has been declared in + * the resource specification header. This construction ensures prompt + * release, avoiding resource exhaustion exceptions and errors that + * may otherwise occur. + * + * @apiNote + *

It is possible, and in fact common, for a base class to + * implement AutoCloseable even though not all of its subclasses or + * instances will hold releasable resources. For code that must operate + * in complete generality, or when it is known that the {@code AutoCloseable} + * instance requires resource release, it is recommended to use {@code + * try}-with-resources constructions. However, when using facilities such as + * {@link java.util.stream.Stream} that support both I/O-based and + * non-I/O-based forms, {@code try}-with-resources blocks are in + * general unnecessary when using non-I/O-based forms. + * + * @author Josh Bloch + * @since 1.7 + */ + +public interface AutoCloseable { + /** + * Closes this resource, relinquishing any underlying resources. + * This method is invoked automatically on objects managed by the + * {@code try}-with-resources statement. + * + *

While this interface method is declared to throw {@code + * Exception}, implementers are strongly encouraged to + * declare concrete implementations of the {@code close} method to + * throw more specific exceptions, or to throw no exception at all + * if the close operation cannot fail. + * + *

Cases where the close operation may fail require careful + * attention by implementers. It is strongly advised to relinquish + * the underlying resources and to internally mark the + * resource as closed, prior to throwing the exception. The {@code + * close} method is unlikely to be invoked more than once and so + * this ensures that the resources are released in a timely manner. + * Furthermore it reduces problems that could arise when the resource + * wraps, or is wrapped, by another resource. + * + *

Implementers of this interface are also strongly advised + * to not have the {@code close} method throw {@link + * InterruptedException}. + * + * This exception interacts with a thread's interrupted status, + * and runtime misbehavior is likely to occur if an {@code + * InterruptedException} is {@linkplain Throwable#addSuppressed + * suppressed}. + * + * More generally, if it would cause problems for an + * exception to be suppressed, the {@code AutoCloseable.close} + * method should not throw it. + * + *

Note that unlike the {@link java.io.Closeable#close close} + * method of {@link java.io.Closeable}, this {@code close} method + * is not required to be idempotent. In other words, + * calling this {@code close} method more than once may have some + * visible side effect, unlike {@code Closeable.close} which is + * required to have no effect if called more than once. + * + * However, implementers of this interface are strongly encouraged + * to make their {@code close} methods idempotent. + * + * @throws Exception if this resource cannot be closed + */ + void close() throws Exception; +} diff --git a/src/main/java/java/lang/Class.java b/src/main/java/java/lang/Class.java index 36d0482..aa77311 100644 --- a/src/main/java/java/lang/Class.java +++ b/src/main/java/java/lang/Class.java @@ -428,22 +428,22 @@ public static Class getPrimitiveClass(String s){ // takes 8 seconds while the int version takes 3 seconds. static Class getPrimitiveClass(int i){ if(i==0) - return Class.forName("boolean"); + return boolean.class; if(i==1) - return Class.forName("char"); + return char.class; if(i==2) - return Class.forName("byte"); + return byte.class; if(i==3) - return Class.forName("short"); + return short.class; if(i==4) - return Class.forName("int"); + return int.class; if(i==5) - return Class.forName("long"); + return long.class; if(i==6) - return Class.forName("float"); + return float.class; if(i==7) - return Class.forName("double"); - return Class.forName("void"); + return double.class; + return void.class; } Map enumConstantDirectory() { diff --git a/src/main/java/java/lang/StringBuilder.java b/src/main/java/java/lang/StringBuilder.java index 5ab1b2f..eae70f3 100644 --- a/src/main/java/java/lang/StringBuilder.java +++ b/src/main/java/java/lang/StringBuilder.java @@ -344,6 +344,19 @@ public StringBuilder appendCodePoint(int codePoint) { return CProver.nondetWithNullForNotModelled(); } + /** + * @throws StringIndexOutOfBoundsException {@inheritDoc} + * @diffblue.fullSupport + * @diffblue.untested Only exception support is tested. + * */ + @Override + public char charAt(int index) { + if ((index < 0) || (index >= this.length())) + throw new StringIndexOutOfBoundsException(index); + String tmp = this.toString(); + return CProverString.charAt(tmp, index); + } + /** * @throws StringIndexOutOfBoundsException {@inheritDoc} * diff --git a/src/main/java/java/util/AbstractSequentialList.java b/src/main/java/java/util/AbstractSequentialList.java new file mode 100644 index 0000000..a398823 --- /dev/null +++ b/src/main/java/java/util/AbstractSequentialList.java @@ -0,0 +1,285 @@ +/* + * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util; + +import org.cprover.CProver; + +/** + * This class provides a skeletal implementation of the List + * interface to minimize the effort required to implement this interface + * backed by a "sequential access" data store (such as a linked list). For + * random access data (such as an array), AbstractList should be used + * in preference to this class.

+ * + * This class is the opposite of the AbstractList class in the sense + * that it implements the "random access" methods (get(int index), + * set(int index, E element), add(int index, E element) and + * remove(int index)) on top of the list's list iterator, instead of + * the other way around.

+ * + * To implement a list the programmer needs only to extend this class and + * provide implementations for the listIterator and size + * methods. For an unmodifiable list, the programmer need only implement the + * list iterator's hasNext, next, hasPrevious, + * previous and index methods.

+ * + * For a modifiable list the programmer should additionally implement the list + * iterator's set method. For a variable-size list the programmer + * should additionally implement the list iterator's remove and + * add methods.

+ * + * The programmer should generally provide a void (no argument) and collection + * constructor, as per the recommendation in the Collection interface + * specification.

+ * + * This class is a member of the + * + * Java Collections Framework. + * + * @author Josh Bloch + * @author Neal Gafter + * @see Collection + * @see List + * @see AbstractList + * @see AbstractCollection + * @since 1.2 + * + * @diffblue.limitedSupport + * Only the constructor of this abstract class is modelled so that subclasses + * can be instantiated. All methods are currently marked as not modelled, so + * subclasses cannot inherit any methods from this class; it only works as a + * pure interface. + */ + +public abstract class AbstractSequentialList extends AbstractList { + /** + * Sole constructor. (For invocation by subclass constructors, typically + * implicit.) + * + * @diffblue.fullSupport + */ + protected AbstractSequentialList() { + } + + /** + * Returns the element at the specified position in this list. + * + *

This implementation first gets a list iterator pointing to the + * indexed element (with listIterator(index)). Then, it gets + * the element using ListIterator.next and returns it. + * + * @throws IndexOutOfBoundsException {@inheritDoc} + * + * @diffblue.noSupport + */ + public E get(int index) { + // try { + // return listIterator(index).next(); + // } catch (NoSuchElementException exc) { + // throw new IndexOutOfBoundsException("Index: "+index); + // } + CProver.notModelled(); + return CProver.nondetWithNullForNotModelled(); + } + + /** + * Replaces the element at the specified position in this list with the + * specified element (optional operation). + * + *

This implementation first gets a list iterator pointing to the + * indexed element (with listIterator(index)). Then, it gets + * the current element using ListIterator.next and replaces it + * with ListIterator.set. + * + *

Note that this implementation will throw an + * UnsupportedOperationException if the list iterator does not + * implement the set operation. + * + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + * @throws IndexOutOfBoundsException {@inheritDoc} + * + * @diffblue.noSupport + */ + public E set(int index, E element) { + // try { + // ListIterator e = listIterator(index); + // E oldVal = e.next(); + // e.set(element); + // return oldVal; + // } catch (NoSuchElementException exc) { + // throw new IndexOutOfBoundsException("Index: "+index); + // } + CProver.notModelled(); + return CProver.nondetWithNullForNotModelled(); + } + + /** + * Inserts the specified element at the specified position in this list + * (optional operation). Shifts the element currently at that position + * (if any) and any subsequent elements to the right (adds one to their + * indices). + * + *

This implementation first gets a list iterator pointing to the + * indexed element (with listIterator(index)). Then, it + * inserts the specified element with ListIterator.add. + * + *

Note that this implementation will throw an + * UnsupportedOperationException if the list iterator does not + * implement the add operation. + * + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + * @throws IndexOutOfBoundsException {@inheritDoc} + * + * @diffblue.noSupport + */ + public void add(int index, E element) { + // try { + // listIterator(index).add(element); + // } catch (NoSuchElementException exc) { + // throw new IndexOutOfBoundsException("Index: "+index); + // } + CProver.notModelled(); + } + + /** + * Removes the element at the specified position in this list (optional + * operation). Shifts any subsequent elements to the left (subtracts one + * from their indices). Returns the element that was removed from the + * list. + * + *

This implementation first gets a list iterator pointing to the + * indexed element (with listIterator(index)). Then, it removes + * the element with ListIterator.remove. + * + *

Note that this implementation will throw an + * UnsupportedOperationException if the list iterator does not + * implement the remove operation. + * + * @throws UnsupportedOperationException {@inheritDoc} + * @throws IndexOutOfBoundsException {@inheritDoc} + * + * @diffblue.noSupport + */ + public E remove(int index) { + // try { + // ListIterator e = listIterator(index); + // E outCast = e.next(); + // e.remove(); + // return outCast; + // } catch (NoSuchElementException exc) { + // throw new IndexOutOfBoundsException("Index: "+index); + // } + CProver.notModelled(); + return CProver.nondetWithNullForNotModelled(); + } + + + // Bulk Operations + + /** + * Inserts all of the elements in the specified collection into this + * list at the specified position (optional operation). Shifts the + * element currently at that position (if any) and any subsequent + * elements to the right (increases their indices). The new elements + * will appear in this list in the order that they are returned by the + * specified collection's iterator. The behavior of this operation is + * undefined if the specified collection is modified while the + * operation is in progress. (Note that this will occur if the specified + * collection is this list, and it's nonempty.) + * + *

This implementation gets an iterator over the specified collection and + * a list iterator over this list pointing to the indexed element (with + * listIterator(index)). Then, it iterates over the specified + * collection, inserting the elements obtained from the iterator into this + * list, one at a time, using ListIterator.add followed by + * ListIterator.next (to skip over the added element). + * + *

Note that this implementation will throw an + * UnsupportedOperationException if the list iterator returned by + * the listIterator method does not implement the add + * operation. + * + * @throws UnsupportedOperationException {@inheritDoc} + * @throws ClassCastException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + * @throws IndexOutOfBoundsException {@inheritDoc} + * + * @diffblue.noSupport + */ + public boolean addAll(int index, Collection c) { + // try { + // boolean modified = false; + // ListIterator e1 = listIterator(index); + // Iterator e2 = c.iterator(); + // while (e2.hasNext()) { + // e1.add(e2.next()); + // modified = true; + // } + // return modified; + // } catch (NoSuchElementException exc) { + // throw new IndexOutOfBoundsException("Index: "+index); + // } + CProver.notModelled(); + return CProver.nondetBoolean(); + } + + + // Iterators + + /** + * Returns an iterator over the elements in this list (in proper + * sequence).

+ * + * This implementation merely returns a list iterator over the list. + * + * @return an iterator over the elements in this list (in proper sequence) + * + * @diffblue.fullSupport + * @diffblue.untested + */ + public Iterator iterator() { + return listIterator(); + } + + /** + * Returns a list iterator over the elements in this list (in proper + * sequence). + * + * @param index index of first element to be returned from the list + * iterator (by a call to the next method) + * @return a list iterator over the elements in this list (in proper + * sequence) + * @throws IndexOutOfBoundsException {@inheritDoc} + */ + public abstract ListIterator listIterator(int index); +} diff --git a/src/main/java/java/util/Arrays.java b/src/main/java/java/util/Arrays.java new file mode 100644 index 0000000..55c06c2 --- /dev/null +++ b/src/main/java/java/util/Arrays.java @@ -0,0 +1,5729 @@ +/* + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util; + +import java.lang.reflect.Array; +import java.util.concurrent.ForkJoinPool; +import java.util.function.BinaryOperator; +import java.util.function.Consumer; +import java.util.function.DoubleBinaryOperator; +import java.util.function.IntBinaryOperator; +import java.util.function.IntFunction; +import java.util.function.IntToDoubleFunction; +import java.util.function.IntToLongFunction; +import java.util.function.IntUnaryOperator; +import java.util.function.LongBinaryOperator; +import java.util.function.UnaryOperator; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.cprover.CProver; + +/** + * This class contains various methods for manipulating arrays (such as + * sorting and searching). This class also contains a static factory + * that allows arrays to be viewed as lists. + * + *

The methods in this class all throw a {@code NullPointerException}, + * if the specified array reference is null, except where noted. + * + *

The documentation for the methods contained in this class includes + * briefs description of the implementations. Such descriptions should + * be regarded as implementation notes, rather than parts of the + * specification. Implementors should feel free to substitute other + * algorithms, so long as the specification itself is adhered to. (For + * example, the algorithm used by {@code sort(Object[])} does not have to be + * a MergeSort, but it does have to be stable.) + * + *

This class is a member of the + * + * Java Collections Framework. + * + * @author Josh Bloch + * @author Neal Gafter + * @author John Rose + * @since 1.2 + * + * @diffblue.limitedSupport + * Implements the asList(T...) method and the inner class Arrays$ArrayList + * that it returns. + */ +public class Arrays { + + /** + * The minimum array length below which a parallel sorting + * algorithm will not further partition the sorting task. Using + * smaller sizes typically results in memory contention across + * tasks that makes parallel speedups unlikely. + */ + + // DIFFBLUE MODEL LIBRARY + // This is not used in the model, so it can be commented out. + // private static final int MIN_ARRAY_SORT_GRAN = 1 << 13; + + // Suppresses default constructor, ensuring non-instantiability. + private Arrays() {} + + /** + * A comparator that implements the natural ordering of a group of + * mutually comparable elements. May be used when a supplied + * comparator is null. To simplify code-sharing within underlying + * implementations, the compare method only declares type Object + * for its second argument. + * + * Arrays class implementor's note: It is an empirical matter + * whether ComparableTimSort offers any performance benefit over + * TimSort used with this comparator. If not, you are better off + * deleting or bypassing ComparableTimSort. There is currently no + * empirical case for separating them for parallel sorting, so all + * public Object parallelSort methods use the same comparator + * based implementation. + */ + + // DIFFBLUE MODEL LIBRARY + // This class is not currently modelled. + // static final class NaturalOrder implements Comparator { + // @SuppressWarnings("unchecked") + // public int compare(Object first, Object second) { + // return ((Comparable)first).compareTo(second); + // } + // static final NaturalOrder INSTANCE = new NaturalOrder(); + // } + + /** + * Checks that {@code fromIndex} and {@code toIndex} are in + * the range and throws an exception if they aren't. + */ + private static void rangeCheck(int arrayLength, int fromIndex, int toIndex) { + if (fromIndex > toIndex) { + //throw new IllegalArgumentException( + // "fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); + // DIFFBLUE MODEL LIBRARY removing string concatenation for performance + throw new IllegalArgumentException(); + } + if (fromIndex < 0) { + throw new ArrayIndexOutOfBoundsException(fromIndex); + } + if (toIndex > arrayLength) { + throw new ArrayIndexOutOfBoundsException(toIndex); + } + } + + /* + * Sorting methods. Note that all public "sort" methods take the + * same form: Performing argument checks if necessary, and then + * expanding arguments into those required for the internal + * implementation methods residing in other package-private + * classes (except for legacyMergeSort, included in this class). + */ + + /** + * Sorts the specified array into ascending numerical order. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * + * @diffblue.fullSupport + */ + // DIFFBLUE MODEL LIBRARY + // The original implementation uses the Dual Pivot Quicksort. + // We avoid nested loops by using CProver, iterating through the + // array and setting every entry to store an element from a copy of + // the old array whose position is determined by nondetInt. + // To ensure that each position is unique, we use an array of booleans + // to mark positions. The CProver.assume method ensures that the + // choices are such that the array is sorted. + public static void sort(int[] a) { + // DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + int[] oldArray = a.clone(); + boolean[] assigned = new boolean[a.length]; + for (int i = 0; i < a.length; ++i) { + int choice = CProver.nondetInt(); + CProver.assume(0 <= choice && choice < a.length && !assigned[choice]); + a[i] = oldArray[choice]; + assigned[choice] = true; + if (i != 0) CProver.assume(a[i - 1] <= a[i]); + } + } + + /** + * Sorts the specified range of the array into ascending order. The range + * to be sorted extends from the index {@code fromIndex}, inclusive, to + * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, + * the range to be sorted is empty. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @diffblue.noSupport + */ + public static void sort(int[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * + * @diffblue.fullSupport + */ + // DIFFBLUE MODEL LIBRARY + // See sort(int[] a) + public static void sort(long[] a) { + // DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + long[] oldArray = a.clone(); + boolean[] assigned = new boolean[a.length]; + for (int i = 0; i < a.length; ++i) { + int choice = CProver.nondetInt(); + CProver.assume(0 <= choice && choice < a.length && !assigned[choice]); + a[i] = oldArray[choice]; + assigned[choice] = true; + if (i != 0) CProver.assume(a[i - 1] <= a[i]); + } + } + + /** + * Sorts the specified range of the array into ascending order. The range + * to be sorted extends from the index {@code fromIndex}, inclusive, to + * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, + * the range to be sorted is empty. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @diffblue.noSupport + */ + public static void sort(long[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @diffblue.fullSupport + */ + // DIFFBLUE MODEL LIBRARY + // See sort(int[] a) + public static void sort(short[] a) { + // DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + short[] oldArray = a.clone(); + boolean[] assigned = new boolean[a.length]; + for (int i = 0; i < a.length; ++i) { + int choice = CProver.nondetInt(); + CProver.assume(0 <= choice && choice < a.length && !assigned[choice]); + a[i] = oldArray[choice]; + assigned[choice] = true; + if (i != 0) CProver.assume(a[i - 1] <= a[i]); + } + } + + /** + * Sorts the specified range of the array into ascending order. The range + * to be sorted extends from the index {@code fromIndex}, inclusive, to + * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, + * the range to be sorted is empty. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @diffblue.noSupport + */ + public static void sort(short[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @diffblue.limitedSupport + * TG-4076 Non-deterministically generated char arrays can be incorrect + */ + // DIFFBLUE MODEL LIBRARY + // See sort(int[] a) + public static void sort(char[] a) { + // DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + char[] oldArray = a.clone(); + boolean[] assigned = new boolean[a.length]; + for (int i = 0; i < a.length; ++i) { + int choice = CProver.nondetInt(); + CProver.assume(0 <= choice && choice < a.length && !assigned[choice]); + a[i] = oldArray[choice]; + assigned[choice] = true; + if (i != 0) CProver.assume(a[i - 1] <= a[i]); + } + } + + /** + * Sorts the specified range of the array into ascending order. The range + * to be sorted extends from the index {@code fromIndex}, inclusive, to + * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, + * the range to be sorted is empty. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @diffblue.noSupport + */ + public static void sort(char[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @diffblue.fullSupport + */ + // DIFFBLUE MODEL LIBRARY + // See sort(int[] a) + public static void sort(byte[] a) { + // DualPivotQuicksort.sort(a, 0, a.length - 1); + byte[] oldArray = a.clone(); + boolean[] assigned = new boolean[a.length]; + for (int i = 0; i < a.length; ++i) { + int choice = CProver.nondetInt(); + CProver.assume(0 <= choice && choice < a.length && !assigned[choice]); + a[i] = oldArray[choice]; + assigned[choice] = true; + if (i != 0) CProver.assume(a[i - 1] <= a[i]); + } + } + + /** + * Sorts the specified range of the array into ascending order. The range + * to be sorted extends from the index {@code fromIndex}, inclusive, to + * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, + * the range to be sorted is empty. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @diffblue.noSupport + */ + public static void sort(byte[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + *

The {@code <} relation does not provide a total order on all float + * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} + * value compares neither less than, greater than, nor equal to any value, + * even itself. This method uses the total order imposed by the method + * {@link Float#compareTo}: {@code -0.0f} is treated as less than value + * {@code 0.0f} and {@code Float.NaN} is considered greater than any + * other value and all {@code Float.NaN} values are considered equal. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @diffblue.fullSupport + */ + // DIFFBLUE MODEL LIBRARY + // See sort(int[] a) + public static void sort(float[] a) { + // DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + float[] oldArray = a.clone(); + boolean[] assigned = new boolean[a.length]; + for (int i = 0; i < a.length; ++i) { + int choice = CProver.nondetInt(); + CProver.assume(0 <= choice && choice < a.length && !assigned[choice]); + a[i] = oldArray[choice]; + assigned[choice] = true; + // DIFFBLUE MODEL LIBRARY - Added predicate to ensure NaN values + // are considered greater than any other value, required since + // the inequality (a[i] <= a[i+1]) is always false with NaN values + if (i != 0) CProver.assume(a[i - 1] <= a[i] || Float.isNaN(a[i])); + } + } + + /** + * Sorts the specified range of the array into ascending order. The range + * to be sorted extends from the index {@code fromIndex}, inclusive, to + * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, + * the range to be sorted is empty. + * + *

The {@code <} relation does not provide a total order on all float + * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} + * value compares neither less than, greater than, nor equal to any value, + * even itself. This method uses the total order imposed by the method + * {@link Float#compareTo}: {@code -0.0f} is treated as less than value + * {@code 0.0f} and {@code Float.NaN} is considered greater than any + * other value and all {@code Float.NaN} values are considered equal. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @diffblue.noSupport + */ + public static void sort(float[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + *

The {@code <} relation does not provide a total order on all double + * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} + * value compares neither less than, greater than, nor equal to any value, + * even itself. This method uses the total order imposed by the method + * {@link Double#compareTo}: {@code -0.0d} is treated as less than value + * {@code 0.0d} and {@code Double.NaN} is considered greater than any + * other value and all {@code Double.NaN} values are considered equal. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @diffblue.fullSupport + */ + // DIFFBLUE MODEL LIBRARY + // See sort(int[] a) + public static void sort(double[] a) { + // DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + double[] oldArray = a.clone(); + boolean[] assigned = new boolean[a.length]; + for (int i = 0; i < a.length; ++i) { + int choice = CProver.nondetInt(); + CProver.assume(0 <= choice && choice < a.length && !assigned[choice]); + a[i] = oldArray[choice]; + assigned[choice] = true; + // DIFFBLUE MODEL LIBRARY - Added predicate to ensure NaN values + // are considered greater than any other value, required since + // the inequality (a[i] <= a[i+1]) is always false with NaN values + if (i != 0) CProver.assume(a[i - 1] <= a[i] || Double.isNaN(a[i])); + } + } + + /** + * Sorts the specified range of the array into ascending order. The range + * to be sorted extends from the index {@code fromIndex}, inclusive, to + * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, + * the range to be sorted is empty. + * + *

The {@code <} relation does not provide a total order on all double + * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} + * value compares neither less than, greater than, nor equal to any value, + * even itself. This method uses the total order imposed by the method + * {@link Double#compareTo}: {@code -0.0d} is treated as less than value + * {@code 0.0d} and {@code Double.NaN} is considered greater than any + * other value and all {@code Double.NaN} values are considered equal. + * + *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort + * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm + * offers O(n log(n)) performance on many data sets that cause other + * quicksorts to degrade to quadratic performance, and is typically + * faster than traditional (one-pivot) Quicksort implementations. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @diffblue.noSupport + */ + public static void sort(double[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(byte[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(byte[]) Arrays.sort} method. The algorithm requires a + * working space no greater than the size of the original array. The + * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to + * execute any parallel tasks. + * + * @param a the array to be sorted + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(byte[] a) { + // int n = a.length, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, 0, n - 1); + // else + // new ArraysParallelSortHelpers.FJByte.Sorter + // (null, a, new byte[n], 0, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified range of the array into ascending numerical order. + * The range to be sorted extends from the index {@code fromIndex}, + * inclusive, to the index {@code toIndex}, exclusive. If + * {@code fromIndex == toIndex}, the range to be sorted is empty. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(byte[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(byte[]) Arrays.sort} method. The algorithm requires a working + * space no greater than the size of the specified range of the original + * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is + * used to execute any parallel tasks. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(byte[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // int n = toIndex - fromIndex, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); + // else + // new ArraysParallelSortHelpers.FJByte.Sorter + // (null, a, new byte[n], fromIndex, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(char[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(char[]) Arrays.sort} method. The algorithm requires a + * working space no greater than the size of the original array. The + * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to + * execute any parallel tasks. + * + * @param a the array to be sorted + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(char[] a) { + // int n = a.length, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJChar.Sorter + // (null, a, new char[n], 0, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified range of the array into ascending numerical order. + * The range to be sorted extends from the index {@code fromIndex}, + * inclusive, to the index {@code toIndex}, exclusive. If + * {@code fromIndex == toIndex}, the range to be sorted is empty. + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(char[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(char[]) Arrays.sort} method. The algorithm requires a working + * space no greater than the size of the specified range of the original + * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is + * used to execute any parallel tasks. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(char[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // int n = toIndex - fromIndex, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJChar.Sorter + // (null, a, new char[n], fromIndex, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(short[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(short[]) Arrays.sort} method. The algorithm requires a + * working space no greater than the size of the original array. The + * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to + * execute any parallel tasks. + * + * @param a the array to be sorted + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(short[] a) { + // int n = a.length, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJShort.Sorter + // (null, a, new short[n], 0, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified range of the array into ascending numerical order. + * The range to be sorted extends from the index {@code fromIndex}, + * inclusive, to the index {@code toIndex}, exclusive. If + * {@code fromIndex == toIndex}, the range to be sorted is empty. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(short[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(short[]) Arrays.sort} method. The algorithm requires a working + * space no greater than the size of the specified range of the original + * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is + * used to execute any parallel tasks. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(short[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // int n = toIndex - fromIndex, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJShort.Sorter + // (null, a, new short[n], fromIndex, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(int[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(int[]) Arrays.sort} method. The algorithm requires a + * working space no greater than the size of the original array. The + * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to + * execute any parallel tasks. + * + * @param a the array to be sorted + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(int[] a) { + // int n = a.length, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJInt.Sorter + // (null, a, new int[n], 0, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified range of the array into ascending numerical order. + * The range to be sorted extends from the index {@code fromIndex}, + * inclusive, to the index {@code toIndex}, exclusive. If + * {@code fromIndex == toIndex}, the range to be sorted is empty. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(int[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(int[]) Arrays.sort} method. The algorithm requires a working + * space no greater than the size of the specified range of the original + * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is + * used to execute any parallel tasks. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(int[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // int n = toIndex - fromIndex, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJInt.Sorter + // (null, a, new int[n], fromIndex, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(long[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(long[]) Arrays.sort} method. The algorithm requires a + * working space no greater than the size of the original array. The + * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to + * execute any parallel tasks. + * + * @param a the array to be sorted + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(long[] a) { + // int n = a.length, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJLong.Sorter + // (null, a, new long[n], 0, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified range of the array into ascending numerical order. + * The range to be sorted extends from the index {@code fromIndex}, + * inclusive, to the index {@code toIndex}, exclusive. If + * {@code fromIndex == toIndex}, the range to be sorted is empty. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(long[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(long[]) Arrays.sort} method. The algorithm requires a working + * space no greater than the size of the specified range of the original + * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is + * used to execute any parallel tasks. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(long[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // int n = toIndex - fromIndex, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJLong.Sorter + // (null, a, new long[n], fromIndex, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + *

The {@code <} relation does not provide a total order on all float + * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} + * value compares neither less than, greater than, nor equal to any value, + * even itself. This method uses the total order imposed by the method + * {@link Float#compareTo}: {@code -0.0f} is treated as less than value + * {@code 0.0f} and {@code Float.NaN} is considered greater than any + * other value and all {@code Float.NaN} values are considered equal. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(float[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(float[]) Arrays.sort} method. The algorithm requires a + * working space no greater than the size of the original array. The + * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to + * execute any parallel tasks. + * + * @param a the array to be sorted + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(float[] a) { + // int n = a.length, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJFloat.Sorter + // (null, a, new float[n], 0, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified range of the array into ascending numerical order. + * The range to be sorted extends from the index {@code fromIndex}, + * inclusive, to the index {@code toIndex}, exclusive. If + * {@code fromIndex == toIndex}, the range to be sorted is empty. + * + *

The {@code <} relation does not provide a total order on all float + * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} + * value compares neither less than, greater than, nor equal to any value, + * even itself. This method uses the total order imposed by the method + * {@link Float#compareTo}: {@code -0.0f} is treated as less than value + * {@code 0.0f} and {@code Float.NaN} is considered greater than any + * other value and all {@code Float.NaN} values are considered equal. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(float[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(float[]) Arrays.sort} method. The algorithm requires a working + * space no greater than the size of the specified range of the original + * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is + * used to execute any parallel tasks. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(float[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // int n = toIndex - fromIndex, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJFloat.Sorter + // (null, a, new float[n], fromIndex, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified array into ascending numerical order. + * + *

The {@code <} relation does not provide a total order on all double + * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} + * value compares neither less than, greater than, nor equal to any value, + * even itself. This method uses the total order imposed by the method + * {@link Double#compareTo}: {@code -0.0d} is treated as less than value + * {@code 0.0d} and {@code Double.NaN} is considered greater than any + * other value and all {@code Double.NaN} values are considered equal. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(double[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(double[]) Arrays.sort} method. The algorithm requires a + * working space no greater than the size of the original array. The + * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to + * execute any parallel tasks. + * + * @param a the array to be sorted + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(double[] a) { + // int n = a.length, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJDouble.Sorter + // (null, a, new double[n], 0, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified range of the array into ascending numerical order. + * The range to be sorted extends from the index {@code fromIndex}, + * inclusive, to the index {@code toIndex}, exclusive. If + * {@code fromIndex == toIndex}, the range to be sorted is empty. + * + *

The {@code <} relation does not provide a total order on all double + * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} + * value compares neither less than, greater than, nor equal to any value, + * even itself. This method uses the total order imposed by the method + * {@link Double#compareTo}: {@code -0.0d} is treated as less than value + * {@code 0.0d} and {@code Double.NaN} is considered greater than any + * other value and all {@code Double.NaN} values are considered equal. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(double[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(double[]) Arrays.sort} method. The algorithm requires a working + * space no greater than the size of the specified range of the original + * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is + * used to execute any parallel tasks. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element, inclusive, to be sorted + * @param toIndex the index of the last element, exclusive, to be sorted + * + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > a.length} + * + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSort(double[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // int n = toIndex - fromIndex, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJDouble.Sorter + // (null, a, new double[n], fromIndex, n, 0, + // ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified array of objects into ascending order, according + * to the {@linkplain Comparable natural ordering} of its elements. + * All elements in the array must implement the {@link Comparable} + * interface. Furthermore, all elements in the array must be + * mutually comparable (that is, {@code e1.compareTo(e2)} must + * not throw a {@code ClassCastException} for any elements {@code e1} + * and {@code e2} in the array). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(Object[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(Object[]) Arrays.sort} method. The algorithm requires a + * working space no greater than the size of the original array. The + * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to + * execute any parallel tasks. + * + * @param the class of the objects to be sorted + * @param a the array to be sorted + * + * @throws ClassCastException if the array contains elements that are not + * mutually comparable (for example, strings and integers) + * @throws IllegalArgumentException (optional) if the natural + * ordering of the array elements is found to violate the + * {@link Comparable} contract + * + * @since 1.8 + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static > void parallelSort(T[] a) { + // int n = a.length, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // TimSort.sort(a, 0, n, NaturalOrder.INSTANCE, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJObject.Sorter + // (null, a, + // (T[])Array.newInstance(a.getClass().getComponentType(), n), + // 0, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g, NaturalOrder.INSTANCE).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified range of the specified array of objects into + * ascending order, according to the + * {@linkplain Comparable natural ordering} of its + * elements. The range to be sorted extends from index + * {@code fromIndex}, inclusive, to index {@code toIndex}, exclusive. + * (If {@code fromIndex==toIndex}, the range to be sorted is empty.) All + * elements in this range must implement the {@link Comparable} + * interface. Furthermore, all elements in this range must be mutually + * comparable (that is, {@code e1.compareTo(e2)} must not throw a + * {@code ClassCastException} for any elements {@code e1} and + * {@code e2} in the array). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(Object[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(Object[]) Arrays.sort} method. The algorithm requires a working + * space no greater than the size of the specified range of the original + * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is + * used to execute any parallel tasks. + * + * @param the class of the objects to be sorted + * @param a the array to be sorted + * @param fromIndex the index of the first element (inclusive) to be + * sorted + * @param toIndex the index of the last element (exclusive) to be sorted + * @throws IllegalArgumentException if {@code fromIndex > toIndex} or + * (optional) if the natural ordering of the array elements is + * found to violate the {@link Comparable} contract + * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or + * {@code toIndex > a.length} + * @throws ClassCastException if the array contains elements that are + * not mutually comparable (for example, strings and + * integers). + * + * @since 1.8 + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static > + void parallelSort(T[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // int n = toIndex - fromIndex, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // TimSort.sort(a, fromIndex, toIndex, NaturalOrder.INSTANCE, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJObject.Sorter + // (null, a, + // (T[])Array.newInstance(a.getClass().getComponentType(), n), + // fromIndex, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g, NaturalOrder.INSTANCE).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified array of objects according to the order induced by + * the specified comparator. All elements in the array must be + * mutually comparable by the specified comparator (that is, + * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} + * for any elements {@code e1} and {@code e2} in the array). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(Object[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(Object[]) Arrays.sort} method. The algorithm requires a + * working space no greater than the size of the original array. The + * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to + * execute any parallel tasks. + * + * @param the class of the objects to be sorted + * @param a the array to be sorted + * @param cmp the comparator to determine the order of the array. A + * {@code null} value indicates that the elements' + * {@linkplain Comparable natural ordering} should be used. + * @throws ClassCastException if the array contains elements that are + * not mutually comparable using the specified comparator + * @throws IllegalArgumentException (optional) if the comparator is + * found to violate the {@link java.util.Comparator} contract + * + * @since 1.8 + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static void parallelSort(T[] a, Comparator cmp) { + // if (cmp == null) + // cmp = NaturalOrder.INSTANCE; + // int n = a.length, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // TimSort.sort(a, 0, n, cmp, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJObject.Sorter + // (null, a, + // (T[])Array.newInstance(a.getClass().getComponentType(), n), + // 0, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g, cmp).invoke(); + CProver.notModelled(); + } + + /** + * Sorts the specified range of the specified array of objects according + * to the order induced by the specified comparator. The range to be + * sorted extends from index {@code fromIndex}, inclusive, to index + * {@code toIndex}, exclusive. (If {@code fromIndex==toIndex}, the + * range to be sorted is empty.) All elements in the range must be + * mutually comparable by the specified comparator (that is, + * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} + * for any elements {@code e1} and {@code e2} in the range). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + * @implNote The sorting algorithm is a parallel sort-merge that breaks the + * array into sub-arrays that are themselves sorted and then merged. When + * the sub-array length reaches a minimum granularity, the sub-array is + * sorted using the appropriate {@link Arrays#sort(Object[]) Arrays.sort} + * method. If the length of the specified array is less than the minimum + * granularity, then it is sorted using the appropriate {@link + * Arrays#sort(Object[]) Arrays.sort} method. The algorithm requires a working + * space no greater than the size of the specified range of the original + * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is + * used to execute any parallel tasks. + * + * @param the class of the objects to be sorted + * @param a the array to be sorted + * @param fromIndex the index of the first element (inclusive) to be + * sorted + * @param toIndex the index of the last element (exclusive) to be sorted + * @param cmp the comparator to determine the order of the array. A + * {@code null} value indicates that the elements' + * {@linkplain Comparable natural ordering} should be used. + * @throws IllegalArgumentException if {@code fromIndex > toIndex} or + * (optional) if the natural ordering of the array elements is + * found to violate the {@link Comparable} contract + * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or + * {@code toIndex > a.length} + * @throws ClassCastException if the array contains elements that are + * not mutually comparable (for example, strings and + * integers). + * + * @since 1.8 + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static void parallelSort(T[] a, int fromIndex, int toIndex, + Comparator cmp) { + // rangeCheck(a.length, fromIndex, toIndex); + // if (cmp == null) + // cmp = NaturalOrder.INSTANCE; + // int n = toIndex - fromIndex, p, g; + // if (n <= MIN_ARRAY_SORT_GRAN || + // (p = ForkJoinPool.getCommonPoolParallelism()) == 1) + // TimSort.sort(a, fromIndex, toIndex, cmp, null, 0, 0); + // else + // new ArraysParallelSortHelpers.FJObject.Sorter + // (null, a, + // (T[])Array.newInstance(a.getClass().getComponentType(), n), + // fromIndex, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? + // MIN_ARRAY_SORT_GRAN : g, cmp).invoke(); + CProver.notModelled(); + } + + /* + * Sorting of complex type arrays. + */ + + /** + * Old merge sort implementation can be selected (for + * compatibility with broken comparators) using a system property. + * Cannot be a static boolean in the enclosing class due to + * circular dependencies. To be removed in a future release. + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static final class LegacyMergeSort { + // private static final boolean userRequested = + // java.security.AccessController.doPrivileged( + // new sun.security.action.GetBooleanAction( + // "java.util.Arrays.useLegacyMergeSort")).booleanValue(); + // } + + /** + * Sorts the specified array of objects into ascending order, according + * to the {@linkplain Comparable natural ordering} of its elements. + * All elements in the array must implement the {@link Comparable} + * interface. Furthermore, all elements in the array must be + * mutually comparable (that is, {@code e1.compareTo(e2)} must + * not throw a {@code ClassCastException} for any elements {@code e1} + * and {@code e2} in the array). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + *

Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. + * + *

The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techniques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. + * + * @param a the array to be sorted + * @throws ClassCastException if the array contains elements that are not + * mutually comparable (for example, strings and integers) + * @throws IllegalArgumentException (optional) if the natural + * ordering of the array elements is found to violate the + * {@link Comparable} contract + * + * @diffblue.limitedSupport + * TG-4302 - Will not work for compareTo methods that don't implement a + * total order (if a < b and b < a OR a > b and b > a) + */ + // DIFFBLUE MODEL LIBRARY + // See sort(int[] a) + public static void sort(Object[] a) { + // if (LegacyMergeSort.userRequested) + // legacyMergeSort(a); + // else + // ComparableTimSort.sort(a, 0, a.length, null, 0, 0); + Object[] oldArray = a.clone(); + boolean[] assigned = new boolean[a.length]; + for (int i = 0; i < a.length; ++i) { + int choice = CProver.nondetInt(); + CProver.assume(0 <= choice && choice < a.length && !assigned[choice]); + a[i] = oldArray[choice]; + assigned[choice] = true; + // Added test solves case if comparison always returns positive + if (i != 0) CProver.assume(((((Comparable)a[i-1]).compareTo((Comparable)a[i]) <= 0) || (((Comparable)a[i]).compareTo((Comparable)a[i-1]) > 0))); + } + } + + /** To be removed in a future release. */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static void legacyMergeSort(Object[] a) { + // Object[] aux = a.clone(); + // mergeSort(aux, a, 0, a.length, 0); + // } + + /** + * Sorts the specified range of the specified array of objects into + * ascending order, according to the + * {@linkplain Comparable natural ordering} of its + * elements. The range to be sorted extends from index + * {@code fromIndex}, inclusive, to index {@code toIndex}, exclusive. + * (If {@code fromIndex==toIndex}, the range to be sorted is empty.) All + * elements in this range must implement the {@link Comparable} + * interface. Furthermore, all elements in this range must be mutually + * comparable (that is, {@code e1.compareTo(e2)} must not throw a + * {@code ClassCastException} for any elements {@code e1} and + * {@code e2} in the array). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + *

Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. + * + *

The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techniques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. + * + * @param a the array to be sorted + * @param fromIndex the index of the first element (inclusive) to be + * sorted + * @param toIndex the index of the last element (exclusive) to be sorted + * @throws IllegalArgumentException if {@code fromIndex > toIndex} or + * (optional) if the natural ordering of the array elements is + * found to violate the {@link Comparable} contract + * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or + * {@code toIndex > a.length} + * @throws ClassCastException if the array contains elements that are + * not mutually comparable (for example, strings and + * integers). + * @diffblue.noSupport + */ + public static void sort(Object[] a, int fromIndex, int toIndex) { + // rangeCheck(a.length, fromIndex, toIndex); + // if (LegacyMergeSort.userRequested) + // legacyMergeSort(a, fromIndex, toIndex); + // else + // ComparableTimSort.sort(a, fromIndex, toIndex, null, 0, 0); + CProver.notModelled(); + } + + /** To be removed in a future release. */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static void legacyMergeSort(Object[] a, + // int fromIndex, int toIndex) { + // Object[] aux = copyOfRange(a, fromIndex, toIndex); + // mergeSort(aux, a, fromIndex, toIndex, -fromIndex); + // } + + /** + * Tuning parameter: list size at or below which insertion sort will be + * used in preference to mergesort. + * To be removed in a future release. + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static final int INSERTIONSORT_THRESHOLD = 7; + + /** + * Src is the source array that starts at index 0 + * Dest is the (possibly larger) array destination with a possible offset + * low is the index in dest to start sorting + * high is the end index in dest to end sorting + * off is the offset to generate corresponding low, high in src + * To be removed in a future release. + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // @SuppressWarnings({"unchecked", "rawtypes"}) + // private static void mergeSort(Object[] src, + // Object[] dest, + // int low, + // int high, + // int off) { + // int length = high - low; + // + // // Insertion sort on smallest arrays + // if (length < INSERTIONSORT_THRESHOLD) { + // for (int i=low; ilow && + // ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--) + // swap(dest, j, j-1); + // return; + // } + // + // // Recursively sort halves of dest into src + // int destLow = low; + // int destHigh = high; + // low += off; + // high += off; + // int mid = (low + high) >>> 1; + // mergeSort(dest, src, low, mid, -off); + // mergeSort(dest, src, mid, high, -off); + // + // // If list is already sorted, just copy from src to dest. This is an + // // optimization that results in faster sorts for nearly ordered lists. + // if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) { + // System.arraycopy(src, low, dest, destLow, length); + // return; + // } + // + // // Merge sorted halves (now in src) into dest + // for(int i = destLow, p = low, q = mid; i < destHigh; i++) { + // if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0) + // dest[i] = src[p++]; + // else + // dest[i] = src[q++]; + // } + // } + + /** + * Swaps x[a] with x[b]. + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static void swap(Object[] x, int a, int b) { + // Object t = x[a]; + // x[a] = x[b]; + // x[b] = t; + // } + + /** + * Sorts the specified array of objects according to the order induced by + * the specified comparator. All elements in the array must be + * mutually comparable by the specified comparator (that is, + * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} + * for any elements {@code e1} and {@code e2} in the array). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + *

Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. + * + *

The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techniques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. + * + * @param the class of the objects to be sorted + * @param a the array to be sorted + * @param c the comparator to determine the order of the array. A + * {@code null} value indicates that the elements' + * {@linkplain Comparable natural ordering} should be used. + * @throws ClassCastException if the array contains elements that are + * not mutually comparable using the specified comparator + * @throws IllegalArgumentException (optional) if the comparator is + * found to violate the {@link Comparator} contract + * + * @diffblue.limitedSupport + * TG-675 problems with generating tests with wildcard arguments + * TG-4181 incorrect generated tests for interface arguments + * TG-4302 - Will not work for comparators that don't implement a + * total order (if a < b and b < a OR a > b and b > a) + */ + // DIFFBLUE MODEL LIBRARY + // See sort(int[] a) + public static void sort(T[] a, Comparator c) { + // if (c == null) { + // sort(a); + // } else { + // if (LegacyMergeSort.userRequested) + // legacyMergeSort(a, c); + // else + // TimSort.sort(a, 0, a.length, c, null, 0, 0); + // } + if (c == null) { + sort(a); + return; + } + T[] oldArray = a.clone(); + boolean[] assigned = new boolean[a.length]; + for (int i = 0; i < a.length; ++i) { + int choice = CProver.nondetInt(); + CProver.assume(0 <= choice && choice < a.length && !assigned[choice]); + a[i] = oldArray[choice]; + assigned[choice] = true; + // Added test solves case if comparison always returns positive + if (i != 0) CProver.assume(c.compare(a[i - 1], a[i]) <= 0 || c.compare(a[i], a[i-1]) > 0); + } + } + + /** To be removed in a future release. */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static void legacyMergeSort(T[] a, Comparator c) { + // T[] aux = a.clone(); + // if (c==null) + // mergeSort(aux, a, 0, a.length, 0); + // else + // mergeSort(aux, a, 0, a.length, 0, c); + // } + + /** + * Sorts the specified range of the specified array of objects according + * to the order induced by the specified comparator. The range to be + * sorted extends from index {@code fromIndex}, inclusive, to index + * {@code toIndex}, exclusive. (If {@code fromIndex==toIndex}, the + * range to be sorted is empty.) All elements in the range must be + * mutually comparable by the specified comparator (that is, + * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} + * for any elements {@code e1} and {@code e2} in the range). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + *

Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. + * + *

The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techniques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. + * + * @param the class of the objects to be sorted + * @param a the array to be sorted + * @param fromIndex the index of the first element (inclusive) to be + * sorted + * @param toIndex the index of the last element (exclusive) to be sorted + * @param c the comparator to determine the order of the array. A + * {@code null} value indicates that the elements' + * {@linkplain Comparable natural ordering} should be used. + * @throws ClassCastException if the array contains elements that are not + * mutually comparable using the specified comparator. + * @throws IllegalArgumentException if {@code fromIndex > toIndex} or + * (optional) if the comparator is found to violate the + * {@link Comparator} contract + * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or + * {@code toIndex > a.length} + */ + public static void sort(T[] a, int fromIndex, int toIndex, + Comparator c) { + // if (c == null) { + // sort(a, fromIndex, toIndex); + // } else { + // rangeCheck(a.length, fromIndex, toIndex); + // if (LegacyMergeSort.userRequested) + // legacyMergeSort(a, fromIndex, toIndex, c); + // else + // TimSort.sort(a, fromIndex, toIndex, c, null, 0, 0); + // } + CProver.notModelled(); + } + + /** To be removed in a future release. */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static void legacyMergeSort(T[] a, int fromIndex, int toIndex, + // Comparator c) { + // T[] aux = copyOfRange(a, fromIndex, toIndex); + // if (c==null) + // mergeSort(aux, a, fromIndex, toIndex, -fromIndex); + // else + // mergeSort(aux, a, fromIndex, toIndex, -fromIndex, c); + // } + + /** + * Src is the source array that starts at index 0 + * Dest is the (possibly larger) array destination with a possible offset + * low is the index in dest to start sorting + * high is the end index in dest to end sorting + * off is the offset into src corresponding to low in dest + * To be removed in a future release. + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // @SuppressWarnings({"rawtypes", "unchecked"}) + // private static void mergeSort(Object[] src, + // Object[] dest, + // int low, int high, int off, + // Comparator c) { + // int length = high - low; + // + // // Insertion sort on smallest arrays + // if (length < INSERTIONSORT_THRESHOLD) { + // for (int i=low; ilow && c.compare(dest[j-1], dest[j])>0; j--) + // swap(dest, j, j-1); + // return; + // } + // + // // Recursively sort halves of dest into src + // int destLow = low; + // int destHigh = high; + // low += off; + // high += off; + // int mid = (low + high) >>> 1; + // mergeSort(dest, src, low, mid, -off, c); + // mergeSort(dest, src, mid, high, -off, c); + // + // // If list is already sorted, just copy from src to dest. This is an + // // optimization that results in faster sorts for nearly ordered lists. + // if (c.compare(src[mid-1], src[mid]) <= 0) { + // System.arraycopy(src, low, dest, destLow, length); + // return; + // } + // + // // Merge sorted halves (now in src) into dest + // for(int i = destLow, p = low, q = mid; i < destHigh; i++) { + // if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0) + // dest[i] = src[p++]; + // else + // dest[i] = src[q++]; + // } + // } + + // Parallel prefix + + /** + * Cumulates, in parallel, each element of the given array in place, + * using the supplied function. For example if the array initially + * holds {@code [2, 1, 0, 3]} and the operation performs addition, + * then upon return the array holds {@code [2, 3, 3, 6]}. + * Parallel prefix computation is usually more efficient than + * sequential loops for large arrays. + * + * @param the class of the objects in the array + * @param array the array, which is modified in-place by this method + * @param op a side-effect-free, associative function to perform the + * cumulation + * @throws NullPointerException if the specified array or function is null + * @since 1.8 + */ + public static void parallelPrefix(T[] array, BinaryOperator op) { + // Objects.requireNonNull(op); + // if (array.length > 0) + // new ArrayPrefixHelpers.CumulateTask<> + // (null, op, array, 0, array.length).invoke(); + CProver.notModelled(); + } + + /** + * Performs {@link #parallelPrefix(Object[], BinaryOperator)} + * for the given subrange of the array. + * + * @param the class of the objects in the array + * @param array the array + * @param fromIndex the index of the first element, inclusive + * @param toIndex the index of the last element, exclusive + * @param op a side-effect-free, associative function to perform the + * cumulation + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > array.length} + * @throws NullPointerException if the specified array or function is null + * @since 1.8 + */ + public static void parallelPrefix(T[] array, int fromIndex, + int toIndex, BinaryOperator op) { + // Objects.requireNonNull(op); + // rangeCheck(array.length, fromIndex, toIndex); + // if (fromIndex < toIndex) + // new ArrayPrefixHelpers.CumulateTask<> + // (null, op, array, fromIndex, toIndex).invoke(); + CProver.notModelled(); + } + + /** + * Cumulates, in parallel, each element of the given array in place, + * using the supplied function. For example if the array initially + * holds {@code [2, 1, 0, 3]} and the operation performs addition, + * then upon return the array holds {@code [2, 3, 3, 6]}. + * Parallel prefix computation is usually more efficient than + * sequential loops for large arrays. + * + * @param array the array, which is modified in-place by this method + * @param op a side-effect-free, associative function to perform the + * cumulation + * @throws NullPointerException if the specified array or function is null + * @since 1.8 + */ + public static void parallelPrefix(long[] array, LongBinaryOperator op) { + // Objects.requireNonNull(op); + // if (array.length > 0) + // new ArrayPrefixHelpers.LongCumulateTask + // (null, op, array, 0, array.length).invoke(); + CProver.notModelled(); + } + + /** + * Performs {@link #parallelPrefix(long[], LongBinaryOperator)} + * for the given subrange of the array. + * + * @param array the array + * @param fromIndex the index of the first element, inclusive + * @param toIndex the index of the last element, exclusive + * @param op a side-effect-free, associative function to perform the + * cumulation + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > array.length} + * @throws NullPointerException if the specified array or function is null + * @since 1.8 + */ + public static void parallelPrefix(long[] array, int fromIndex, + int toIndex, LongBinaryOperator op) { + // Objects.requireNonNull(op); + // rangeCheck(array.length, fromIndex, toIndex); + // if (fromIndex < toIndex) + // new ArrayPrefixHelpers.LongCumulateTask + // (null, op, array, fromIndex, toIndex).invoke(); + CProver.notModelled(); + } + + /** + * Cumulates, in parallel, each element of the given array in place, + * using the supplied function. For example if the array initially + * holds {@code [2.0, 1.0, 0.0, 3.0]} and the operation performs addition, + * then upon return the array holds {@code [2.0, 3.0, 3.0, 6.0]}. + * Parallel prefix computation is usually more efficient than + * sequential loops for large arrays. + * + *

Because floating-point operations may not be strictly associative, + * the returned result may not be identical to the value that would be + * obtained if the operation was performed sequentially. + * + * @param array the array, which is modified in-place by this method + * @param op a side-effect-free function to perform the cumulation + * @throws NullPointerException if the specified array or function is null + * @since 1.8 + */ + public static void parallelPrefix(double[] array, DoubleBinaryOperator op) { + // Objects.requireNonNull(op); + // if (array.length > 0) + // new ArrayPrefixHelpers.DoubleCumulateTask + // (null, op, array, 0, array.length).invoke(); + CProver.notModelled(); + } + + /** + * Performs {@link #parallelPrefix(double[], DoubleBinaryOperator)} + * for the given subrange of the array. + * + * @param array the array + * @param fromIndex the index of the first element, inclusive + * @param toIndex the index of the last element, exclusive + * @param op a side-effect-free, associative function to perform the + * cumulation + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > array.length} + * @throws NullPointerException if the specified array or function is null + * @since 1.8 + */ + public static void parallelPrefix(double[] array, int fromIndex, + int toIndex, DoubleBinaryOperator op) { + // Objects.requireNonNull(op); + // rangeCheck(array.length, fromIndex, toIndex); + // if (fromIndex < toIndex) + // new ArrayPrefixHelpers.DoubleCumulateTask + // (null, op, array, fromIndex, toIndex).invoke(); + CProver.notModelled(); + } + + /** + * Cumulates, in parallel, each element of the given array in place, + * using the supplied function. For example if the array initially + * holds {@code [2, 1, 0, 3]} and the operation performs addition, + * then upon return the array holds {@code [2, 3, 3, 6]}. + * Parallel prefix computation is usually more efficient than + * sequential loops for large arrays. + * + * @param array the array, which is modified in-place by this method + * @param op a side-effect-free, associative function to perform the + * cumulation + * @throws NullPointerException if the specified array or function is null + * @since 1.8 + */ + public static void parallelPrefix(int[] array, IntBinaryOperator op) { + // Objects.requireNonNull(op); + // if (array.length > 0) + // new ArrayPrefixHelpers.IntCumulateTask + // (null, op, array, 0, array.length).invoke(); + CProver.notModelled(); + } + + /** + * Performs {@link #parallelPrefix(int[], IntBinaryOperator)} + * for the given subrange of the array. + * + * @param array the array + * @param fromIndex the index of the first element, inclusive + * @param toIndex the index of the last element, exclusive + * @param op a side-effect-free, associative function to perform the + * cumulation + * @throws IllegalArgumentException if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0} or {@code toIndex > array.length} + * @throws NullPointerException if the specified array or function is null + * @since 1.8 + */ + public static void parallelPrefix(int[] array, int fromIndex, + int toIndex, IntBinaryOperator op) { + // Objects.requireNonNull(op); + // rangeCheck(array.length, fromIndex, toIndex); + // if (fromIndex < toIndex) + // new ArrayPrefixHelpers.IntCumulateTask + // (null, op, array, fromIndex, toIndex).invoke(); + CProver.notModelled(); + } + + // Searching + + /** + * Searches the specified array of longs for the specified value using the + * binary search algorithm. The array must be sorted (as + * by the {@link #sort(long[])} method) prior to making this call. If it + * is not sorted, the results are undefined. If the array contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element greater than the key, or a.length if all + * elements in the array are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @diffblue.noSupport + */ + public static int binarySearch(long[] a, long key) { + // return binarySearch0(a, 0, a.length, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Searches a range of + * the specified array of longs for the specified value using the + * binary search algorithm. + * The range must be sorted (as + * by the {@link #sort(long[], int, int)} method) + * prior to making this call. If it + * is not sorted, the results are undefined. If the range contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param fromIndex the index of the first element (inclusive) to be + * searched + * @param toIndex the index of the last element (exclusive) to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array + * within the specified range; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element in the range greater than the key, + * or toIndex if all + * elements in the range are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws IllegalArgumentException + * if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0 or toIndex > a.length} + * @since 1.6 + * @diffblue.noSupport + */ + public static int binarySearch(long[] a, int fromIndex, int toIndex, + long key) { + // rangeCheck(a.length, fromIndex, toIndex); + // return binarySearch0(a, fromIndex, toIndex, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // Like public version, but without range checks. + // private static int binarySearch0(long[] a, int fromIndex, int toIndex, + // long key) { + // int low = fromIndex; + // int high = toIndex - 1; + // + // while (low <= high) { + // int mid = (low + high) >>> 1; + // long midVal = a[mid]; + // + // if (midVal < key) + // low = mid + 1; + // else if (midVal > key) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found. + // } + + /** + * Searches the specified array of ints for the specified value using the + * binary search algorithm. The array must be sorted (as + * by the {@link #sort(int[])} method) prior to making this call. If it + * is not sorted, the results are undefined. If the array contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element greater than the key, or a.length if all + * elements in the array are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @diffblue.noSupport + */ + public static int binarySearch(int[] a, int key) { + // return binarySearch0(a, 0, a.length, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Searches a range of + * the specified array of ints for the specified value using the + * binary search algorithm. + * The range must be sorted (as + * by the {@link #sort(int[], int, int)} method) + * prior to making this call. If it + * is not sorted, the results are undefined. If the range contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param fromIndex the index of the first element (inclusive) to be + * searched + * @param toIndex the index of the last element (exclusive) to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array + * within the specified range; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element in the range greater than the key, + * or toIndex if all + * elements in the range are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws IllegalArgumentException + * if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0 or toIndex > a.length} + * @since 1.6 + * @diffblue.noSupport + */ + public static int binarySearch(int[] a, int fromIndex, int toIndex, + int key) { + // rangeCheck(a.length, fromIndex, toIndex); + // return binarySearch0(a, fromIndex, toIndex, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // Like public version, but without range checks. + // private static int binarySearch0(int[] a, int fromIndex, int toIndex, + // int key) { + // int low = fromIndex; + // int high = toIndex - 1; + // + // while (low <= high) { + // int mid = (low + high) >>> 1; + // int midVal = a[mid]; + // + // if (midVal < key) + // low = mid + 1; + // else if (midVal > key) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found. + // } + + /** + * Searches the specified array of shorts for the specified value using + * the binary search algorithm. The array must be sorted + * (as by the {@link #sort(short[])} method) prior to making this call. If + * it is not sorted, the results are undefined. If the array contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element greater than the key, or a.length if all + * elements in the array are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @diffblue.noSupport + */ + public static int binarySearch(short[] a, short key) { + // return binarySearch0(a, 0, a.length, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Searches a range of + * the specified array of shorts for the specified value using + * the binary search algorithm. + * The range must be sorted + * (as by the {@link #sort(short[], int, int)} method) + * prior to making this call. If + * it is not sorted, the results are undefined. If the range contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param fromIndex the index of the first element (inclusive) to be + * searched + * @param toIndex the index of the last element (exclusive) to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array + * within the specified range; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element in the range greater than the key, + * or toIndex if all + * elements in the range are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws IllegalArgumentException + * if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0 or toIndex > a.length} + * @since 1.6 + * @diffblue.noSupport + */ + public static int binarySearch(short[] a, int fromIndex, int toIndex, + short key) { + // rangeCheck(a.length, fromIndex, toIndex); + // return binarySearch0(a, fromIndex, toIndex, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // Like public version, but without range checks. + // private static int binarySearch0(short[] a, int fromIndex, int toIndex, + // short key) { + // int low = fromIndex; + // int high = toIndex - 1; + // + // while (low <= high) { + // int mid = (low + high) >>> 1; + // short midVal = a[mid]; + // + // if (midVal < key) + // low = mid + 1; + // else if (midVal > key) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found. + // } + + /** + * Searches the specified array of chars for the specified value using the + * binary search algorithm. The array must be sorted (as + * by the {@link #sort(char[])} method) prior to making this call. If it + * is not sorted, the results are undefined. If the array contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element greater than the key, or a.length if all + * elements in the array are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @diffblue.noSupport + */ + public static int binarySearch(char[] a, char key) { + // return binarySearch0(a, 0, a.length, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Searches a range of + * the specified array of chars for the specified value using the + * binary search algorithm. + * The range must be sorted (as + * by the {@link #sort(char[], int, int)} method) + * prior to making this call. If it + * is not sorted, the results are undefined. If the range contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param fromIndex the index of the first element (inclusive) to be + * searched + * @param toIndex the index of the last element (exclusive) to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array + * within the specified range; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element in the range greater than the key, + * or toIndex if all + * elements in the range are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws IllegalArgumentException + * if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0 or toIndex > a.length} + * @since 1.6 + * @diffblue.noSupport + */ + public static int binarySearch(char[] a, int fromIndex, int toIndex, + char key) { + // rangeCheck(a.length, fromIndex, toIndex); + // return binarySearch0(a, fromIndex, toIndex, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // Like public version, but without range checks. + // private static int binarySearch0(char[] a, int fromIndex, int toIndex, + // char key) { + // int low = fromIndex; + // int high = toIndex - 1; + // + // while (low <= high) { + // int mid = (low + high) >>> 1; + // char midVal = a[mid]; + // + // if (midVal < key) + // low = mid + 1; + // else if (midVal > key) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found. + // } + + /** + * Searches the specified array of bytes for the specified value using the + * binary search algorithm. The array must be sorted (as + * by the {@link #sort(byte[])} method) prior to making this call. If it + * is not sorted, the results are undefined. If the array contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element greater than the key, or a.length if all + * elements in the array are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @diffblue.noSupport + */ + public static int binarySearch(byte[] a, byte key) { + // return binarySearch0(a, 0, a.length, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Searches a range of + * the specified array of bytes for the specified value using the + * binary search algorithm. + * The range must be sorted (as + * by the {@link #sort(byte[], int, int)} method) + * prior to making this call. If it + * is not sorted, the results are undefined. If the range contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param fromIndex the index of the first element (inclusive) to be + * searched + * @param toIndex the index of the last element (exclusive) to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array + * within the specified range; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element in the range greater than the key, + * or toIndex if all + * elements in the range are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws IllegalArgumentException + * if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0 or toIndex > a.length} + * @since 1.6 + * @diffblue.noSupport + */ + public static int binarySearch(byte[] a, int fromIndex, int toIndex, + byte key) { + // rangeCheck(a.length, fromIndex, toIndex); + // return binarySearch0(a, fromIndex, toIndex, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // Like public version, but without range checks. + // private static int binarySearch0(byte[] a, int fromIndex, int toIndex, + // byte key) { + // int low = fromIndex; + // int high = toIndex - 1; + // + // while (low <= high) { + // int mid = (low + high) >>> 1; + // byte midVal = a[mid]; + // + // if (midVal < key) + // low = mid + 1; + // else if (midVal > key) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found. + // } + + /** + * Searches the specified array of doubles for the specified value using + * the binary search algorithm. The array must be sorted + * (as by the {@link #sort(double[])} method) prior to making this call. + * If it is not sorted, the results are undefined. If the array contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. This method considers all NaN values to be + * equivalent and equal. + * + * @param a the array to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element greater than the key, or a.length if all + * elements in the array are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @diffblue.noSupport + */ + public static int binarySearch(double[] a, double key) { + // return binarySearch0(a, 0, a.length, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Searches a range of + * the specified array of doubles for the specified value using + * the binary search algorithm. + * The range must be sorted + * (as by the {@link #sort(double[], int, int)} method) + * prior to making this call. + * If it is not sorted, the results are undefined. If the range contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. This method considers all NaN values to be + * equivalent and equal. + * + * @param a the array to be searched + * @param fromIndex the index of the first element (inclusive) to be + * searched + * @param toIndex the index of the last element (exclusive) to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array + * within the specified range; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element in the range greater than the key, + * or toIndex if all + * elements in the range are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws IllegalArgumentException + * if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0 or toIndex > a.length} + * @since 1.6 + * @diffblue.noSupport + */ + public static int binarySearch(double[] a, int fromIndex, int toIndex, + double key) { + // rangeCheck(a.length, fromIndex, toIndex); + // return binarySearch0(a, fromIndex, toIndex, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // Like public version, but without range checks. + // private static int binarySearch0(double[] a, int fromIndex, int toIndex, + // double key) { + // int low = fromIndex; + // int high = toIndex - 1; + // + // while (low <= high) { + // int mid = (low + high) >>> 1; + // double midVal = a[mid]; + // + // if (midVal < key) + // low = mid + 1; // Neither val is NaN, thisVal is smaller + // else if (midVal > key) + // high = mid - 1; // Neither val is NaN, thisVal is larger + // else { + // long midBits = Double.doubleToLongBits(midVal); + // long keyBits = Double.doubleToLongBits(key); + // if (midBits == keyBits) // Values are equal + // return mid; // Key found + // else if (midBits < keyBits) // (-0.0, 0.0) or (!NaN, NaN) + // low = mid + 1; + // else // (0.0, -0.0) or (NaN, !NaN) + // high = mid - 1; + // } + // } + // return -(low + 1); // key not found. + // } + + /** + * Searches the specified array of floats for the specified value using + * the binary search algorithm. The array must be sorted + * (as by the {@link #sort(float[])} method) prior to making this call. If + * it is not sorted, the results are undefined. If the array contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. This method considers all NaN values to be + * equivalent and equal. + * + * @param a the array to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element greater than the key, or a.length if all + * elements in the array are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @diffblue.noSupport + */ + public static int binarySearch(float[] a, float key) { + // return binarySearch0(a, 0, a.length, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Searches a range of + * the specified array of floats for the specified value using + * the binary search algorithm. + * The range must be sorted + * (as by the {@link #sort(float[], int, int)} method) + * prior to making this call. If + * it is not sorted, the results are undefined. If the range contains + * multiple elements with the specified value, there is no guarantee which + * one will be found. This method considers all NaN values to be + * equivalent and equal. + * + * @param a the array to be searched + * @param fromIndex the index of the first element (inclusive) to be + * searched + * @param toIndex the index of the last element (exclusive) to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array + * within the specified range; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element in the range greater than the key, + * or toIndex if all + * elements in the range are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws IllegalArgumentException + * if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0 or toIndex > a.length} + * @since 1.6 + * @diffblue.noSupport + */ + public static int binarySearch(float[] a, int fromIndex, int toIndex, + float key) { + // rangeCheck(a.length, fromIndex, toIndex); + // return binarySearch0(a, fromIndex, toIndex, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // Like public version, but without range checks. + // private static int binarySearch0(float[] a, int fromIndex, int toIndex, + // float key) { + // int low = fromIndex; + // int high = toIndex - 1; + // + // while (low <= high) { + // int mid = (low + high) >>> 1; + // float midVal = a[mid]; + // + // if (midVal < key) + // low = mid + 1; // Neither val is NaN, thisVal is smaller + // else if (midVal > key) + // high = mid - 1; // Neither val is NaN, thisVal is larger + // else { + // int midBits = Float.floatToIntBits(midVal); + // int keyBits = Float.floatToIntBits(key); + // if (midBits == keyBits) // Values are equal + // return mid; // Key found + // else if (midBits < keyBits) // (-0.0, 0.0) or (!NaN, NaN) + // low = mid + 1; + // else // (0.0, -0.0) or (NaN, !NaN) + // high = mid - 1; + // } + // } + // return -(low + 1); // key not found. + // } + + /** + * Searches the specified array for the specified object using the binary + * search algorithm. The array must be sorted into ascending order + * according to the + * {@linkplain Comparable natural ordering} + * of its elements (as by the + * {@link #sort(Object[])} method) prior to making this call. + * If it is not sorted, the results are undefined. + * (If the array contains elements that are not mutually comparable (for + * example, strings and integers), it cannot be sorted according + * to the natural ordering of its elements, hence results are undefined.) + * If the array contains multiple + * elements equal to the specified object, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element greater than the key, or a.length if all + * elements in the array are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws ClassCastException if the search key is not comparable to the + * elements of the array. + * @diffblue.noSupport + */ + public static int binarySearch(Object[] a, Object key) { + // return binarySearch0(a, 0, a.length, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Searches a range of + * the specified array for the specified object using the binary + * search algorithm. + * The range must be sorted into ascending order + * according to the + * {@linkplain Comparable natural ordering} + * of its elements (as by the + * {@link #sort(Object[], int, int)} method) prior to making this + * call. If it is not sorted, the results are undefined. + * (If the range contains elements that are not mutually comparable (for + * example, strings and integers), it cannot be sorted according + * to the natural ordering of its elements, hence results are undefined.) + * If the range contains multiple + * elements equal to the specified object, there is no guarantee which + * one will be found. + * + * @param a the array to be searched + * @param fromIndex the index of the first element (inclusive) to be + * searched + * @param toIndex the index of the last element (exclusive) to be searched + * @param key the value to be searched for + * @return index of the search key, if it is contained in the array + * within the specified range; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element in the range greater than the key, + * or toIndex if all + * elements in the range are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws ClassCastException if the search key is not comparable to the + * elements of the array within the specified range. + * @throws IllegalArgumentException + * if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0 or toIndex > a.length} + * @since 1.6 + * @diffblue.noSupport + */ + public static int binarySearch(Object[] a, int fromIndex, int toIndex, + Object key) { + // rangeCheck(a.length, fromIndex, toIndex); + // return binarySearch0(a, fromIndex, toIndex, key); + CProver.notModelled(); + return CProver.nondetInt(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // Like public version, but without range checks. + // private static int binarySearch0(Object[] a, int fromIndex, int toIndex, + // Object key) { + // int low = fromIndex; + // int high = toIndex - 1; + // + // while (low <= high) { + // int mid = (low + high) >>> 1; + // @SuppressWarnings("rawtypes") + // Comparable midVal = (Comparable)a[mid]; + // @SuppressWarnings("unchecked") + // int cmp = midVal.compareTo(key); + // + // if (cmp < 0) + // low = mid + 1; + // else if (cmp > 0) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found. + // } + + /** + * Searches the specified array for the specified object using the binary + * search algorithm. The array must be sorted into ascending order + * according to the specified comparator (as by the + * {@link #sort(Object[], Comparator) sort(T[], Comparator)} + * method) prior to making this call. If it is + * not sorted, the results are undefined. + * If the array contains multiple + * elements equal to the specified object, there is no guarantee which one + * will be found. + * + * @param the class of the objects in the array + * @param a the array to be searched + * @param key the value to be searched for + * @param c the comparator by which the array is ordered. A + * null value indicates that the elements' + * {@linkplain Comparable natural ordering} should be used. + * @return index of the search key, if it is contained in the array; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element greater than the key, or a.length if all + * elements in the array are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws ClassCastException if the array contains elements that are not + * mutually comparable using the specified comparator, + * or the search key is not comparable to the + * elements of the array using this comparator. + * @diffblue.noSupport + */ + public static int binarySearch(T[] a, T key, Comparator c) { + // return binarySearch0(a, 0, a.length, key, c); + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Searches a range of + * the specified array for the specified object using the binary + * search algorithm. + * The range must be sorted into ascending order + * according to the specified comparator (as by the + * {@link #sort(Object[], int, int, Comparator) + * sort(T[], int, int, Comparator)} + * method) prior to making this call. + * If it is not sorted, the results are undefined. + * If the range contains multiple elements equal to the specified object, + * there is no guarantee which one will be found. + * + * @param the class of the objects in the array + * @param a the array to be searched + * @param fromIndex the index of the first element (inclusive) to be + * searched + * @param toIndex the index of the last element (exclusive) to be searched + * @param key the value to be searched for + * @param c the comparator by which the array is ordered. A + * null value indicates that the elements' + * {@linkplain Comparable natural ordering} should be used. + * @return index of the search key, if it is contained in the array + * within the specified range; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the array: the index of the first + * element in the range greater than the key, + * or toIndex if all + * elements in the range are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws ClassCastException if the range contains elements that are not + * mutually comparable using the specified comparator, + * or the search key is not comparable to the + * elements in the range using this comparator. + * @throws IllegalArgumentException + * if {@code fromIndex > toIndex} + * @throws ArrayIndexOutOfBoundsException + * if {@code fromIndex < 0 or toIndex > a.length} + * @since 1.6 + * @diffblue.noSupport + */ + public static int binarySearch(T[] a, int fromIndex, int toIndex, + T key, Comparator c) { + // rangeCheck(a.length, fromIndex, toIndex); + // return binarySearch0(a, fromIndex, toIndex, key, c); + CProver.notModelled(); + return CProver.nondetInt(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // Like public version, but without range checks. + // private static int binarySearch0(T[] a, int fromIndex, int toIndex, + // T key, Comparator c) { + // if (c == null) { + // return binarySearch0(a, fromIndex, toIndex, key); + // } + // int low = fromIndex; + // int high = toIndex - 1; + // + // while (low <= high) { + // int mid = (low + high) >>> 1; + // T midVal = a[mid]; + // int cmp = c.compare(midVal, key); + // if (cmp < 0) + // low = mid + 1; + // else if (cmp > 0) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found. + // } + + // Equality Testing + + /** + * Returns true if the two specified arrays of longs are + * equal to one another. Two arrays are considered equal if both + * arrays contain the same number of elements, and all corresponding pairs + * of elements in the two arrays are equal. In other words, two arrays + * are equal if they contain the same elements in the same order. Also, + * two array references are considered equal if both are null.

+ * + * @param a one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * + * @diffblue.fullSupport + */ + public static boolean equals(long[] a, long[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; itrue if the two specified arrays of ints are + * equal to one another. Two arrays are considered equal if both + * arrays contain the same number of elements, and all corresponding pairs + * of elements in the two arrays are equal. In other words, two arrays + * are equal if they contain the same elements in the same order. Also, + * two array references are considered equal if both are null.

+ * + * @param a one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * + * @diffblue.fullSupport + */ + public static boolean equals(int[] a, int[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; itrue if the two specified arrays of shorts are + * equal to one another. Two arrays are considered equal if both + * arrays contain the same number of elements, and all corresponding pairs + * of elements in the two arrays are equal. In other words, two arrays + * are equal if they contain the same elements in the same order. Also, + * two array references are considered equal if both are null.

+ * + * @param a one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * + * @diffblue.fullSupport + */ + public static boolean equals(short[] a, short a2[]) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; itrue if the two specified arrays of chars are + * equal to one another. Two arrays are considered equal if both + * arrays contain the same number of elements, and all corresponding pairs + * of elements in the two arrays are equal. In other words, two arrays + * are equal if they contain the same elements in the same order. Also, + * two array references are considered equal if both are null.

+ * + * @param a one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * + * @diffblue.limitedSupport + * TG-4076 Non-deterministically generated char arrays can be incorrect + */ + public static boolean equals(char[] a, char[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; itrue if the two specified arrays of bytes are + * equal to one another. Two arrays are considered equal if both + * arrays contain the same number of elements, and all corresponding pairs + * of elements in the two arrays are equal. In other words, two arrays + * are equal if they contain the same elements in the same order. Also, + * two array references are considered equal if both are null.

+ * + * @param a one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * + * @diffblue.fullSupport + */ + public static boolean equals(byte[] a, byte[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; itrue if the two specified arrays of booleans are + * equal to one another. Two arrays are considered equal if both + * arrays contain the same number of elements, and all corresponding pairs + * of elements in the two arrays are equal. In other words, two arrays + * are equal if they contain the same elements in the same order. Also, + * two array references are considered equal if both are null.

+ * + * @param a one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * + * @diffblue.fullSupport + */ + public static boolean equals(boolean[] a, boolean[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; itrue if the two specified arrays of doubles are + * equal to one another. Two arrays are considered equal if both + * arrays contain the same number of elements, and all corresponding pairs + * of elements in the two arrays are equal. In other words, two arrays + * are equal if they contain the same elements in the same order. Also, + * two array references are considered equal if both are null.

+ * + * Two doubles d1 and d2 are considered equal if: + *

    new Double(d1).equals(new Double(d2))
+ * (Unlike the == operator, this method considers + * NaN equals to itself, and 0.0d unequal to -0.0d.) + * + * @param a one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * @see Double#equals(Object) + * + * @diffblue.fullSupport + */ + public static boolean equals(double[] a, double[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; itrue if the two specified arrays of floats are + * equal to one another. Two arrays are considered equal if both + * arrays contain the same number of elements, and all corresponding pairs + * of elements in the two arrays are equal. In other words, two arrays + * are equal if they contain the same elements in the same order. Also, + * two array references are considered equal if both are null.

+ * + * Two floats f1 and f2 are considered equal if: + *

    new Float(f1).equals(new Float(f2))
+ * (Unlike the == operator, this method considers + * NaN equals to itself, and 0.0f unequal to -0.0f.) + * + * @param a one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * @see Float#equals(Object) + * + * @diffblue.fullSupport + */ + public static boolean equals(float[] a, float[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; itrue if the two specified arrays of Objects are + * equal to one another. The two arrays are considered equal if + * both arrays contain the same number of elements, and all corresponding + * pairs of elements in the two arrays are equal. Two objects e1 + * and e2 are considered equal if (e1==null ? e2==null + * : e1.equals(e2)). In other words, the two arrays are equal if + * they contain the same elements in the same order. Also, two array + * references are considered equal if both are null.

+ * + * @param a one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * + * @diffblue.fullSupport + */ + public static boolean equals(Object[] a, Object[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; ifromIndex, inclusive, to index + * toIndex, exclusive. (If fromIndex==toIndex, the + * range to be filled is empty.) + * + * @param a the array to be filled + * @param fromIndex the index of the first element (inclusive) to be + * filled with the specified value + * @param toIndex the index of the last element (exclusive) to be + * filled with the specified value + * @param val the value to be stored in all elements of the array + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or + * toIndex > a.length + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(long[] a, int fromIndex, int toIndex, long val) { + rangeCheck(a.length, fromIndex, toIndex); + for (int i = fromIndex; i < toIndex; i++) + a[i] = val; + } + + /** + * Assigns the specified int value to each element of the specified array + * of ints. + * + * @param a the array to be filled + * @param val the value to be stored in all elements of the array + * @diffblue.fullSupport + */ + public static void fill(int[] a, int val) { + for (int i = 0, len = a.length; i < len; i++) + a[i] = val; + } + + /** + * Assigns the specified int value to each element of the specified + * range of the specified array of ints. The range to be filled + * extends from index fromIndex, inclusive, to index + * toIndex, exclusive. (If fromIndex==toIndex, the + * range to be filled is empty.) + * + * @param a the array to be filled + * @param fromIndex the index of the first element (inclusive) to be + * filled with the specified value + * @param toIndex the index of the last element (exclusive) to be + * filled with the specified value + * @param val the value to be stored in all elements of the array + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or + * toIndex > a.length + * @diffblue.fullSupport + */ + public static void fill(int[] a, int fromIndex, int toIndex, int val) { + rangeCheck(a.length, fromIndex, toIndex); + for (int i = fromIndex; i < toIndex; i++) + a[i] = val; + } + + /** + * Assigns the specified short value to each element of the specified array + * of shorts. + * + * @param a the array to be filled + * @param val the value to be stored in all elements of the array + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(short[] a, short val) { + for (int i = 0, len = a.length; i < len; i++) + a[i] = val; + } + + /** + * Assigns the specified short value to each element of the specified + * range of the specified array of shorts. The range to be filled + * extends from index fromIndex, inclusive, to index + * toIndex, exclusive. (If fromIndex==toIndex, the + * range to be filled is empty.) + * + * @param a the array to be filled + * @param fromIndex the index of the first element (inclusive) to be + * filled with the specified value + * @param toIndex the index of the last element (exclusive) to be + * filled with the specified value + * @param val the value to be stored in all elements of the array + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or + * toIndex > a.length + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(short[] a, int fromIndex, int toIndex, short val) { + rangeCheck(a.length, fromIndex, toIndex); + for (int i = fromIndex; i < toIndex; i++) + a[i] = val; + } + + /** + * Assigns the specified char value to each element of the specified array + * of chars. + * + * @param a the array to be filled + * @param val the value to be stored in all elements of the array + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(char[] a, char val) { + for (int i = 0, len = a.length; i < len; i++) + a[i] = val; + } + + /** + * Assigns the specified char value to each element of the specified + * range of the specified array of chars. The range to be filled + * extends from index fromIndex, inclusive, to index + * toIndex, exclusive. (If fromIndex==toIndex, the + * range to be filled is empty.) + * + * @param a the array to be filled + * @param fromIndex the index of the first element (inclusive) to be + * filled with the specified value + * @param toIndex the index of the last element (exclusive) to be + * filled with the specified value + * @param val the value to be stored in all elements of the array + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or + * toIndex > a.length + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(char[] a, int fromIndex, int toIndex, char val) { + rangeCheck(a.length, fromIndex, toIndex); + for (int i = fromIndex; i < toIndex; i++) + a[i] = val; + } + + /** + * Assigns the specified byte value to each element of the specified array + * of bytes. + * + * @param a the array to be filled + * @param val the value to be stored in all elements of the array + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(byte[] a, byte val) { + for (int i = 0, len = a.length; i < len; i++) + a[i] = val; + } + + /** + * Assigns the specified byte value to each element of the specified + * range of the specified array of bytes. The range to be filled + * extends from index fromIndex, inclusive, to index + * toIndex, exclusive. (If fromIndex==toIndex, the + * range to be filled is empty.) + * + * @param a the array to be filled + * @param fromIndex the index of the first element (inclusive) to be + * filled with the specified value + * @param toIndex the index of the last element (exclusive) to be + * filled with the specified value + * @param val the value to be stored in all elements of the array + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or + * toIndex > a.length + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(byte[] a, int fromIndex, int toIndex, byte val) { + rangeCheck(a.length, fromIndex, toIndex); + for (int i = fromIndex; i < toIndex; i++) + a[i] = val; + } + + /** + * Assigns the specified boolean value to each element of the specified + * array of booleans. + * + * @param a the array to be filled + * @param val the value to be stored in all elements of the array + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(boolean[] a, boolean val) { + for (int i = 0, len = a.length; i < len; i++) + a[i] = val; + } + + /** + * Assigns the specified boolean value to each element of the specified + * range of the specified array of booleans. The range to be filled + * extends from index fromIndex, inclusive, to index + * toIndex, exclusive. (If fromIndex==toIndex, the + * range to be filled is empty.) + * + * @param a the array to be filled + * @param fromIndex the index of the first element (inclusive) to be + * filled with the specified value + * @param toIndex the index of the last element (exclusive) to be + * filled with the specified value + * @param val the value to be stored in all elements of the array + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or + * toIndex > a.length + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(boolean[] a, int fromIndex, int toIndex, + boolean val) { + rangeCheck(a.length, fromIndex, toIndex); + for (int i = fromIndex; i < toIndex; i++) + a[i] = val; + } + + /** + * Assigns the specified double value to each element of the specified + * array of doubles. + * + * @param a the array to be filled + * @param val the value to be stored in all elements of the array + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(double[] a, double val) { + for (int i = 0, len = a.length; i < len; i++) + a[i] = val; + } + + /** + * Assigns the specified double value to each element of the specified + * range of the specified array of doubles. The range to be filled + * extends from index fromIndex, inclusive, to index + * toIndex, exclusive. (If fromIndex==toIndex, the + * range to be filled is empty.) + * + * @param a the array to be filled + * @param fromIndex the index of the first element (inclusive) to be + * filled with the specified value + * @param toIndex the index of the last element (exclusive) to be + * filled with the specified value + * @param val the value to be stored in all elements of the array + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or + * toIndex > a.length + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(double[] a, int fromIndex, int toIndex,double val){ + rangeCheck(a.length, fromIndex, toIndex); + for (int i = fromIndex; i < toIndex; i++) + a[i] = val; + } + + /** + * Assigns the specified float value to each element of the specified array + * of floats. + * + * @param a the array to be filled + * @param val the value to be stored in all elements of the array + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(float[] a, float val) { + for (int i = 0, len = a.length; i < len; i++) + a[i] = val; + } + + /** + * Assigns the specified float value to each element of the specified + * range of the specified array of floats. The range to be filled + * extends from index fromIndex, inclusive, to index + * toIndex, exclusive. (If fromIndex==toIndex, the + * range to be filled is empty.) + * + * @param a the array to be filled + * @param fromIndex the index of the first element (inclusive) to be + * filled with the specified value + * @param toIndex the index of the last element (exclusive) to be + * filled with the specified value + * @param val the value to be stored in all elements of the array + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or + * toIndex > a.length + * @diffblue.untested + * @diffblue.fullSupport + */ + public static void fill(float[] a, int fromIndex, int toIndex, float val) { + rangeCheck(a.length, fromIndex, toIndex); + for (int i = fromIndex; i < toIndex; i++) + a[i] = val; + } + + /** + * Assigns the specified Object reference to each element of the specified + * array of Objects. + * + * @param a the array to be filled + * @param val the value to be stored in all elements of the array + * @throws ArrayStoreException if the specified value is not of a + * runtime type that can be stored in the specified array + * @diffblue.fullSupport + */ + public static void fill(Object[] a, Object val) { + for (int i = 0, len = a.length; i < len; i++) + a[i] = val; + } + + /** + * Assigns the specified Object reference to each element of the specified + * range of the specified array of Objects. The range to be filled + * extends from index fromIndex, inclusive, to index + * toIndex, exclusive. (If fromIndex==toIndex, the + * range to be filled is empty.) + * + * @param a the array to be filled + * @param fromIndex the index of the first element (inclusive) to be + * filled with the specified value + * @param toIndex the index of the last element (exclusive) to be + * filled with the specified value + * @param val the value to be stored in all elements of the array + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or + * toIndex > a.length + * @throws ArrayStoreException if the specified value is not of a + * runtime type that can be stored in the specified array + * @diffblue.fullSupport + */ + public static void fill(Object[] a, int fromIndex, int toIndex, Object val) { + rangeCheck(a.length, fromIndex, toIndex); + for (int i = fromIndex; i < toIndex; i++) + a[i] = val; + } + + // Cloning + + /** + * Copies the specified array, truncating or padding with nulls (if necessary) + * so the copy has the specified length. For all indices that are + * valid in both the original array and the copy, the two arrays will + * contain identical values. For any indices that are valid in the + * copy but not the original, the copy will contain null. + * Such indices will exist if and only if the specified length + * is greater than that of the original array. + * The resulting array is of exactly the same class as the original array. + * + * @param the class of the objects in the array + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @return a copy of the original array, truncated or padded with nulls + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.fullSupport + */ + // @SuppressWarnings("unchecked") + // (the original JDK needed an unchecked cast here; we use the intrinsic + // CProver.createArrayWithType instead) + public static T[] copyOf(T[] original, int newLength) { + // The real JDK uses the reflective variant of copyOf, which we don't + // currently understand, but this restricted case where the user + // provides an example array of the correct type works. + // + // Original code: + // return (T[]) copyOf(original, newLength, original.getClass()); + + if(newLength < 0) + throw new NegativeArraySizeException(); + + T[] result = CProver.createArrayWithType(newLength, original); + for(int i = 0; i < newLength; ++i) { + result[i] = i < original.length ? original[i] : null; + } + return result; + } + + /** + * Copies the specified array, truncating or padding with nulls (if necessary) + * so the copy has the specified length. For all indices that are + * valid in both the original array and the copy, the two arrays will + * contain identical values. For any indices that are valid in the + * copy but not the original, the copy will contain null. + * Such indices will exist if and only if the specified length + * is greater than that of the original array. + * The resulting array is of the class newType. + * + * @param the class of the objects in the original array + * @param the class of the objects in the returned array + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @param newType the class of the copy to be returned + * @return a copy of the original array, truncated or padded with nulls + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @throws ArrayStoreException if an element copied from + * original is not of a runtime type that can be stored in + * an array of class newType + * @since 1.6 + * @diffblue.noSupport + */ + public static T[] copyOf(U[] original, int newLength, Class newType) { + // @SuppressWarnings("unchecked") + // T[] copy = ((Object)newType == (Object)Object[].class) + // ? (T[]) new Object[newLength] + // : (T[]) Array.newInstance(newType.getComponentType(), newLength); + // System.arraycopy(original, 0, copy, 0, + // Math.min(original.length, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified array, truncating or padding with zeros (if necessary) + * so the copy has the specified length. For all indices that are + * valid in both the original array and the copy, the two arrays will + * contain identical values. For any indices that are valid in the + * copy but not the original, the copy will contain (byte)0. + * Such indices will exist if and only if the specified length + * is greater than that of the original array. + * + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @return a copy of the original array, truncated or padded with zeros + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static byte[] copyOf(byte[] original, int newLength) { + // byte[] copy = new byte[newLength]; + // System.arraycopy(original, 0, copy, 0, + // Math.min(original.length, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified array, truncating or padding with zeros (if necessary) + * so the copy has the specified length. For all indices that are + * valid in both the original array and the copy, the two arrays will + * contain identical values. For any indices that are valid in the + * copy but not the original, the copy will contain (short)0. + * Such indices will exist if and only if the specified length + * is greater than that of the original array. + * + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @return a copy of the original array, truncated or padded with zeros + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static short[] copyOf(short[] original, int newLength) { + // short[] copy = new short[newLength]; + // System.arraycopy(original, 0, copy, 0, + // Math.min(original.length, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified array, truncating or padding with zeros (if necessary) + * so the copy has the specified length. For all indices that are + * valid in both the original array and the copy, the two arrays will + * contain identical values. For any indices that are valid in the + * copy but not the original, the copy will contain 0. + * Such indices will exist if and only if the specified length + * is greater than that of the original array. + * + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @return a copy of the original array, truncated or padded with zeros + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static int[] copyOf(int[] original, int newLength) { + // int[] copy = new int[newLength]; + // System.arraycopy(original, 0, copy, 0, + // Math.min(original.length, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified array, truncating or padding with zeros (if necessary) + * so the copy has the specified length. For all indices that are + * valid in both the original array and the copy, the two arrays will + * contain identical values. For any indices that are valid in the + * copy but not the original, the copy will contain 0L. + * Such indices will exist if and only if the specified length + * is greater than that of the original array. + * + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @return a copy of the original array, truncated or padded with zeros + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static long[] copyOf(long[] original, int newLength) { + // long[] copy = new long[newLength]; + // System.arraycopy(original, 0, copy, 0, + // Math.min(original.length, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified array, truncating or padding with null characters (if necessary) + * so the copy has the specified length. For all indices that are valid + * in both the original array and the copy, the two arrays will contain + * identical values. For any indices that are valid in the copy but not + * the original, the copy will contain '\\u000'. Such indices + * will exist if and only if the specified length is greater than that of + * the original array. + * + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @return a copy of the original array, truncated or padded with null characters + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static char[] copyOf(char[] original, int newLength) { + // char[] copy = new char[newLength]; + // System.arraycopy(original, 0, copy, 0, + // Math.min(original.length, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified array, truncating or padding with zeros (if necessary) + * so the copy has the specified length. For all indices that are + * valid in both the original array and the copy, the two arrays will + * contain identical values. For any indices that are valid in the + * copy but not the original, the copy will contain 0f. + * Such indices will exist if and only if the specified length + * is greater than that of the original array. + * + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @return a copy of the original array, truncated or padded with zeros + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static float[] copyOf(float[] original, int newLength) { + // float[] copy = new float[newLength]; + // System.arraycopy(original, 0, copy, 0, + // Math.min(original.length, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified array, truncating or padding with zeros (if necessary) + * so the copy has the specified length. For all indices that are + * valid in both the original array and the copy, the two arrays will + * contain identical values. For any indices that are valid in the + * copy but not the original, the copy will contain 0d. + * Such indices will exist if and only if the specified length + * is greater than that of the original array. + * + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @return a copy of the original array, truncated or padded with zeros + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static double[] copyOf(double[] original, int newLength) { + // double[] copy = new double[newLength]; + // System.arraycopy(original, 0, copy, 0, + // Math.min(original.length, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified array, truncating or padding with false (if necessary) + * so the copy has the specified length. For all indices that are + * valid in both the original array and the copy, the two arrays will + * contain identical values. For any indices that are valid in the + * copy but not the original, the copy will contain false. + * Such indices will exist if and only if the specified length + * is greater than that of the original array. + * + * @param original the array to be copied + * @param newLength the length of the copy to be returned + * @return a copy of the original array, truncated or padded with false elements + * to obtain the specified length + * @throws NegativeArraySizeException if newLength is negative + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static boolean[] copyOf(boolean[] original, int newLength) { + // boolean[] copy = new boolean[newLength]; + // System.arraycopy(original, 0, copy, 0, + // Math.min(original.length, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * null is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + *

+ * The resulting array is of exactly the same class as the original array. + * + * @param the class of the objects in the array + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @return a new array containing the specified range from the original array, + * truncated or padded with nulls to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static T[] copyOfRange(T[] original, int from, int to) { + // return copyOfRange(original, from, to, (Class) original.getClass()); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * null is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + * The resulting array is of the class newType. + * + * @param the class of the objects in the original array + * @param the class of the objects in the returned array + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @param newType the class of the copy to be returned + * @return a new array containing the specified range from the original array, + * truncated or padded with nulls to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @throws ArrayStoreException if an element copied from + * original is not of a runtime type that can be stored in + * an array of class newType. + * @since 1.6 + * @diffblue.noSupport + */ + public static T[] copyOfRange(U[] original, int from, int to, Class newType) { + // int newLength = to - from; + // if (newLength < 0) + // throw new IllegalArgumentException(from + " > " + to); + // @SuppressWarnings("unchecked") + // T[] copy = ((Object)newType == (Object)Object[].class) + // ? (T[]) new Object[newLength] + // : (T[]) Array.newInstance(newType.getComponentType(), newLength); + // System.arraycopy(original, from, copy, 0, + // Math.min(original.length - from, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * (byte)0 is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + * + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @return a new array containing the specified range from the original array, + * truncated or padded with zeros to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static byte[] copyOfRange(byte[] original, int from, int to) { + // int newLength = to - from; + // if (newLength < 0) + // throw new IllegalArgumentException(from + " > " + to); + // byte[] copy = new byte[newLength]; + // System.arraycopy(original, from, copy, 0, + // Math.min(original.length - from, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * (short)0 is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + * + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @return a new array containing the specified range from the original array, + * truncated or padded with zeros to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static short[] copyOfRange(short[] original, int from, int to) { + // int newLength = to - from; + // if (newLength < 0) + // throw new IllegalArgumentException(from + " > " + to); + // short[] copy = new short[newLength]; + // System.arraycopy(original, from, copy, 0, + // Math.min(original.length - from, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * 0 is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + * + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @return a new array containing the specified range from the original array, + * truncated or padded with zeros to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static int[] copyOfRange(int[] original, int from, int to) { + // int newLength = to - from; + // if (newLength < 0) + // throw new IllegalArgumentException(from + " > " + to); + // int[] copy = new int[newLength]; + // System.arraycopy(original, from, copy, 0, + // Math.min(original.length - from, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * 0L is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + * + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @return a new array containing the specified range from the original array, + * truncated or padded with zeros to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static long[] copyOfRange(long[] original, int from, int to) { + // int newLength = to - from; + // if (newLength < 0) + // throw new IllegalArgumentException(from + " > " + to); + // long[] copy = new long[newLength]; + // System.arraycopy(original, from, copy, 0, + // Math.min(original.length - from, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * '\\u000' is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + * + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @return a new array containing the specified range from the original array, + * truncated or padded with null characters to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static char[] copyOfRange(char[] original, int from, int to) { + // int newLength = to - from; + // if (newLength < 0) + // throw new IllegalArgumentException(from + " > " + to); + // char[] copy = new char[newLength]; + // System.arraycopy(original, from, copy, 0, + // Math.min(original.length - from, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * 0f is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + * + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @return a new array containing the specified range from the original array, + * truncated or padded with zeros to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static float[] copyOfRange(float[] original, int from, int to) { + // int newLength = to - from; + // if (newLength < 0) + // throw new IllegalArgumentException(from + " > " + to); + // float[] copy = new float[newLength]; + // System.arraycopy(original, from, copy, 0, + // Math.min(original.length - from, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * 0d is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + * + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @return a new array containing the specified range from the original array, + * truncated or padded with zeros to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static double[] copyOfRange(double[] original, int from, int to) { + // int newLength = to - from; + // if (newLength < 0) + // throw new IllegalArgumentException(from + " > " + to); + // double[] copy = new double[newLength]; + // System.arraycopy(original, from, copy, 0, + // Math.min(original.length - from, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Copies the specified range of the specified array into a new array. + * The initial index of the range (from) must lie between zero + * and original.length, inclusive. The value at + * original[from] is placed into the initial element of the copy + * (unless from == original.length or from == to). + * Values from subsequent elements in the original array are placed into + * subsequent elements in the copy. The final index of the range + * (to), which must be greater than or equal to from, + * may be greater than original.length, in which case + * false is placed in all elements of the copy whose index is + * greater than or equal to original.length - from. The length + * of the returned array will be to - from. + * + * @param original the array from which a range is to be copied + * @param from the initial index of the range to be copied, inclusive + * @param to the final index of the range to be copied, exclusive. + * (This index may lie outside the array.) + * @return a new array containing the specified range from the original array, + * truncated or padded with false elements to obtain the required length + * @throws ArrayIndexOutOfBoundsException if {@code from < 0} + * or {@code from > original.length} + * @throws IllegalArgumentException if from > to + * @throws NullPointerException if original is null + * @since 1.6 + * @diffblue.noSupport + */ + public static boolean[] copyOfRange(boolean[] original, int from, int to) { + // int newLength = to - from; + // if (newLength < 0) + // throw new IllegalArgumentException(from + " > " + to); + // boolean[] copy = new boolean[newLength]; + // System.arraycopy(original, from, copy, 0, + // Math.min(original.length - from, newLength)); + // return copy; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + // Misc + + /** + * Returns a fixed-size list backed by the specified array. (Changes to + * the returned list "write through" to the array.) This method acts + * as bridge between array-based and collection-based APIs, in + * combination with {@link Collection#toArray}. The returned list is + * serializable and implements {@link RandomAccess}. + * + *

This method also provides a convenient way to create a fixed-size + * list initialized to contain several elements: + *

+     *     List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
+     * 
+ * + * @param the class of the objects in the array + * @param a the array by which the list will be backed + * @return a list view of the specified array + * + * @diffblue.limitedSupport + * @diffblue.untested + * This implementation does not currently support, + * listIterator(), spliterator(), containsAll(), forEach(), + * replaceAll() or sort() on the returned List. + * iterator() on the return Arrays$ArrayList from Arrays.asList() is limited + * to approximately eight elements for test generation. + */ + @SafeVarargs + @SuppressWarnings("varargs") + public static List asList(T... a) { + return new ArrayList<>(a); + } + + /** + * @serial include + */ + private static class ArrayList extends AbstractList + implements RandomAccess, java.io.Serializable + { + // DIFFBLUE MODEL LIBRARY + // Not used in the model, so can be commented out. + // private static final long serialVersionUID = -2764017481108945198L; + private final E[] a; + + ArrayList(E[] array) { + // a = Objects.requireNonNull(array); + if (array == null) { + throw new NullPointerException(); + } + a = array; + } + + @Override + public int size() { + return a.length; + } + + @Override + public Object[] toArray() { + return a.clone(); + } + + /** + * @diffblue.limitedSupport + * DIFFBLUE MODEL LIBRARY + * This behaves like the real JDK method, except that an ArrayStoreException + * won't be raised if you pass in an array that can't store the actual + * elements held in this container. + */ + @Override + @SuppressWarnings("unchecked") + public T[] toArray(T[] a) { + // int size = size(); + // if (a.length < size) + // return Arrays.copyOf(this.a, size, + // (Class) a.getClass()); + // System.arraycopy(this.a, 0, a, 0, size); + // if (a.length > size) + // a[size] = null; + // return a; + if (a.length < size()) { + // DIFFBLUE MODEL LIBRARY + // Object.getClass() is currently not modelled, so we need to use + // Object[] rather than the runtime type of a. + T[] newArray = CProver.createArrayWithType(size(), a); + for (int i = 0; i < size(); i++) { + newArray[i] = (T)this.a[i]; + } + return newArray; + } + for (int i = 0; i < size(); i++) { + a[i] = (T) this.a[i]; + } + if (a.length > size()) { + a[size()] = null; + } + return a; + } + + @Override + public E get(int index) { + return a[index]; + } + + @Override + public E set(int index, E element) { + E oldValue = a[index]; + a[index] = element; + return oldValue; + } + + @Override + public int indexOf(Object o) { + E[] a = this.a; + if (o == null) { + for (int i = 0; i < a.length; i++) + if (a[i] == null) + return i; + } else { + for (int i = 0; i < a.length; i++) + if (o.equals(a[i])) + return i; + } + return -1; + } + + @Override + public boolean contains(Object o) { + return indexOf(o) != -1; + } + + // This is not in the original jdk and overrides the method + // in AbstractList. + @Override + public void clear() { + if (size() > 0) { + throw new UnsupportedOperationException(); + } + } + + // This is not in the original jdk and overrides the method + // in AbstractCollection. + @Override + public boolean isEmpty() { + return size() == 0; + } + + // This is not in the original jdk and overrides the method + // in AbstractList. + @Override + public int lastIndexOf(Object o) { + if (o == null) { + for (int i = size()-1; i >= 0; i--) + if (a[i]==null) + return i; + } else { + for (int i = size()-1; i >= 0; i--) + if (o.equals(a[i])) + return i; + } + return -1; + } + + @Override + public Spliterator spliterator() { + return Spliterators.spliterator(a, Spliterator.ORDERED); + } + + @Override + public void forEach(Consumer action) { + // Objects.requireNonNull(action); + // for (E e : a) { + // action.accept(e); + // } + CProver.notModelled(); + } + + @Override + public void replaceAll(UnaryOperator operator) { + // Objects.requireNonNull(operator); + // E[] a = this.a; + // for (int i = 0; i < a.length; i++) { + // a[i] = operator.apply(a[i]); + // } + CProver.notModelled(); + } + + @Override + public void sort(Comparator c) { + // Arrays.sort(a, c); + CProver.notModelled(); + } + + // DIFFBLUE MODEL LIBRARY + // This method is called by CBMC just after nondeterministic object + // creation, i.e. the constraints that it specifies are only enforced at + // that time and do not have to hold globally. + // We generally want to make sure that all necessary invariants of the class + // are satisfied, and potentially restrict some fields to speed up test + // generation. + @org.cprover.MustNotThrow + protected void cproverNondetInitialize() { + CProver.assume(a != null); + // The number of calls to add in the generated test is equal to size. + // Each call to add increments the modCount variable by 1. + CProver.assume(modCount == size()); + } + + } + + /** + * Returns a hash code based on the contents of the specified array. + * For any two long arrays a and b + * such that Arrays.equals(a, b), it is also the case that + * Arrays.hashCode(a) == Arrays.hashCode(b). + * + *

The value returned by this method is the same value that would be + * obtained by invoking the {@link List#hashCode() hashCode} + * method on a {@link List} containing a sequence of {@link Long} + * instances representing the elements of a in the same order. + * If a is null, this method returns 0. + * + * @param a the array whose hash value to compute + * @return a content-based hash code for a + * @since 1.5 + * @diffblue.fullSupport + */ + public static int hashCode(long a[]) { + if (a == null) + return 0; + + int result = 1; + for (long element : a) { + int elementHash = (int)(element ^ (element >>> 32)); + result = 31 * result + elementHash; + } + + return result; + } + + /** + * Returns a hash code based on the contents of the specified array. + * For any two non-null int arrays a and b + * such that Arrays.equals(a, b), it is also the case that + * Arrays.hashCode(a) == Arrays.hashCode(b). + * + *

The value returned by this method is the same value that would be + * obtained by invoking the {@link List#hashCode() hashCode} + * method on a {@link List} containing a sequence of {@link Integer} + * instances representing the elements of a in the same order. + * If a is null, this method returns 0. + * + * @param a the array whose hash value to compute + * @return a content-based hash code for a + * @since 1.5 + * @diffblue.fullSupport + */ + public static int hashCode(int a[]) { + if (a == null) + return 0; + + int result = 1; + for (int element : a) + result = 31 * result + element; + + return result; + } + + /** + * Returns a hash code based on the contents of the specified array. + * For any two short arrays a and b + * such that Arrays.equals(a, b), it is also the case that + * Arrays.hashCode(a) == Arrays.hashCode(b). + * + *

The value returned by this method is the same value that would be + * obtained by invoking the {@link List#hashCode() hashCode} + * method on a {@link List} containing a sequence of {@link Short} + * instances representing the elements of a in the same order. + * If a is null, this method returns 0. + * + * @param a the array whose hash value to compute + * @return a content-based hash code for a + * @since 1.5 + * @diffblue.fullSupport + */ + public static int hashCode(short a[]) { + if (a == null) + return 0; + + int result = 1; + for (short element : a) + result = 31 * result + element; + + return result; + } + + /** + * Returns a hash code based on the contents of the specified array. + * For any two char arrays a and b + * such that Arrays.equals(a, b), it is also the case that + * Arrays.hashCode(a) == Arrays.hashCode(b). + * + *

The value returned by this method is the same value that would be + * obtained by invoking the {@link List#hashCode() hashCode} + * method on a {@link List} containing a sequence of {@link Character} + * instances representing the elements of a in the same order. + * If a is null, this method returns 0. + * + * @param a the array whose hash value to compute + * @return a content-based hash code for a + * @since 1.5 + * @diffblue.fullSupport + */ + public static int hashCode(char a[]) { + if (a == null) + return 0; + + int result = 1; + for (char element : a) + result = 31 * result + element; + + return result; + } + + /** + * Returns a hash code based on the contents of the specified array. + * For any two byte arrays a and b + * such that Arrays.equals(a, b), it is also the case that + * Arrays.hashCode(a) == Arrays.hashCode(b). + * + *

The value returned by this method is the same value that would be + * obtained by invoking the {@link List#hashCode() hashCode} + * method on a {@link List} containing a sequence of {@link Byte} + * instances representing the elements of a in the same order. + * If a is null, this method returns 0. + * + * @param a the array whose hash value to compute + * @return a content-based hash code for a + * @since 1.5 + * @diffblue.fullSupport + */ + public static int hashCode(byte a[]) { + if (a == null) + return 0; + + int result = 1; + for (byte element : a) + result = 31 * result + element; + + return result; + } + + /** + * Returns a hash code based on the contents of the specified array. + * For any two boolean arrays a and b + * such that Arrays.equals(a, b), it is also the case that + * Arrays.hashCode(a) == Arrays.hashCode(b). + * + *

The value returned by this method is the same value that would be + * obtained by invoking the {@link List#hashCode() hashCode} + * method on a {@link List} containing a sequence of {@link Boolean} + * instances representing the elements of a in the same order. + * If a is null, this method returns 0. + * + * @param a the array whose hash value to compute + * @return a content-based hash code for a + * @since 1.5 + * @diffblue.fullSupport + */ + public static int hashCode(boolean a[]) { + if (a == null) + return 0; + + int result = 1; + for (boolean element : a) + result = 31 * result + (element ? 1231 : 1237); + + return result; + } + + /** + * Returns a hash code based on the contents of the specified array. + * For any two float arrays a and b + * such that Arrays.equals(a, b), it is also the case that + * Arrays.hashCode(a) == Arrays.hashCode(b). + * + *

The value returned by this method is the same value that would be + * obtained by invoking the {@link List#hashCode() hashCode} + * method on a {@link List} containing a sequence of {@link Float} + * instances representing the elements of a in the same order. + * If a is null, this method returns 0. + * + * @param a the array whose hash value to compute + * @return a content-based hash code for a + * @since 1.5 + * @diffblue.limitedSupport + * This will always return 0. To model this correctly, we would first need to + * model Double.doubleToLongBits. + * TG-4330 Double.doubleToRawLongBits and Float.floatToRawIntBits not supported + */ + public static int hashCode(float a[]) { + // if (a == null) + // return 0; + // + // int result = 1; + // for (float element : a) + // result = 31 * result + Float.floatToIntBits(element); + // + // return result; + return 0; + } + + /** + * Returns a hash code based on the contents of the specified array. + * For any two double arrays a and b + * such that Arrays.equals(a, b), it is also the case that + * Arrays.hashCode(a) == Arrays.hashCode(b). + * + *

The value returned by this method is the same value that would be + * obtained by invoking the {@link List#hashCode() hashCode} + * method on a {@link List} containing a sequence of {@link Double} + * instances representing the elements of a in the same order. + * If a is null, this method returns 0. + * + * @param a the array whose hash value to compute + * @return a content-based hash code for a + * @since 1.5 + * @diffblue.limitedSupport + * This will always return 0. To model this correctly, we would first need to + * model Double.doubleToLongBits. + * TG-4330 Double.doubleToRawLongBits and Float.floatToRawIntBits not supported + */ + public static int hashCode(double a[]) { + // if (a == null) + // return 0; + // + // int result = 1; + // for (double element : a) { + // long bits = Double.doubleToLongBits(element); + // result = 31 * result + (int)(bits ^ (bits >>> 32)); + // } + // return result; + return 0; + } + + /** + * Returns a hash code based on the contents of the specified array. If + * the array contains other arrays as elements, the hash code is based on + * their identities rather than their contents. It is therefore + * acceptable to invoke this method on an array that contains itself as an + * element, either directly or indirectly through one or more levels of + * arrays. + * + *

For any two arrays a and b such that + * Arrays.equals(a, b), it is also the case that + * Arrays.hashCode(a) == Arrays.hashCode(b). + * + *

The value returned by this method is equal to the value that would + * be returned by Arrays.asList(a).hashCode(), unless a + * is null, in which case 0 is returned. + * + * @param a the array whose content-based hash code to compute + * @return a content-based hash code for a + * @see #deepHashCode(Object[]) + * @since 1.5 + * @diffblue.limitedSupport + * This relies on the elements having a hashCode function that overrides Object.hashCode + */ + public static int hashCode(Object a[]) { + if (a == null) + return 0; + + int result = 1; + + for (Object element : a) + result = 31 * result + (element == null ? 0 : element.hashCode()); + + return result; + } + + /** + * Returns a hash code based on the "deep contents" of the specified + * array. If the array contains other arrays as elements, the + * hash code is based on their contents and so on, ad infinitum. + * It is therefore unacceptable to invoke this method on an array that + * contains itself as an element, either directly or indirectly through + * one or more levels of arrays. The behavior of such an invocation is + * undefined. + * + *

For any two arrays a and b such that + * Arrays.deepEquals(a, b), it is also the case that + * Arrays.deepHashCode(a) == Arrays.deepHashCode(b). + * + *

The computation of the value returned by this method is similar to + * that of the value returned by {@link List#hashCode()} on a list + * containing the same elements as a in the same order, with one + * difference: If an element e of a is itself an array, + * its hash code is computed not by calling e.hashCode(), but as + * by calling the appropriate overloading of Arrays.hashCode(e) + * if e is an array of a primitive type, or as by calling + * Arrays.deepHashCode(e) recursively if e is an array + * of a reference type. If a is null, this method + * returns 0. + * + * @param a the array whose deep-content-based hash code to compute + * @return a deep-content-based hash code for a + * @see #hashCode(Object[]) + * @since 1.5 + * @diffblue.noSupport + */ + public static int deepHashCode(Object a[]) { + // if (a == null) + // return 0; + // + // int result = 1; + // + // for (Object element : a) { + // int elementHash = 0; + // if (element instanceof Object[]) + // elementHash = deepHashCode((Object[]) element); + // else if (element instanceof byte[]) + // elementHash = hashCode((byte[]) element); + // else if (element instanceof short[]) + // elementHash = hashCode((short[]) element); + // else if (element instanceof int[]) + // elementHash = hashCode((int[]) element); + // else if (element instanceof long[]) + // elementHash = hashCode((long[]) element); + // else if (element instanceof char[]) + // elementHash = hashCode((char[]) element); + // else if (element instanceof float[]) + // elementHash = hashCode((float[]) element); + // else if (element instanceof double[]) + // elementHash = hashCode((double[]) element); + // else if (element instanceof boolean[]) + // elementHash = hashCode((boolean[]) element); + // else if (element != null) + // elementHash = element.hashCode(); + // + // result = 31 * result + elementHash; + // } + // + // return result; + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Returns true if the two specified arrays are deeply + * equal to one another. Unlike the {@link #equals(Object[],Object[])} + * method, this method is appropriate for use with nested arrays of + * arbitrary depth. + * + *

Two array references are considered deeply equal if both + * are null, or if they refer to arrays that contain the same + * number of elements and all corresponding pairs of elements in the two + * arrays are deeply equal. + * + *

Two possibly null elements e1 and e2 are + * deeply equal if any of the following conditions hold: + *

    + *
  • e1 and e2 are both arrays of object reference + * types, and Arrays.deepEquals(e1, e2) would return true + *
  • e1 and e2 are arrays of the same primitive + * type, and the appropriate overloading of + * Arrays.equals(e1, e2) would return true. + *
  • e1 == e2 + *
  • e1.equals(e2) would return true. + *
+ * Note that this definition permits null elements at any depth. + * + *

If either of the specified arrays contain themselves as elements + * either directly or indirectly through one or more levels of arrays, + * the behavior of this method is undefined. + * + * @param a1 one array to be tested for equality + * @param a2 the other array to be tested for equality + * @return true if the two arrays are equal + * @see #equals(Object[],Object[]) + * @see Objects#deepEquals(Object, Object) + * @since 1.5 + * @diffblue.noSupport + */ + public static boolean deepEquals(Object[] a1, Object[] a2) { + // if (a1 == a2) + // return true; + // if (a1 == null || a2==null) + // return false; + // int length = a1.length; + // if (a2.length != length) + // return false; + // + // for (int i = 0; i < length; i++) { + // Object e1 = a1[i]; + // Object e2 = a2[i]; + // + // if (e1 == e2) + // continue; + // if (e1 == null) + // return false; + // + // // Figure out whether the two elements are equal + // boolean eq = deepEquals0(e1, e2); + // + // if (!eq) + // return false; + // } + // return true; + CProver.notModelled(); + return CProver.nondetBoolean(); + } + + static boolean deepEquals0(Object e1, Object e2) { + // assert e1 != null; + // boolean eq; + // if (e1 instanceof Object[] && e2 instanceof Object[]) + // eq = deepEquals ((Object[]) e1, (Object[]) e2); + // else if (e1 instanceof byte[] && e2 instanceof byte[]) + // eq = equals((byte[]) e1, (byte[]) e2); + // else if (e1 instanceof short[] && e2 instanceof short[]) + // eq = equals((short[]) e1, (short[]) e2); + // else if (e1 instanceof int[] && e2 instanceof int[]) + // eq = equals((int[]) e1, (int[]) e2); + // else if (e1 instanceof long[] && e2 instanceof long[]) + // eq = equals((long[]) e1, (long[]) e2); + // else if (e1 instanceof char[] && e2 instanceof char[]) + // eq = equals((char[]) e1, (char[]) e2); + // else if (e1 instanceof float[] && e2 instanceof float[]) + // eq = equals((float[]) e1, (float[]) e2); + // else if (e1 instanceof double[] && e2 instanceof double[]) + // eq = equals((double[]) e1, (double[]) e2); + // else if (e1 instanceof boolean[] && e2 instanceof boolean[]) + // eq = equals((boolean[]) e1, (boolean[]) e2); + // else + // eq = e1.equals(e2); + // return eq; + CProver.notModelled(); + return CProver.nondetBoolean(); + } + + /** + * Returns a string representation of the contents of the specified array. + * The string representation consists of a list of the array's elements, + * enclosed in square brackets ("[]"). Adjacent elements are + * separated by the characters ", " (a comma followed by a + * space). Elements are converted to strings as by + * String.valueOf(long). Returns "null" if a + * is null. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @since 1.5 + * @diffblue.noSupport + */ + public static String toString(long[] a) { + // if (a == null) + // return "null"; + // int iMax = a.length - 1; + // if (iMax == -1) + // return "[]"; + // + // StringBuilder b = new StringBuilder(); + // b.append('['); + // for (int i = 0; ; i++) { + // b.append(a[i]); + // if (i == iMax) + // return b.append(']').toString(); + // b.append(", "); + // } + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a string representation of the contents of the specified array. + * The string representation consists of a list of the array's elements, + * enclosed in square brackets ("[]"). Adjacent elements are + * separated by the characters ", " (a comma followed by a + * space). Elements are converted to strings as by + * String.valueOf(int). Returns "null" if a is + * null. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @since 1.5 + * @diffblue.noSupport + */ + public static String toString(int[] a) { + // if (a == null) + // return "null"; + // int iMax = a.length - 1; + // if (iMax == -1) + // return "[]"; + // + // StringBuilder b = new StringBuilder(); + // b.append('['); + // for (int i = 0; ; i++) { + // b.append(a[i]); + // if (i == iMax) + // return b.append(']').toString(); + // b.append(", "); + // } + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a string representation of the contents of the specified array. + * The string representation consists of a list of the array's elements, + * enclosed in square brackets ("[]"). Adjacent elements are + * separated by the characters ", " (a comma followed by a + * space). Elements are converted to strings as by + * String.valueOf(short). Returns "null" if a + * is null. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @since 1.5 + * @diffblue.noSupport + */ + public static String toString(short[] a) { + // if (a == null) + // return "null"; + // int iMax = a.length - 1; + // if (iMax == -1) + // return "[]"; + // + // StringBuilder b = new StringBuilder(); + // b.append('['); + // for (int i = 0; ; i++) { + // b.append(a[i]); + // if (i == iMax) + // return b.append(']').toString(); + // b.append(", "); + // } + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a string representation of the contents of the specified array. + * The string representation consists of a list of the array's elements, + * enclosed in square brackets ("[]"). Adjacent elements are + * separated by the characters ", " (a comma followed by a + * space). Elements are converted to strings as by + * String.valueOf(char). Returns "null" if a + * is null. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @since 1.5 + * @diffblue.noSupport + */ + public static String toString(char[] a) { + // if (a == null) + // return "null"; + // int iMax = a.length - 1; + // if (iMax == -1) + // return "[]"; + // + // StringBuilder b = new StringBuilder(); + // b.append('['); + // for (int i = 0; ; i++) { + // b.append(a[i]); + // if (i == iMax) + // return b.append(']').toString(); + // b.append(", "); + // } + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a string representation of the contents of the specified array. + * The string representation consists of a list of the array's elements, + * enclosed in square brackets ("[]"). Adjacent elements + * are separated by the characters ", " (a comma followed + * by a space). Elements are converted to strings as by + * String.valueOf(byte). Returns "null" if + * a is null. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @since 1.5 + * @diffblue.noSupport + */ + public static String toString(byte[] a) { + // if (a == null) + // return "null"; + // int iMax = a.length - 1; + // if (iMax == -1) + // return "[]"; + // + // StringBuilder b = new StringBuilder(); + // b.append('['); + // for (int i = 0; ; i++) { + // b.append(a[i]); + // if (i == iMax) + // return b.append(']').toString(); + // b.append(", "); + // } + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a string representation of the contents of the specified array. + * The string representation consists of a list of the array's elements, + * enclosed in square brackets ("[]"). Adjacent elements are + * separated by the characters ", " (a comma followed by a + * space). Elements are converted to strings as by + * String.valueOf(boolean). Returns "null" if + * a is null. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @since 1.5 + * @diffblue.noSupport + */ + public static String toString(boolean[] a) { + // if (a == null) + // return "null"; + // int iMax = a.length - 1; + // if (iMax == -1) + // return "[]"; + // + // StringBuilder b = new StringBuilder(); + // b.append('['); + // for (int i = 0; ; i++) { + // b.append(a[i]); + // if (i == iMax) + // return b.append(']').toString(); + // b.append(", "); + // } + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a string representation of the contents of the specified array. + * The string representation consists of a list of the array's elements, + * enclosed in square brackets ("[]"). Adjacent elements are + * separated by the characters ", " (a comma followed by a + * space). Elements are converted to strings as by + * String.valueOf(float). Returns "null" if a + * is null. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @since 1.5 + * @diffblue.noSupport + */ + public static String toString(float[] a) { + // if (a == null) + // return "null"; + // + // int iMax = a.length - 1; + // if (iMax == -1) + // return "[]"; + // + // StringBuilder b = new StringBuilder(); + // b.append('['); + // for (int i = 0; ; i++) { + // b.append(a[i]); + // if (i == iMax) + // return b.append(']').toString(); + // b.append(", "); + // } + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a string representation of the contents of the specified array. + * The string representation consists of a list of the array's elements, + * enclosed in square brackets ("[]"). Adjacent elements are + * separated by the characters ", " (a comma followed by a + * space). Elements are converted to strings as by + * String.valueOf(double). Returns "null" if a + * is null. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @since 1.5 + * @diffblue.noSupport + */ + public static String toString(double[] a) { + // if (a == null) + // return "null"; + // int iMax = a.length - 1; + // if (iMax == -1) + // return "[]"; + // + // StringBuilder b = new StringBuilder(); + // b.append('['); + // for (int i = 0; ; i++) { + // b.append(a[i]); + // if (i == iMax) + // return b.append(']').toString(); + // b.append(", "); + // } + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a string representation of the contents of the specified array. + * If the array contains other arrays as elements, they are converted to + * strings by the {@link Object#toString} method inherited from + * Object, which describes their identities rather than + * their contents. + * + *

The value returned by this method is equal to the value that would + * be returned by Arrays.asList(a).toString(), unless a + * is null, in which case "null" is returned. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @see #deepToString(Object[]) + * @since 1.5 + * @diffblue.noSupport + */ + public static String toString(Object[] a) { + // if (a == null) + // return "null"; + // + // int iMax = a.length - 1; + // if (iMax == -1) + // return "[]"; + // + // StringBuilder b = new StringBuilder(); + // b.append('['); + // for (int i = 0; ; i++) { + // b.append(String.valueOf(a[i])); + // if (i == iMax) + // return b.append(']').toString(); + // b.append(", "); + // } + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a string representation of the "deep contents" of the specified + * array. If the array contains other arrays as elements, the string + * representation contains their contents and so on. This method is + * designed for converting multidimensional arrays to strings. + * + *

The string representation consists of a list of the array's + * elements, enclosed in square brackets ("[]"). Adjacent + * elements are separated by the characters ", " (a comma + * followed by a space). Elements are converted to strings as by + * String.valueOf(Object), unless they are themselves + * arrays. + * + *

If an element e is an array of a primitive type, it is + * converted to a string as by invoking the appropriate overloading of + * Arrays.toString(e). If an element e is an array of a + * reference type, it is converted to a string as by invoking + * this method recursively. + * + *

To avoid infinite recursion, if the specified array contains itself + * as an element, or contains an indirect reference to itself through one + * or more levels of arrays, the self-reference is converted to the string + * "[...]". For example, an array containing only a reference + * to itself would be rendered as "[[...]]". + * + *

This method returns "null" if the specified array + * is null. + * + * @param a the array whose string representation to return + * @return a string representation of a + * @see #toString(Object[]) + * @since 1.5 + * @diffblue.noSupport + */ + public static String deepToString(Object[] a) { + // if (a == null) + // return "null"; + // + // int bufLen = 20 * a.length; + // if (a.length != 0 && bufLen <= 0) + // bufLen = Integer.MAX_VALUE; + // StringBuilder buf = new StringBuilder(bufLen); + // deepToString(a, buf, new HashSet()); + // return buf.toString(); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static void deepToString(Object[] a, StringBuilder buf, + // Set dejaVu) { + // if (a == null) { + // buf.append("null"); + // return; + // } + // int iMax = a.length - 1; + // if (iMax == -1) { + // buf.append("[]"); + // return; + // } + // + // dejaVu.add(a); + // buf.append('['); + // for (int i = 0; ; i++) { + // + // Object element = a[i]; + // if (element == null) { + // buf.append("null"); + // } else { + // Class eClass = element.getClass(); + // + // if (eClass.isArray()) { + // if (eClass == byte[].class) + // buf.append(toString((byte[]) element)); + // else if (eClass == short[].class) + // buf.append(toString((short[]) element)); + // else if (eClass == int[].class) + // buf.append(toString((int[]) element)); + // else if (eClass == long[].class) + // buf.append(toString((long[]) element)); + // else if (eClass == char[].class) + // buf.append(toString((char[]) element)); + // else if (eClass == float[].class) + // buf.append(toString((float[]) element)); + // else if (eClass == double[].class) + // buf.append(toString((double[]) element)); + // else if (eClass == boolean[].class) + // buf.append(toString((boolean[]) element)); + // else { // element is an array of object references + // if (dejaVu.contains(element)) + // buf.append("[...]"); + // else + // deepToString((Object[])element, buf, dejaVu); + // } + // } else { // element is non-null and not an array + // buf.append(element.toString()); + // } + // } + // if (i == iMax) + // break; + // buf.append(", "); + // } + // buf.append(']'); + // dejaVu.remove(a); + // } + + + /** + * Set all elements of the specified array, using the provided + * generator function to compute each element. + * + *

If the generator function throws an exception, it is relayed to + * the caller and the array is left in an indeterminate state. + * + * @param type of elements of the array + * @param array array to be initialized + * @param generator a function accepting an index and producing the desired + * value for that position + * @throws NullPointerException if the generator is null + * @since 1.8 + * @diffblue.noSupport + */ + public static void setAll(T[] array, IntFunction generator) { + // Objects.requireNonNull(generator); + // for (int i = 0; i < array.length; i++) + // array[i] = generator.apply(i); + CProver.notModelled(); + } + + /** + * Set all elements of the specified array, in parallel, using the + * provided generator function to compute each element. + * + *

If the generator function throws an exception, an unchecked exception + * is thrown from {@code parallelSetAll} and the array is left in an + * indeterminate state. + * + * @param type of elements of the array + * @param array array to be initialized + * @param generator a function accepting an index and producing the desired + * value for that position + * @throws NullPointerException if the generator is null + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSetAll(T[] array, IntFunction generator) { + // Objects.requireNonNull(generator); + // IntStream.range(0, array.length).parallel().forEach(i -> { array[i] = generator.apply(i); }); + CProver.notModelled(); + } + + /** + * Set all elements of the specified array, using the provided + * generator function to compute each element. + * + *

If the generator function throws an exception, it is relayed to + * the caller and the array is left in an indeterminate state. + * + * @param array array to be initialized + * @param generator a function accepting an index and producing the desired + * value for that position + * @throws NullPointerException if the generator is null + * @since 1.8 + * @diffblue.noSupport + */ + public static void setAll(int[] array, IntUnaryOperator generator) { + // Objects.requireNonNull(generator); + // for (int i = 0; i < array.length; i++) + // array[i] = generator.applyAsInt(i); + CProver.notModelled(); + } + + /** + * Set all elements of the specified array, in parallel, using the + * provided generator function to compute each element. + * + *

If the generator function throws an exception, an unchecked exception + * is thrown from {@code parallelSetAll} and the array is left in an + * indeterminate state. + * + * @param array array to be initialized + * @param generator a function accepting an index and producing the desired + * value for that position + * @throws NullPointerException if the generator is null + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSetAll(int[] array, IntUnaryOperator generator) { + // Objects.requireNonNull(generator); + // IntStream.range(0, array.length).parallel().forEach(i -> { array[i] = generator.applyAsInt(i); }); + CProver.notModelled(); + } + + /** + * Set all elements of the specified array, using the provided + * generator function to compute each element. + * + *

If the generator function throws an exception, it is relayed to + * the caller and the array is left in an indeterminate state. + * + * @param array array to be initialized + * @param generator a function accepting an index and producing the desired + * value for that position + * @throws NullPointerException if the generator is null + * @since 1.8 + * @diffblue.noSupport + */ + public static void setAll(long[] array, IntToLongFunction generator) { + // Objects.requireNonNull(generator); + // for (int i = 0; i < array.length; i++) + // array[i] = generator.applyAsLong(i); + CProver.notModelled(); + } + + /** + * Set all elements of the specified array, in parallel, using the + * provided generator function to compute each element. + * + *

If the generator function throws an exception, an unchecked exception + * is thrown from {@code parallelSetAll} and the array is left in an + * indeterminate state. + * + * @param array array to be initialized + * @param generator a function accepting an index and producing the desired + * value for that position + * @throws NullPointerException if the generator is null + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSetAll(long[] array, IntToLongFunction generator) { + // Objects.requireNonNull(generator); + // IntStream.range(0, array.length).parallel().forEach(i -> { array[i] = generator.applyAsLong(i); }); + CProver.notModelled(); + } + + /** + * Set all elements of the specified array, using the provided + * generator function to compute each element. + * + *

If the generator function throws an exception, it is relayed to + * the caller and the array is left in an indeterminate state. + * + * @param array array to be initialized + * @param generator a function accepting an index and producing the desired + * value for that position + * @throws NullPointerException if the generator is null + * @since 1.8 + * @diffblue.noSupport + */ + public static void setAll(double[] array, IntToDoubleFunction generator) { + // Objects.requireNonNull(generator); + // for (int i = 0; i < array.length; i++) + // array[i] = generator.applyAsDouble(i); + CProver.notModelled(); + } + + /** + * Set all elements of the specified array, in parallel, using the + * provided generator function to compute each element. + * + *

If the generator function throws an exception, an unchecked exception + * is thrown from {@code parallelSetAll} and the array is left in an + * indeterminate state. + * + * @param array array to be initialized + * @param generator a function accepting an index and producing the desired + * value for that position + * @throws NullPointerException if the generator is null + * @since 1.8 + * @diffblue.noSupport + */ + public static void parallelSetAll(double[] array, IntToDoubleFunction generator) { + // Objects.requireNonNull(generator); + // IntStream.range(0, array.length).parallel().forEach(i -> { array[i] = generator.applyAsDouble(i); }); + CProver.notModelled(); + } + + /** + * Returns a {@link Spliterator} covering all of the specified array. + * + *

The spliterator reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#IMMUTABLE}. + * + * @param type of elements + * @param array the array, assumed to be unmodified during use + * @return a spliterator for the array elements + * @since 1.8 + * @diffblue.untested + */ + public static Spliterator spliterator(T[] array) { + return Spliterators.spliterator(array, + Spliterator.ORDERED | Spliterator.IMMUTABLE); + } + + /** + * Returns a {@link Spliterator} covering the specified range of the + * specified array. + * + *

The spliterator reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#IMMUTABLE}. + * + * @param type of elements + * @param array the array, assumed to be unmodified during use + * @param startInclusive the first index to cover, inclusive + * @param endExclusive index immediately past the last index to cover + * @return a spliterator for the array elements + * @throws ArrayIndexOutOfBoundsException if {@code startInclusive} is + * negative, {@code endExclusive} is less than + * {@code startInclusive}, or {@code endExclusive} is greater than + * the array size + * @since 1.8 + * @diffblue.untested + */ + public static Spliterator spliterator(T[] array, int startInclusive, int endExclusive) { + return Spliterators.spliterator(array, startInclusive, endExclusive, + Spliterator.ORDERED | Spliterator.IMMUTABLE); + } + + /** + * Returns a {@link Spliterator.OfInt} covering all of the specified array. + * + *

The spliterator reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#IMMUTABLE}. + * + * @param array the array, assumed to be unmodified during use + * @return a spliterator for the array elements + * @since 1.8 + * @diffblue.untested + */ + public static Spliterator.OfInt spliterator(int[] array) { + return Spliterators.spliterator(array, + Spliterator.ORDERED | Spliterator.IMMUTABLE); + } + + /** + * Returns a {@link Spliterator.OfInt} covering the specified range of the + * specified array. + * + *

The spliterator reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#IMMUTABLE}. + * + * @param array the array, assumed to be unmodified during use + * @param startInclusive the first index to cover, inclusive + * @param endExclusive index immediately past the last index to cover + * @return a spliterator for the array elements + * @throws ArrayIndexOutOfBoundsException if {@code startInclusive} is + * negative, {@code endExclusive} is less than + * {@code startInclusive}, or {@code endExclusive} is greater than + * the array size + * @since 1.8 + * @diffblue.noSupport + */ + public static Spliterator.OfInt spliterator(int[] array, int startInclusive, int endExclusive) { + // return Spliterators.spliterator(array, startInclusive, endExclusive, + // Spliterator.ORDERED | Spliterator.IMMUTABLE); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a {@link Spliterator.OfLong} covering all of the specified array. + * + *

The spliterator reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#IMMUTABLE}. + * + * @param array the array, assumed to be unmodified during use + * @return the spliterator for the array elements + * @since 1.8 + * @diffblue.noSupport + */ + public static Spliterator.OfLong spliterator(long[] array) { + // return Spliterators.spliterator(array, + // Spliterator.ORDERED | Spliterator.IMMUTABLE); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a {@link Spliterator.OfLong} covering the specified range of the + * specified array. + * + *

The spliterator reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#IMMUTABLE}. + * + * @param array the array, assumed to be unmodified during use + * @param startInclusive the first index to cover, inclusive + * @param endExclusive index immediately past the last index to cover + * @return a spliterator for the array elements + * @throws ArrayIndexOutOfBoundsException if {@code startInclusive} is + * negative, {@code endExclusive} is less than + * {@code startInclusive}, or {@code endExclusive} is greater than + * the array size + * @since 1.8 + * @diffblue.noSupport + */ + public static Spliterator.OfLong spliterator(long[] array, int startInclusive, int endExclusive) { + // return Spliterators.spliterator(array, startInclusive, endExclusive, + // Spliterator.ORDERED | Spliterator.IMMUTABLE); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a {@link Spliterator.OfDouble} covering all of the specified + * array. + * + *

The spliterator reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#IMMUTABLE}. + * + * @param array the array, assumed to be unmodified during use + * @return a spliterator for the array elements + * @since 1.8 + * @diffblue.noSupport + */ + public static Spliterator.OfDouble spliterator(double[] array) { + // return Spliterators.spliterator(array, + // Spliterator.ORDERED | Spliterator.IMMUTABLE); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a {@link Spliterator.OfDouble} covering the specified range of + * the specified array. + * + *

The spliterator reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#IMMUTABLE}. + * + * @param array the array, assumed to be unmodified during use + * @param startInclusive the first index to cover, inclusive + * @param endExclusive index immediately past the last index to cover + * @return a spliterator for the array elements + * @throws ArrayIndexOutOfBoundsException if {@code startInclusive} is + * negative, {@code endExclusive} is less than + * {@code startInclusive}, or {@code endExclusive} is greater than + * the array size + * @since 1.8 + * @diffblue.noSupport + */ + public static Spliterator.OfDouble spliterator(double[] array, int startInclusive, int endExclusive) { + // return Spliterators.spliterator(array, startInclusive, endExclusive, + // Spliterator.ORDERED | Spliterator.IMMUTABLE); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a sequential {@link Stream} with the specified array as its + * source. + * + * @param The type of the array elements + * @param array The array, assumed to be unmodified during use + * @return a {@code Stream} for the array + * @since 1.8 + * @diffblue.untested + */ + public static Stream stream(T[] array) { + return stream(array, 0, array.length); + } + + /** + * Returns a sequential {@link Stream} with the specified range of the + * specified array as its source. + * + * @param the type of the array elements + * @param array the array, assumed to be unmodified during use + * @param startInclusive the first index to cover, inclusive + * @param endExclusive index immediately past the last index to cover + * @return a {@code Stream} for the array range + * @throws ArrayIndexOutOfBoundsException if {@code startInclusive} is + * negative, {@code endExclusive} is less than + * {@code startInclusive}, or {@code endExclusive} is greater than + * the array size + * @since 1.8 + * @diffblue.untested + */ + public static Stream stream(T[] array, int startInclusive, int endExclusive) { + return StreamSupport.stream(spliterator(array, startInclusive, endExclusive), false); + } + + /** + * Returns a sequential {@link IntStream} with the specified array as its + * source. + * + * @param array the array, assumed to be unmodified during use + * @return an {@code IntStream} for the array + * @since 1.8 + * @diffblue.untested + */ + public static IntStream stream(int[] array) { + return stream(array, 0, array.length); + } + + /** + * Returns a sequential {@link IntStream} with the specified range of the + * specified array as its source. + * + * @param array the array, assumed to be unmodified during use + * @param startInclusive the first index to cover, inclusive + * @param endExclusive index immediately past the last index to cover + * @return an {@code IntStream} for the array range + * @throws ArrayIndexOutOfBoundsException if {@code startInclusive} is + * negative, {@code endExclusive} is less than + * {@code startInclusive}, or {@code endExclusive} is greater than + * the array size + * @since 1.8 + * @diffblue.noSupport + */ + public static IntStream stream(int[] array, int startInclusive, int endExclusive) { + // return StreamSupport.intStream(spliterator(array, startInclusive, endExclusive), false); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a sequential {@link LongStream} with the specified array as its + * source. + * + * @param array the array, assumed to be unmodified during use + * @return a {@code LongStream} for the array + * @since 1.8 + * @diffblue.noSupport + */ + public static LongStream stream(long[] array) { + // return stream(array, 0, array.length); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a sequential {@link LongStream} with the specified range of the + * specified array as its source. + * + * @param array the array, assumed to be unmodified during use + * @param startInclusive the first index to cover, inclusive + * @param endExclusive index immediately past the last index to cover + * @return a {@code LongStream} for the array range + * @throws ArrayIndexOutOfBoundsException if {@code startInclusive} is + * negative, {@code endExclusive} is less than + * {@code startInclusive}, or {@code endExclusive} is greater than + * the array size + * @since 1.8 + * @diffblue.noSupport + */ + public static LongStream stream(long[] array, int startInclusive, int endExclusive) { + // return StreamSupport.longStream(spliterator(array, startInclusive, endExclusive), false); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a sequential {@link DoubleStream} with the specified array as its + * source. + * + * @param array the array, assumed to be unmodified during use + * @return a {@code DoubleStream} for the array + * @since 1.8 + * @diffblue.noSupport + */ + public static DoubleStream stream(double[] array) { + // return stream(array, 0, array.length); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns a sequential {@link DoubleStream} with the specified range of the + * specified array as its source. + * + * @param array the array, assumed to be unmodified during use + * @param startInclusive the first index to cover, inclusive + * @param endExclusive index immediately past the last index to cover + * @return a {@code DoubleStream} for the array range + * @throws ArrayIndexOutOfBoundsException if {@code startInclusive} is + * negative, {@code endExclusive} is less than + * {@code startInclusive}, or {@code endExclusive} is greater than + * the array size + * @since 1.8 + * @diffblue.noSupport + */ + public static DoubleStream stream(double[] array, int startInclusive, int endExclusive) { + // return StreamSupport.doubleStream(spliterator(array, startInclusive, endExclusive), false); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } +} diff --git a/src/main/java/java/util/Collections.java b/src/main/java/java/util/Collections.java new file mode 100644 index 0000000..b050227 --- /dev/null +++ b/src/main/java/java/util/Collections.java @@ -0,0 +1,5957 @@ +/* + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util; + +import org.cprover.CProver; +import java.io.Serializable; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.lang.reflect.Array; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +/** + * This class consists exclusively of static methods that operate on or return + * collections. It contains polymorphic algorithms that operate on + * collections, "wrappers", which return a new collection backed by a + * specified collection, and a few other odds and ends. + * + *

The methods of this class all throw a NullPointerException + * if the collections or class objects provided to them are null. + * + *

The documentation for the polymorphic algorithms contained in this class + * generally includes a brief description of the implementation. Such + * descriptions should be regarded as implementation notes, rather than + * parts of the specification. Implementors should feel free to + * substitute other algorithms, so long as the specification itself is adhered + * to. (For example, the algorithm used by sort does not have to be + * a mergesort, but it does have to be stable.) + * + *

The "destructive" algorithms contained in this class, that is, the + * algorithms that modify the collection on which they operate, are specified + * to throw UnsupportedOperationException if the collection does not + * support the appropriate mutation primitive(s), such as the set + * method. These algorithms may, but are not required to, throw this + * exception if an invocation would have no effect on the collection. For + * example, invoking the sort method on an unmodifiable list that is + * already sorted may or may not throw UnsupportedOperationException. + * + *

This class is a member of the + * + * Java Collections Framework. + * + * @author Josh Bloch + * @author Neal Gafter + * @see Collection + * @see Set + * @see List + * @see Map + * @since 1.2 + * + * @diffblue.untested + * @diffblue.noSupport + * This model was automatically generated by the JDK Processor tool. + */ + +public class Collections { + // Suppresses default constructor, ensuring non-instantiability. + // DIFFBLUE MODEL LIBRARY - not used in model + // private Collections() { + // } + + // Algorithms + + /* + * Tuning parameters for algorithms - Many of the List algorithms have + * two implementations, one of which is appropriate for RandomAccess + * lists, the other for "sequential." Often, the random access variant + * yields better performance on small sequential access lists. The + * tuning parameters below determine the cutoff point for what constitutes + * a "small" sequential access list for each algorithm. The values below + * were empirically determined to work well for LinkedList. Hopefully + * they should be reasonable for other sequential access List + * implementations. Those doing performance work on this code would + * do well to validate the values of these parameters from time to time. + * (The first word of each tuning parameter name is the algorithm to which + * it applies.) + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static final int BINARYSEARCH_THRESHOLD = 5000; + + private static final int REVERSE_THRESHOLD = 18; + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static final int SHUFFLE_THRESHOLD = 5; + // DIFFBLUE MODEL LIBRARY - not used in model + // private static final int FILL_THRESHOLD = 25; + // DIFFBLUE MODEL LIBRARY - not used in model + // private static final int ROTATE_THRESHOLD = 100; + // DIFFBLUE MODEL LIBRARY - not used in model + // private static final int COPY_THRESHOLD = 10; + // DIFFBLUE MODEL LIBRARY - not used in model + // private static final int REPLACEALL_THRESHOLD = 11; + // DIFFBLUE MODEL LIBRARY - not used in model + // private static final int INDEXOFSUBLIST_THRESHOLD = 35; + + /** + * Sorts the specified list into ascending order, according to the + * {@linkplain Comparable natural ordering} of its elements. + * All elements in the list must implement the {@link Comparable} + * interface. Furthermore, all elements in the list must be + * mutually comparable (that is, {@code e1.compareTo(e2)} + * must not throw a {@code ClassCastException} for any elements + * {@code e1} and {@code e2} in the list). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + *

The specified list must be modifiable, but need not be resizable. + * + * @implNote + * This implementation defers to the {@link List#sort(Comparator)} + * method using the specified list and a {@code null} comparator. + * + * @param the class of the objects in the list + * @param list the list to be sorted. + * @throws ClassCastException if the list contains elements that are not + * mutually comparable (for example, strings and integers). + * @throws UnsupportedOperationException if the specified list's + * list-iterator does not support the {@code set} operation. + * @throws IllegalArgumentException (optional) if the implementation + * detects that the natural ordering of the list elements is + * found to violate the {@link Comparable} contract + * @see List#sort(Comparator) + * + * @diffblue.untested + * @diffblue.fullSupport + */ + @SuppressWarnings("unchecked") + public static > void sort(List list) { + list.sort(null); + } + + /** + * Sorts the specified list according to the order induced by the + * specified comparator. All elements in the list must be mutually + * comparable using the specified comparator (that is, + * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} + * for any elements {@code e1} and {@code e2} in the list). + * + *

This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. + * + *

The specified list must be modifiable, but need not be resizable. + * + * @implNote + * This implementation defers to the {@link List#sort(Comparator)} + * method using the specified list and comparator. + * + * @param the class of the objects in the list + * @param list the list to be sorted. + * @param c the comparator to determine the order of the list. A + * {@code null} value indicates that the elements' natural + * ordering should be used. + * @throws ClassCastException if the list contains elements that are not + * mutually comparable using the specified comparator. + * @throws UnsupportedOperationException if the specified list's + * list-iterator does not support the {@code set} operation. + * @throws IllegalArgumentException (optional) if the comparator is + * found to violate the {@link Comparator} contract + * @see List#sort(Comparator) + * + * @diffblue.untested + * @diffblue.fullSupport + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + public static void sort(List list, Comparator c) { + list.sort(c); + } + + + /** + * Searches the specified list for the specified object using the binary + * search algorithm. The list must be sorted into ascending order + * according to the {@linkplain Comparable natural ordering} of its + * elements (as by the {@link #sort(List)} method) prior to making this + * call. If it is not sorted, the results are undefined. If the list + * contains multiple elements equal to the specified object, there is no + * guarantee which one will be found. + * + *

This method runs in log(n) time for a "random access" list (which + * provides near-constant-time positional access). If the specified list + * does not implement the {@link RandomAccess} interface and is large, + * this method will do an iterator-based binary search that performs + * O(n) link traversals and O(log n) element comparisons. + * + * @param the class of the objects in the list + * @param list the list to be searched. + * @param key the key to be searched for. + * @return the index of the search key, if it is contained in the list; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the list: the index of the first + * element greater than the key, or list.size() if all + * elements in the list are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws ClassCastException if the list contains elements that are not + * mutually comparable (for example, strings and + * integers), or the search key is not mutually comparable + * with the elements of the list. + */ + public static + int binarySearch(List> list, T key) { + // if (list instanceof RandomAccess || list.size() + // int indexedBinarySearch(List> list, T key) { + // int low = 0; + // int high = list.size()-1; + + // while (low <= high) { + // int mid = (low + high) >>> 1; + // Comparable midVal = list.get(mid); + // int cmp = midVal.compareTo(key); + + // if (cmp < 0) + // low = mid + 1; + // else if (cmp > 0) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found + // } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static + // int iteratorBinarySearch(List> list, T key) + // { + // int low = 0; + // int high = list.size()-1; + // ListIterator> i = list.listIterator(); + + // while (low <= high) { + // int mid = (low + high) >>> 1; + // Comparable midVal = get(i, mid); + // int cmp = midVal.compareTo(key); + + // if (cmp < 0) + // low = mid + 1; + // else if (cmp > 0) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found + // } + + /** + * Gets the ith element from the given list by repositioning the specified + * list listIterator. + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static T get(ListIterator i, int index) { + // T obj = null; + // int pos = i.nextIndex(); + // if (pos <= index) { + // do { + // obj = i.next(); + // } while (pos++ < index); + // } else { + // do { + // obj = i.previous(); + // } while (--pos > index); + // } + // return obj; + // } + + /** + * Searches the specified list for the specified object using the binary + * search algorithm. The list must be sorted into ascending order + * according to the specified comparator (as by the + * {@link #sort(List, Comparator) sort(List, Comparator)} + * method), prior to making this call. If it is + * not sorted, the results are undefined. If the list contains multiple + * elements equal to the specified object, there is no guarantee which one + * will be found. + * + *

This method runs in log(n) time for a "random access" list (which + * provides near-constant-time positional access). If the specified list + * does not implement the {@link RandomAccess} interface and is large, + * this method will do an iterator-based binary search that performs + * O(n) link traversals and O(log n) element comparisons. + * + * @param the class of the objects in the list + * @param list the list to be searched. + * @param key the key to be searched for. + * @param c the comparator by which the list is ordered. + * A null value indicates that the elements' + * {@linkplain Comparable natural ordering} should be used. + * @return the index of the search key, if it is contained in the list; + * otherwise, (-(insertion point) - 1). The + * insertion point is defined as the point at which the + * key would be inserted into the list: the index of the first + * element greater than the key, or list.size() if all + * elements in the list are less than the specified key. Note + * that this guarantees that the return value will be >= 0 if + * and only if the key is found. + * @throws ClassCastException if the list contains elements that are not + * mutually comparable using the specified comparator, + * or the search key is not mutually comparable with the + * elements of the list using this comparator. + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static int binarySearch(List list, T key, Comparator c) { + // if (c==null) + // return binarySearch((List>) list, key); + + // if (list instanceof RandomAccess || list.size() int indexedBinarySearch(List l, T key, Comparator c) { + // int low = 0; + // int high = l.size()-1; + + // while (low <= high) { + // int mid = (low + high) >>> 1; + // T midVal = l.get(mid); + // int cmp = c.compare(midVal, key); + + // if (cmp < 0) + // low = mid + 1; + // else if (cmp > 0) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found + // } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static int iteratorBinarySearch(List l, T key, Comparator c) { + // int low = 0; + // int high = l.size()-1; + // ListIterator i = l.listIterator(); + + // while (low <= high) { + // int mid = (low + high) >>> 1; + // T midVal = get(i, mid); + // int cmp = c.compare(midVal, key); + + // if (cmp < 0) + // low = mid + 1; + // else if (cmp > 0) + // high = mid - 1; + // else + // return mid; // key found + // } + // return -(low + 1); // key not found + // } + + /** + * Reverses the order of the elements in the specified list.

+ * + * This method runs in linear time. + * + * @param list the list whose elements are to be reversed. + * @throws UnsupportedOperationException if the specified list or + * its list-iterator does not support the set operation. + * + * @diffblue.fullSupport + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static void reverse(List list) { + // int size = list.size(); + // if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { + // for (int i=0, mid=size>>1, j=size-1; i>1; i>1, j=size-1; iThe hedge "approximately" is used in the foregoing description because + * default source of randomness is only approximately an unbiased source + * of independently chosen bits. If it were a perfect source of randomly + * chosen bits, then the algorithm would choose permutations with perfect + * uniformity. + * + *

This implementation traverses the list backwards, from the last + * element up to the second, repeatedly swapping a randomly selected element + * into the "current position". Elements are randomly selected from the + * portion of the list that runs from the first element to the current + * position, inclusive. + * + *

This method runs in linear time. If the specified list does not + * implement the {@link RandomAccess} interface and is large, this + * implementation dumps the specified list into an array before shuffling + * it, and dumps the shuffled array back into the list. This avoids the + * quadratic behavior that would result from shuffling a "sequential + * access" list in place. + * + * @param list the list to be shuffled. + * @throws UnsupportedOperationException if the specified list or + * its list-iterator does not support the set operation. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static void shuffle(List list) { + // Random rnd = r; + // if (rnd == null) + // r = rnd = new Random(); // harmless race. + // shuffle(list, rnd); + CProver.notModelled(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static Random r; + + /** + * Randomly permute the specified list using the specified source of + * randomness. All permutations occur with equal likelihood + * assuming that the source of randomness is fair.

+ * + * This implementation traverses the list backwards, from the last element + * up to the second, repeatedly swapping a randomly selected element into + * the "current position". Elements are randomly selected from the + * portion of the list that runs from the first element to the current + * position, inclusive.

+ * + * This method runs in linear time. If the specified list does not + * implement the {@link RandomAccess} interface and is large, this + * implementation dumps the specified list into an array before shuffling + * it, and dumps the shuffled array back into the list. This avoids the + * quadratic behavior that would result from shuffling a "sequential + * access" list in place. + * + * @param list the list to be shuffled. + * @param rnd the source of randomness to use to shuffle the list. + * @throws UnsupportedOperationException if the specified list or its + * list-iterator does not support the set operation. + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static void shuffle(List list, Random rnd) { + // int size = list.size(); + // if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { + // for (int i=size; i>1; i--) + // swap(list, i-1, rnd.nextInt(i)); + // } else { + // Object arr[] = list.toArray(); + + // // Shuffle array + // for (int i=size; i>1; i--) + // swap(arr, i-1, rnd.nextInt(i)); + + // // Dump array back into list + // // instead of using a raw type here, it's possible to capture + // // the wildcard but it will require a call to a supplementary + // // private method + // ListIterator it = list.listIterator(); + // for (int i=0; ii or j + * is out of range (i < 0 || i >= list.size() + * || j < 0 || j >= list.size()). + * @since 1.4 + * + * @diffblue.fullSupport + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static void swap(List list, int i, int j) { + // instead of using a raw type here, it's possible to capture + // the wildcard but it will require a call to a supplementary + // private method + final List l = list; + l.set(i, l.set(j, l.get(i))); + } + + /** + * Swaps the two specified elements in the specified array. + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static void swap(Object[] arr, int i, int j) { + // Object tmp = arr[i]; + // arr[i] = arr[j]; + // arr[j] = tmp; + // } + + /** + * Replaces all of the elements of the specified list with the specified + * element.

+ * + * This method runs in linear time. + * + * @param the class of the objects in the list + * @param list the list to be filled with the specified element. + * @param obj The element with which to fill the specified list. + * @throws UnsupportedOperationException if the specified list or its + * list-iterator does not support the set operation. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static void fill(List list, T obj) { + // int size = list.size(); + + // if (size < FILL_THRESHOLD || list instanceof RandomAccess) { + // for (int i=0; i itr = list.listIterator(); + // for (int i=0; i + * + * This method runs in linear time. + * + * @param the class of the objects in the lists + * @param dest The destination list. + * @param src The source list. + * @throws IndexOutOfBoundsException if the destination list is too small + * to contain the entire source List. + * @throws UnsupportedOperationException if the destination list's + * list-iterator does not support the set operation. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static void copy(List dest, List src) { + // int srcSize = src.size(); + // if (srcSize > dest.size()) + // throw new IndexOutOfBoundsException("Source does not fit in dest"); + + // if (srcSize < COPY_THRESHOLD || + // (src instanceof RandomAccess && dest instanceof RandomAccess)) { + // for (int i=0; i di=dest.listIterator(); + // ListIterator si=src.listIterator(); + // for (int i=0; inatural ordering of its elements. All elements in the + * collection must implement the Comparable interface. + * Furthermore, all elements in the collection must be mutually + * comparable (that is, e1.compareTo(e2) must not throw a + * ClassCastException for any elements e1 and + * e2 in the collection).

+ * + * This method iterates over the entire collection, hence it requires + * time proportional to the size of the collection. + * + * @param the class of the objects in the collection + * @param coll the collection whose minimum element is to be determined. + * @return the minimum element of the given collection, according + * to the natural ordering of its elements. + * @throws ClassCastException if the collection contains elements that are + * not mutually comparable (for example, strings and + * integers). + * @throws NoSuchElementException if the collection is empty. + * @see Comparable + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static > T min(Collection coll) { + // Iterator i = coll.iterator(); + // T candidate = i.next(); + + // while (i.hasNext()) { + // T next = i.next(); + // if (next.compareTo(candidate) < 0) + // candidate = next; + // } + // return candidate; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns the minimum element of the given collection, according to the + * order induced by the specified comparator. All elements in the + * collection must be mutually comparable by the specified + * comparator (that is, comp.compare(e1, e2) must not throw a + * ClassCastException for any elements e1 and + * e2 in the collection).

+ * + * This method iterates over the entire collection, hence it requires + * time proportional to the size of the collection. + * + * @param the class of the objects in the collection + * @param coll the collection whose minimum element is to be determined. + * @param comp the comparator with which to determine the minimum element. + * A null value indicates that the elements' natural + * ordering should be used. + * @return the minimum element of the given collection, according + * to the specified comparator. + * @throws ClassCastException if the collection contains elements that are + * not mutually comparable using the specified comparator. + * @throws NoSuchElementException if the collection is empty. + * @see Comparable + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + public static T min(Collection coll, Comparator comp) { + // if (comp==null) + // return (T)min((Collection) coll); + + // Iterator i = coll.iterator(); + // T candidate = i.next(); + + // while (i.hasNext()) { + // T next = i.next(); + // if (comp.compare(next, candidate) < 0) + // candidate = next; + // } + // return candidate; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns the maximum element of the given collection, according to the + * natural ordering of its elements. All elements in the + * collection must implement the Comparable interface. + * Furthermore, all elements in the collection must be mutually + * comparable (that is, e1.compareTo(e2) must not throw a + * ClassCastException for any elements e1 and + * e2 in the collection).

+ * + * This method iterates over the entire collection, hence it requires + * time proportional to the size of the collection. + * + * @param the class of the objects in the collection + * @param coll the collection whose maximum element is to be determined. + * @return the maximum element of the given collection, according + * to the natural ordering of its elements. + * @throws ClassCastException if the collection contains elements that are + * not mutually comparable (for example, strings and + * integers). + * @throws NoSuchElementException if the collection is empty. + * @see Comparable + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static > T max(Collection coll) { + // Iterator i = coll.iterator(); + // T candidate = i.next(); + + // while (i.hasNext()) { + // T next = i.next(); + // if (next.compareTo(candidate) > 0) + // candidate = next; + // } + // return candidate; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns the maximum element of the given collection, according to the + * order induced by the specified comparator. All elements in the + * collection must be mutually comparable by the specified + * comparator (that is, comp.compare(e1, e2) must not throw a + * ClassCastException for any elements e1 and + * e2 in the collection).

+ * + * This method iterates over the entire collection, hence it requires + * time proportional to the size of the collection. + * + * @param the class of the objects in the collection + * @param coll the collection whose maximum element is to be determined. + * @param comp the comparator with which to determine the maximum element. + * A null value indicates that the elements' natural + * ordering should be used. + * @return the maximum element of the given collection, according + * to the specified comparator. + * @throws ClassCastException if the collection contains elements that are + * not mutually comparable using the specified comparator. + * @throws NoSuchElementException if the collection is empty. + * @see Comparable + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + public static T max(Collection coll, Comparator comp) { + // if (comp==null) + // return (T)max((Collection) coll); + + // Iterator i = coll.iterator(); + // T candidate = i.next(); + + // while (i.hasNext()) { + // T next = i.next(); + // if (comp.compare(next, candidate) > 0) + // candidate = next; + // } + // return candidate; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Rotates the elements in the specified list by the specified distance. + * After calling this method, the element at index i will be + * the element previously at index (i - distance) mod + * list.size(), for all values of i between 0 + * and list.size()-1, inclusive. (This method has no effect on + * the size of the list.) + * + *

For example, suppose list comprises [t, a, n, k, s]. + * After invoking Collections.rotate(list, 1) (or + * Collections.rotate(list, -4)), list will comprise + * [s, t, a, n, k]. + * + *

Note that this method can usefully be applied to sublists to + * move one or more elements within a list while preserving the + * order of the remaining elements. For example, the following idiom + * moves the element at index j forward to position + * k (which must be greater than or equal to j): + *

+     *     Collections.rotate(list.subList(j, k+1), -1);
+     * 
+ * To make this concrete, suppose list comprises + * [a, b, c, d, e]. To move the element at index 1 + * (b) forward two positions, perform the following invocation: + *
+     *     Collections.rotate(l.subList(1, 4), -1);
+     * 
+ * The resulting list is [a, c, d, b, e]. + * + *

To move more than one element forward, increase the absolute value + * of the rotation distance. To move elements backward, use a positive + * shift distance. + * + *

If the specified list is small or implements the {@link + * RandomAccess} interface, this implementation exchanges the first + * element into the location it should go, and then repeatedly exchanges + * the displaced element into the location it should go until a displaced + * element is swapped into the first element. If necessary, the process + * is repeated on the second and successive elements, until the rotation + * is complete. If the specified list is large and doesn't implement the + * RandomAccess interface, this implementation breaks the + * list into two sublist views around index -distance mod size. + * Then the {@link #reverse(List)} method is invoked on each sublist view, + * and finally it is invoked on the entire list. For a more complete + * description of both algorithms, see Section 2.3 of Jon Bentley's + * Programming Pearls (Addison-Wesley, 1986). + * + * @param list the list to be rotated. + * @param distance the distance to rotate the list. There are no + * constraints on this value; it may be zero, negative, or + * greater than list.size(). + * @throws UnsupportedOperationException if the specified list or + * its list-iterator does not support the set operation. + * @since 1.4 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static void rotate(List list, int distance) { + // if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD) + // rotate1(list, distance); + // else + // rotate2(list, distance); + CProver.notModelled(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static void rotate1(List list, int distance) { + // int size = list.size(); + // if (size == 0) + // return; + // distance = distance % size; + // if (distance < 0) + // distance += size; + // if (distance == 0) + // return; + + // for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) { + // T displaced = list.get(cycleStart); + // int i = cycleStart; + // do { + // i += distance; + // if (i >= size) + // i -= size; + // displaced = list.set(i, displaced); + // nMoved ++; + // } while (i != cycleStart); + // } + // } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static void rotate2(List list, int distance) { + // int size = list.size(); + // if (size == 0) + // return; + // int mid = -distance % size; + // if (mid < 0) + // mid += size; + // if (mid == 0) + // return; + + // reverse(list.subList(0, mid)); + // reverse(list.subList(mid, size)); + // reverse(list); + // } + + /** + * Replaces all occurrences of one specified value in a list with another. + * More formally, replaces with newVal each element e + * in list such that + * (oldVal==null ? e==null : oldVal.equals(e)). + * (This method has no effect on the size of the list.) + * + * @param the class of the objects in the list + * @param list the list in which replacement is to occur. + * @param oldVal the old value to be replaced. + * @param newVal the new value with which oldVal is to be + * replaced. + * @return true if list contained one or more elements + * e such that + * (oldVal==null ? e==null : oldVal.equals(e)). + * @throws UnsupportedOperationException if the specified list or + * its list-iterator does not support the set operation. + * @since 1.4 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static boolean replaceAll(List list, T oldVal, T newVal) { + // boolean result = false; + // int size = list.size(); + // if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) { + // if (oldVal==null) { + // for (int i=0; i itr=list.listIterator(); + // if (oldVal==null) { + // for (int i=0; ii + * such that {@code source.subList(i, i+target.size()).equals(target)}, + * or -1 if there is no such index. (Returns -1 if + * {@code target.size() > source.size()}) + * + *

This implementation uses the "brute force" technique of scanning + * over the source list, looking for a match with the target at each + * location in turn. + * + * @param source the list in which to search for the first occurrence + * of target. + * @param target the list to search for as a subList of source. + * @return the starting position of the first occurrence of the specified + * target list within the specified source list, or -1 if there + * is no such occurrence. + * @since 1.4 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static int indexOfSubList(List source, List target) { + // int sourceSize = source.size(); + // int targetSize = target.size(); + // int maxCandidate = sourceSize - targetSize; + + // if (sourceSize < INDEXOFSUBLIST_THRESHOLD || + // (source instanceof RandomAccess&&target instanceof RandomAccess)) { + // nextCand: + // for (int candidate = 0; candidate <= maxCandidate; candidate++) { + // for (int i=0, j=candidate; i si = source.listIterator(); + // nextCand: + // for (int candidate = 0; candidate <= maxCandidate; candidate++) { + // ListIterator ti = target.listIterator(); + // for (int i=0; ii + * such that {@code source.subList(i, i+target.size()).equals(target)}, + * or -1 if there is no such index. (Returns -1 if + * {@code target.size() > source.size()}) + * + *

This implementation uses the "brute force" technique of iterating + * over the source list, looking for a match with the target at each + * location in turn. + * + * @param source the list in which to search for the last occurrence + * of target. + * @param target the list to search for as a subList of source. + * @return the starting position of the last occurrence of the specified + * target list within the specified source list, or -1 if there + * is no such occurrence. + * @since 1.4 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static int lastIndexOfSubList(List source, List target) { + // int sourceSize = source.size(); + // int targetSize = target.size(); + // int maxCandidate = sourceSize - targetSize; + + // if (sourceSize < INDEXOFSUBLIST_THRESHOLD || + // source instanceof RandomAccess) { // Index access version + // nextCand: + // for (int candidate = maxCandidate; candidate >= 0; candidate--) { + // for (int i=0, j=candidate; i si = source.listIterator(maxCandidate); + // nextCand: + // for (int candidate = maxCandidate; candidate >= 0; candidate--) { + // ListIterator ti = target.listIterator(); + // for (int i=0; iUnsupportedOperationException.

+ * + * The returned collection does not pass the hashCode and equals + * operations through to the backing collection, but relies on + * Object's equals and hashCode methods. This + * is necessary to preserve the contracts of these operations in the case + * that the backing collection is a set or a list.

+ * + * The returned collection will be serializable if the specified collection + * is serializable. + * + * @param the class of the objects in the collection + * @param c the collection for which an unmodifiable view is to be + * returned. + * @return an unmodifiable view of the specified collection. + * + * @diffblue.fullSupport + */ + public static Collection unmodifiableCollection(Collection c) { + return new UnmodifiableCollection<>(c); + } + + /** + * @serial include + */ + static class UnmodifiableCollection implements Collection, Serializable { + // DIFFBLUE MODELS LIBRARY - Not used in model + // private static final long serialVersionUID = 1820017752578914078L; + + final Collection c; + + UnmodifiableCollection(Collection c) { + if (c==null) + throw new NullPointerException(); + this.c = c; + } + + // DIFFBLUE MODELS LIBRARY + // As most of these methods call the inner collection's methods directly, + // is is impractical to reproduce tests for each of these, + // instead we only test size() to ensure that the calls are correctly + // passed to the inner object and add() to ensure that the exception is + // correctly thrown. We also have tests for the inner iterator. + + public int size() {return c.size();} + public boolean isEmpty() {return c.isEmpty();} + public boolean contains(Object o) {return c.contains(o);} + public Object[] toArray() {return c.toArray();} + public T[] toArray(T[] a) {return c.toArray(a);} + public String toString() {return c.toString();} + + public Iterator iterator() { + return new Iterator() { + private final Iterator i = c.iterator(); + + public boolean hasNext() {return i.hasNext();} + public E next() {return i.next();} + public void remove() { + throw new UnsupportedOperationException(); + } + @Override + public void forEachRemaining(Consumer action) { + // Use backing collection version + i.forEachRemaining(action); + } + }; + } + + public boolean add(E e) { + throw new UnsupportedOperationException(); + } + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + public boolean containsAll(Collection coll) { + return c.containsAll(coll); + } + public boolean addAll(Collection coll) { + throw new UnsupportedOperationException(); + } + public boolean removeAll(Collection coll) { + throw new UnsupportedOperationException(); + } + public boolean retainAll(Collection coll) { + throw new UnsupportedOperationException(); + } + public void clear() { + throw new UnsupportedOperationException(); + } + + // Override default methods in Collection + @Override + public void forEach(Consumer action) { + c.forEach(action); + } + @Override + public boolean removeIf(Predicate filter) { + throw new UnsupportedOperationException(); + } + @SuppressWarnings("unchecked") + @Override + public Spliterator spliterator() { + return (Spliterator)c.spliterator(); + } + @SuppressWarnings("unchecked") + @Override + public Stream stream() { + return (Stream)c.stream(); + } + @SuppressWarnings("unchecked") + @Override + public Stream parallelStream() { + return (Stream)c.parallelStream(); + } + } + + /** + * Returns an unmodifiable view of the specified set. This method allows + * modules to provide users with "read-only" access to internal sets. + * Query operations on the returned set "read through" to the specified + * set, and attempts to modify the returned set, whether direct or via its + * iterator, result in an UnsupportedOperationException.

+ * + * The returned set will be serializable if the specified set + * is serializable. + * + * @param the class of the objects in the set + * @param s the set for which an unmodifiable view is to be returned. + * @return an unmodifiable view of the specified set. + * + * @diffblue.fullSupport + */ + public static Set unmodifiableSet(Set s) { + return new UnmodifiableSet<>(s); + } + + /** + * @serial include + */ + static class UnmodifiableSet extends UnmodifiableCollection + implements Set, Serializable { + // DIFFBLUE MODELS LIBRARY - not used in model + // private static final long serialVersionUID = -9215047833775013803L; + + UnmodifiableSet(Set s) {super(s);} + public boolean equals(Object o) {return o == this || c.equals(o);} + public int hashCode() {return c.hashCode();} + } + + /** + * Returns an unmodifiable view of the specified sorted set. This method + * allows modules to provide users with "read-only" access to internal + * sorted sets. Query operations on the returned sorted set "read + * through" to the specified sorted set. Attempts to modify the returned + * sorted set, whether direct, via its iterator, or via its + * subSet, headSet, or tailSet views, result in + * an UnsupportedOperationException.

+ * + * The returned sorted set will be serializable if the specified sorted set + * is serializable. + * + * @param the class of the objects in the set + * @param s the sorted set for which an unmodifiable view is to be + * returned. + * @return an unmodifiable view of the specified sorted set. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static SortedSet unmodifiableSortedSet(SortedSet s) { + // return new UnmodifiableSortedSet<>(s); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class UnmodifiableSortedSet + // extends UnmodifiableSet + // implements SortedSet, Serializable { + // private static final long serialVersionUID = -4929149591599911165L; + // private final SortedSet ss; + + // UnmodifiableSortedSet(SortedSet s) {super(s); ss = s;} + + // public Comparator comparator() {return ss.comparator();} + + // public SortedSet subSet(E fromElement, E toElement) { + // return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement)); + // } + // public SortedSet headSet(E toElement) { + // return new UnmodifiableSortedSet<>(ss.headSet(toElement)); + // } + // public SortedSet tailSet(E fromElement) { + // return new UnmodifiableSortedSet<>(ss.tailSet(fromElement)); + // } + + // public E first() {return ss.first();} + // public E last() {return ss.last();} + // } + + /** + * Returns an unmodifiable view of the specified navigable set. This method + * allows modules to provide users with "read-only" access to internal + * navigable sets. Query operations on the returned navigable set "read + * through" to the specified navigable set. Attempts to modify the returned + * navigable set, whether direct, via its iterator, or via its + * {@code subSet}, {@code headSet}, or {@code tailSet} views, result in + * an {@code UnsupportedOperationException}.

+ * + * The returned navigable set will be serializable if the specified + * navigable set is serializable. + * + * @param the class of the objects in the set + * @param s the navigable set for which an unmodifiable view is to be + * returned + * @return an unmodifiable view of the specified navigable set + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static NavigableSet unmodifiableNavigableSet(NavigableSet s) { + // return new UnmodifiableNavigableSet<>(s); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Wraps a navigable set and disables all of the mutative operations. + * + * @param type of elements + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class UnmodifiableNavigableSet + // extends UnmodifiableSortedSet + // implements NavigableSet, Serializable { + + // private static final long serialVersionUID = -6027448201786391929L; + + // /** + // * A singleton empty unmodifiable navigable set used for + // * {@link #emptyNavigableSet()}. + // * + // * @param type of elements, if there were any, and bounds + // */ + // private static class EmptyNavigableSet extends UnmodifiableNavigableSet + // implements Serializable { + // private static final long serialVersionUID = -6291252904449939134L; + + // public EmptyNavigableSet() { + // super(new TreeSet()); + // } + + // private Object readResolve() { return EMPTY_NAVIGABLE_SET; } + // } + + // @SuppressWarnings("rawtypes") + // private static final NavigableSet EMPTY_NAVIGABLE_SET = + // new EmptyNavigableSet<>(); + + // /** + // * The instance we are protecting. + // */ + // private final NavigableSet ns; + + // UnmodifiableNavigableSet(NavigableSet s) {super(s); ns = s;} + + // public E lower(E e) { return ns.lower(e); } + // public E floor(E e) { return ns.floor(e); } + // public E ceiling(E e) { return ns.ceiling(e); } + // public E higher(E e) { return ns.higher(e); } + // public E pollFirst() { throw new UnsupportedOperationException(); } + // public E pollLast() { throw new UnsupportedOperationException(); } + // public NavigableSet descendingSet() + // { return new UnmodifiableNavigableSet<>(ns.descendingSet()); } + // public Iterator descendingIterator() + // { return descendingSet().iterator(); } + + // public NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { + // return new UnmodifiableNavigableSet<>( + // ns.subSet(fromElement, fromInclusive, toElement, toInclusive)); + // } + + // public NavigableSet headSet(E toElement, boolean inclusive) { + // return new UnmodifiableNavigableSet<>( + // ns.headSet(toElement, inclusive)); + // } + + // public NavigableSet tailSet(E fromElement, boolean inclusive) { + // return new UnmodifiableNavigableSet<>( + // ns.tailSet(fromElement, inclusive)); + // } + // } + + /** + * Returns an unmodifiable view of the specified list. This method allows + * modules to provide users with "read-only" access to internal + * lists. Query operations on the returned list "read through" to the + * specified list, and attempts to modify the returned list, whether + * direct or via its iterator, result in an + * UnsupportedOperationException.

+ * + * The returned list will be serializable if the specified list + * is serializable. Similarly, the returned list will implement + * {@link RandomAccess} if the specified list does. + * + * @param the class of the objects in the list + * @param list the list for which an unmodifiable view is to be returned. + * @return an unmodifiable view of the specified list. + * + * @diffblue.fullSupport + */ + public static List unmodifiableList(List list) { + return (list instanceof RandomAccess ? + new UnmodifiableRandomAccessList<>(list) : + new UnmodifiableList<>(list)); + } + + /** + * @serial include + */ + static class UnmodifiableList extends UnmodifiableCollection + implements List { + // private static final long serialVersionUID = -283967356065247728L; + + final List list; + + UnmodifiableList(List list) { + super(list); + this.list = list; + } + + // DIFFBLUE MODELS LIBRARY + // As most of these methods call the inner collection's methods directly, + // is is impractical to reproduce tests for each of these, + // instead we only test get() to ensure that the calls are correctly + // passed to the inner object and add() to ensure that the exception is + // correctly thrown. We also have tests for the inner iterator. + + public boolean equals(Object o) {return o == this || list.equals(o);} + public int hashCode() {return list.hashCode();} + + public E get(int index) {return list.get(index);} + public E set(int index, E element) { + throw new UnsupportedOperationException(); + } + public void add(int index, E element) { + throw new UnsupportedOperationException(); + } + public E remove(int index) { + throw new UnsupportedOperationException(); + } + public int indexOf(Object o) {return list.indexOf(o);} + public int lastIndexOf(Object o) {return list.lastIndexOf(o);} + public boolean addAll(int index, Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public void replaceAll(UnaryOperator operator) { + throw new UnsupportedOperationException(); + } + @Override + public void sort(Comparator c) { + throw new UnsupportedOperationException(); + } + + public ListIterator listIterator() {return listIterator(0);} + + public ListIterator listIterator(final int index) { + return new ListIterator() { + private final ListIterator i + = list.listIterator(index); + + public boolean hasNext() {return i.hasNext();} + public E next() {return i.next();} + public boolean hasPrevious() {return i.hasPrevious();} + public E previous() {return i.previous();} + public int nextIndex() {return i.nextIndex();} + public int previousIndex() {return i.previousIndex();} + + public void remove() { + throw new UnsupportedOperationException(); + } + public void set(E e) { + throw new UnsupportedOperationException(); + } + public void add(E e) { + throw new UnsupportedOperationException(); + } + + @Override + public void forEachRemaining(Consumer action) { + i.forEachRemaining(action); + } + }; + } + + public List subList(int fromIndex, int toIndex) { + return new UnmodifiableList<>(list.subList(fromIndex, toIndex)); + } + + /** + * UnmodifiableRandomAccessList instances are serialized as + * UnmodifiableList instances to allow them to be deserialized + * in pre-1.4 JREs (which do not have UnmodifiableRandomAccessList). + * This method inverts the transformation. As a beneficial + * side-effect, it also grafts the RandomAccess marker onto + * UnmodifiableList instances that were serialized in pre-1.4 JREs. + * + * Note: Unfortunately, UnmodifiableRandomAccessList instances + * serialized in 1.4.1 and deserialized in 1.4 will become + * UnmodifiableList instances, as this method was missing in 1.4. + */ + // private Object readResolve() { + // return (list instanceof RandomAccess + // ? new UnmodifiableRandomAccessList<>(list) + // : this); + // } + } + + /** + * @serial include + */ + static class UnmodifiableRandomAccessList extends UnmodifiableList + implements RandomAccess + { + UnmodifiableRandomAccessList(List list) { + super(list); + } + + public List subList(int fromIndex, int toIndex) { + return new UnmodifiableRandomAccessList<>( + list.subList(fromIndex, toIndex)); + } + + // private static final long serialVersionUID = -2542308836966382001L; + + // /** + // * Allows instances to be deserialized in pre-1.4 JREs (which do + // * not have UnmodifiableRandomAccessList). UnmodifiableList has + // * a readResolve method that inverts this transformation upon + // * deserialization. + // */ + // private Object writeReplace() { + // return new UnmodifiableList<>(list); + // } + } + + /** + * Returns an unmodifiable view of the specified map. This method + * allows modules to provide users with "read-only" access to internal + * maps. Query operations on the returned map "read through" + * to the specified map, and attempts to modify the returned + * map, whether direct or via its collection views, result in an + * UnsupportedOperationException.

+ * + * The returned map will be serializable if the specified map + * is serializable. + * + * @param the class of the map keys + * @param the class of the map values + * @param m the map for which an unmodifiable view is to be returned. + * @return an unmodifiable view of the specified map. + * + * @diffblue.fullSupport + */ + public static Map unmodifiableMap(Map m) { + return new UnmodifiableMap<>(m); + } + + /** + * @serial include + */ + private static class UnmodifiableMap implements Map, Serializable { + // DIFFBLUE MODELS LIBRARY - not used in model + // private static final long serialVersionUID = -1034234728574286014L; + + private final Map m; + + UnmodifiableMap(Map m) { + if (m==null) + throw new NullPointerException(); + this.m = m; + } + + // DIFFBLUE MODELS LIBRARY + // As most of these methods call the inner collection's methods directly, + // is is impractical to reproduce tests for each of these, + // instead we only test size() to ensure that the calls are correctly + // passed to the inner object and put() to ensure that the exception is + // correctly thrown. We also have tests for the inner iterator. + + public int size() {return m.size();} + public boolean isEmpty() {return m.isEmpty();} + public boolean containsKey(Object key) {return m.containsKey(key);} + public boolean containsValue(Object val) {return m.containsValue(val);} + public V get(Object key) {return m.get(key);} + + public V put(K key, V value) { + throw new UnsupportedOperationException(); + } + public V remove(Object key) { + throw new UnsupportedOperationException(); + } + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + public void clear() { + throw new UnsupportedOperationException(); + } + + // DIFFBLUE MODELS LIBRARY - Not used in model + // private transient Set keySet; + // private transient Set> entrySet; + // private transient Collection values; + + public Set keySet() { + // if (keySet==null) + // keySet = unmodifiableSet(m.keySet()); + // return keySet; + return unmodifiableSet(m.keySet()); + } + + public Set> entrySet() { + // if (entrySet==null) + // entrySet = new UnmodifiableEntrySet<>(m.entrySet()); + // return entrySet; + return new UnmodifiableEntrySet<>(m.entrySet()); + } + + public Collection values() { + // if (values==null) + // values = unmodifiableCollection(m.values()); + // return values; + return unmodifiableCollection(m.values()); + } + + public boolean equals(Object o) {return o == this || m.equals(o);} + public int hashCode() {return m.hashCode();} + public String toString() {return m.toString();} + + // Override default methods in Map + @Override + @SuppressWarnings("unchecked") + public V getOrDefault(Object k, V defaultValue) { + // Safe cast as we don't change the value + return ((Map)m).getOrDefault(k, defaultValue); + } + + @Override + public void forEach(BiConsumer action) { + m.forEach(action); + } + + @Override + public void replaceAll(BiFunction function) { + throw new UnsupportedOperationException(); + } + + @Override + public V putIfAbsent(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object key, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean replace(K key, V oldValue, V newValue) { + throw new UnsupportedOperationException(); + } + + @Override + public V replace(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public V computeIfAbsent(K key, Function mappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public V computeIfPresent(K key, + BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public V compute(K key, + BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public V merge(K key, V value, + BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + /** + * We need this class in addition to UnmodifiableSet as + * Map.Entries themselves permit modification of the backing Map + * via their setValue operation. This class is subtle: there are + * many possible attacks that must be thwarted. + * + * @serial include + */ + static class UnmodifiableEntrySet + extends UnmodifiableSet> { + // private static final long serialVersionUID = 7854390611657943733L; + + @SuppressWarnings({"unchecked", "rawtypes"}) + UnmodifiableEntrySet(Set> s) { + // Need to cast to raw in order to work around a limitation in the type system + super((Set)s); + } + + static Consumer> entryConsumer(Consumer> action) { + return e -> action.accept(new UnmodifiableEntry<>(e)); + } + + public void forEach(Consumer> action) { + Objects.requireNonNull(action); + c.forEach(entryConsumer(action)); + } + + static final class UnmodifiableEntrySetSpliterator + implements Spliterator> { + final Spliterator> s; + + UnmodifiableEntrySetSpliterator(Spliterator> s) { + this.s = s; + } + + @Override + public boolean tryAdvance(Consumer> action) { + Objects.requireNonNull(action); + return s.tryAdvance(entryConsumer(action)); + } + + @Override + public void forEachRemaining(Consumer> action) { + Objects.requireNonNull(action); + s.forEachRemaining(entryConsumer(action)); + } + + @Override + public Spliterator> trySplit() { + Spliterator> split = s.trySplit(); + return split == null + ? null + : new UnmodifiableEntrySetSpliterator<>(split); + } + + @Override + public long estimateSize() { + return s.estimateSize(); + } + + @Override + public long getExactSizeIfKnown() { + return s.getExactSizeIfKnown(); + } + + @Override + public int characteristics() { + return s.characteristics(); + } + + @Override + public boolean hasCharacteristics(int characteristics) { + return s.hasCharacteristics(characteristics); + } + + @Override + public Comparator> getComparator() { + return s.getComparator(); + } + } + + @SuppressWarnings("unchecked") + public Spliterator> spliterator() { + return new UnmodifiableEntrySetSpliterator<>( + (Spliterator>) c.spliterator()); + } + + @Override + public Stream> stream() { + return StreamSupport.stream(spliterator(), false); + } + + @Override + public Stream> parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + public Iterator> iterator() { + return new Iterator>() { + private final Iterator> i = c.iterator(); + + public boolean hasNext() { + return i.hasNext(); + } + public Map.Entry next() { + return new UnmodifiableEntry<>(i.next()); + } + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + @SuppressWarnings("unchecked") + public Object[] toArray() { + Object[] a = c.toArray(); + for (int i=0; i((Map.Entry)a[i]); + return a; + } + + @SuppressWarnings("unchecked") + public T[] toArray(T[] a) { + // We don't pass a to c.toArray, to avoid window of + // vulnerability wherein an unscrupulous multithreaded client + // could get his hands on raw (unwrapped) Entries from c. + Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0)); + + for (int i=0; i((Map.Entry)arr[i]); + + if (arr.length > a.length) + return (T[])arr; + + System.arraycopy(arr, 0, a, 0, arr.length); + if (a.length > arr.length) + a[arr.length] = null; + return a; + } + + /** + * This method is overridden to protect the backing set against + * an object with a nefarious equals function that senses + * that the equality-candidate is Map.Entry and calls its + * setValue method. + */ + public boolean contains(Object o) { + if (!(o instanceof Map.Entry)) + return false; + return c.contains( + new UnmodifiableEntry<>((Map.Entry) o)); + } + + /** + * The next two methods are overridden to protect against + * an unscrupulous List whose contains(Object o) method senses + * when o is a Map.Entry, and calls o.setValue. + */ + public boolean containsAll(Collection coll) { + for (Object e : coll) { + if (!contains(e)) // Invokes safe contains() above + return false; + } + return true; + } + public boolean equals(Object o) { + if (o == this) + return true; + + if (!(o instanceof Set)) + return false; + Set s = (Set) o; + if (s.size() != c.size()) + return false; + return containsAll(s); // Invokes safe containsAll() above + } + + /** + * This "wrapper class" serves two purposes: it prevents + * the client from modifying the backing Map, by short-circuiting + * the setValue method, and it protects the backing Map against + * an ill-behaved Map.Entry that attempts to modify another + * Map Entry when asked to perform an equality check. + */ + private static class UnmodifiableEntry implements Map.Entry { + private Map.Entry e; + + UnmodifiableEntry(Map.Entry e) + {this.e = Objects.requireNonNull(e);} + + public K getKey() {return e.getKey();} + public V getValue() {return e.getValue();} + public V setValue(V value) { + throw new UnsupportedOperationException(); + } + public int hashCode() {return e.hashCode();} + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof Map.Entry)) + return false; + Map.Entry t = (Map.Entry)o; + return eq(e.getKey(), t.getKey()) && + eq(e.getValue(), t.getValue()); + } + public String toString() {return e.toString();} + } + } + } + + /** + * Returns an unmodifiable view of the specified sorted map. This method + * allows modules to provide users with "read-only" access to internal + * sorted maps. Query operations on the returned sorted map "read through" + * to the specified sorted map. Attempts to modify the returned + * sorted map, whether direct, via its collection views, or via its + * subMap, headMap, or tailMap views, result in + * an UnsupportedOperationException.

+ * + * The returned sorted map will be serializable if the specified sorted map + * is serializable. + * + * @param the class of the map keys + * @param the class of the map values + * @param m the sorted map for which an unmodifiable view is to be + * returned. + * @return an unmodifiable view of the specified sorted map. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static SortedMap unmodifiableSortedMap(SortedMap m) { + // return new UnmodifiableSortedMap<>(m); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class UnmodifiableSortedMap + // extends UnmodifiableMap + // implements SortedMap, Serializable { + // private static final long serialVersionUID = -8806743815996713206L; + + // private final SortedMap sm; + + // UnmodifiableSortedMap(SortedMap m) {super(m); sm = m; } + // public Comparator comparator() { return sm.comparator(); } + // public SortedMap subMap(K fromKey, K toKey) + // { return new UnmodifiableSortedMap<>(sm.subMap(fromKey, toKey)); } + // public SortedMap headMap(K toKey) + // { return new UnmodifiableSortedMap<>(sm.headMap(toKey)); } + // public SortedMap tailMap(K fromKey) + // { return new UnmodifiableSortedMap<>(sm.tailMap(fromKey)); } + // public K firstKey() { return sm.firstKey(); } + // public K lastKey() { return sm.lastKey(); } + // } + + /** + * Returns an unmodifiable view of the specified navigable map. This method + * allows modules to provide users with "read-only" access to internal + * navigable maps. Query operations on the returned navigable map "read + * through" to the specified navigable map. Attempts to modify the returned + * navigable map, whether direct, via its collection views, or via its + * {@code subMap}, {@code headMap}, or {@code tailMap} views, result in + * an {@code UnsupportedOperationException}.

+ * + * The returned navigable map will be serializable if the specified + * navigable map is serializable. + * + * @param the class of the map keys + * @param the class of the map values + * @param m the navigable map for which an unmodifiable view is to be + * returned + * @return an unmodifiable view of the specified navigable map + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static NavigableMap unmodifiableNavigableMap(NavigableMap m) { + // return new UnmodifiableNavigableMap<>(m); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class UnmodifiableNavigableMap + // extends UnmodifiableSortedMap + // implements NavigableMap, Serializable { + // private static final long serialVersionUID = -4858195264774772197L; + + // /** + // * A class for the {@link EMPTY_NAVIGABLE_MAP} which needs readResolve + // * to preserve singleton property. + // * + // * @param type of keys, if there were any, and of bounds + // * @param type of values, if there were any + // */ + // private static class EmptyNavigableMap extends UnmodifiableNavigableMap + // implements Serializable { + + // private static final long serialVersionUID = -2239321462712562324L; + + // EmptyNavigableMap() { super(new TreeMap()); } + + // @Override + // public NavigableSet navigableKeySet() + // { return emptyNavigableSet(); } + + // private Object readResolve() { return EMPTY_NAVIGABLE_MAP; } + // } + + // /** + // * Singleton for {@link emptyNavigableMap()} which is also immutable. + // */ + // private static final EmptyNavigableMap EMPTY_NAVIGABLE_MAP = + // new EmptyNavigableMap<>(); + + // /** + // * The instance we wrap and protect. + // */ + // private final NavigableMap nm; + + // UnmodifiableNavigableMap(NavigableMap m) + // {super(m); nm = m;} + + // public K lowerKey(K key) { return nm.lowerKey(key); } + // public K floorKey(K key) { return nm.floorKey(key); } + // public K ceilingKey(K key) { return nm.ceilingKey(key); } + // public K higherKey(K key) { return nm.higherKey(key); } + + // @SuppressWarnings("unchecked") + // public Entry lowerEntry(K key) { + // Entry lower = (Entry) nm.lowerEntry(key); + // return (null != lower) + // ? new UnmodifiableEntrySet.UnmodifiableEntry<>(lower) + // : null; + // } + + // @SuppressWarnings("unchecked") + // public Entry floorEntry(K key) { + // Entry floor = (Entry) nm.floorEntry(key); + // return (null != floor) + // ? new UnmodifiableEntrySet.UnmodifiableEntry<>(floor) + // : null; + // } + + // @SuppressWarnings("unchecked") + // public Entry ceilingEntry(K key) { + // Entry ceiling = (Entry) nm.ceilingEntry(key); + // return (null != ceiling) + // ? new UnmodifiableEntrySet.UnmodifiableEntry<>(ceiling) + // : null; + // } + + + // @SuppressWarnings("unchecked") + // public Entry higherEntry(K key) { + // Entry higher = (Entry) nm.higherEntry(key); + // return (null != higher) + // ? new UnmodifiableEntrySet.UnmodifiableEntry<>(higher) + // : null; + // } + + // @SuppressWarnings("unchecked") + // public Entry firstEntry() { + // Entry first = (Entry) nm.firstEntry(); + // return (null != first) + // ? new UnmodifiableEntrySet.UnmodifiableEntry<>(first) + // : null; + // } + + // @SuppressWarnings("unchecked") + // public Entry lastEntry() { + // Entry last = (Entry) nm.lastEntry(); + // return (null != last) + // ? new UnmodifiableEntrySet.UnmodifiableEntry<>(last) + // : null; + // } + + // public Entry pollFirstEntry() + // { throw new UnsupportedOperationException(); } + // public Entry pollLastEntry() + // { throw new UnsupportedOperationException(); } + // public NavigableMap descendingMap() + // { return unmodifiableNavigableMap(nm.descendingMap()); } + // public NavigableSet navigableKeySet() + // { return unmodifiableNavigableSet(nm.navigableKeySet()); } + // public NavigableSet descendingKeySet() + // { return unmodifiableNavigableSet(nm.descendingKeySet()); } + + // public NavigableMap subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { + // return unmodifiableNavigableMap( + // nm.subMap(fromKey, fromInclusive, toKey, toInclusive)); + // } + + // public NavigableMap headMap(K toKey, boolean inclusive) + // { return unmodifiableNavigableMap(nm.headMap(toKey, inclusive)); } + // public NavigableMap tailMap(K fromKey, boolean inclusive) + // { return unmodifiableNavigableMap(nm.tailMap(fromKey, inclusive)); } + // } + + // Synch Wrappers + + /** + * Returns a synchronized (thread-safe) collection backed by the specified + * collection. In order to guarantee serial access, it is critical that + * all access to the backing collection is accomplished + * through the returned collection.

+ * + * It is imperative that the user manually synchronize on the returned + * collection when traversing it via {@link Iterator}, {@link Spliterator} + * or {@link Stream}: + *

+     *  Collection c = Collections.synchronizedCollection(myCollection);
+     *     ...
+     *  synchronized (c) {
+     *      Iterator i = c.iterator(); // Must be in the synchronized block
+     *      while (i.hasNext())
+     *         foo(i.next());
+     *  }
+     * 
+ * Failure to follow this advice may result in non-deterministic behavior. + * + *

The returned collection does not pass the {@code hashCode} + * and {@code equals} operations through to the backing collection, but + * relies on {@code Object}'s equals and hashCode methods. This is + * necessary to preserve the contracts of these operations in the case + * that the backing collection is a set or a list.

+ * + * The returned collection will be serializable if the specified collection + * is serializable. + * + * @param the class of the objects in the collection + * @param c the collection to be "wrapped" in a synchronized collection. + * @return a synchronized view of the specified collection. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Collection synchronizedCollection(Collection c) { + // return new SynchronizedCollection<>(c); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // static Collection synchronizedCollection(Collection c, Object mutex) { + // return new SynchronizedCollection<>(c, mutex); + // } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class SynchronizedCollection implements Collection, Serializable { + // private static final long serialVersionUID = 3053995032091335093L; + + // final Collection c; // Backing Collection + // final Object mutex; // Object on which to synchronize + + // SynchronizedCollection(Collection c) { + // this.c = Objects.requireNonNull(c); + // mutex = this; + // } + + // SynchronizedCollection(Collection c, Object mutex) { + // this.c = Objects.requireNonNull(c); + // this.mutex = Objects.requireNonNull(mutex); + // } + + // public int size() { + // synchronized (mutex) {return c.size();} + // } + // public boolean isEmpty() { + // synchronized (mutex) {return c.isEmpty();} + // } + // public boolean contains(Object o) { + // synchronized (mutex) {return c.contains(o);} + // } + // public Object[] toArray() { + // synchronized (mutex) {return c.toArray();} + // } + // public T[] toArray(T[] a) { + // synchronized (mutex) {return c.toArray(a);} + // } + + // public Iterator iterator() { + // return c.iterator(); // Must be manually synched by user! + // } + + // public boolean add(E e) { + // synchronized (mutex) {return c.add(e);} + // } + // public boolean remove(Object o) { + // synchronized (mutex) {return c.remove(o);} + // } + + // public boolean containsAll(Collection coll) { + // synchronized (mutex) {return c.containsAll(coll);} + // } + // public boolean addAll(Collection coll) { + // synchronized (mutex) {return c.addAll(coll);} + // } + // public boolean removeAll(Collection coll) { + // synchronized (mutex) {return c.removeAll(coll);} + // } + // public boolean retainAll(Collection coll) { + // synchronized (mutex) {return c.retainAll(coll);} + // } + // public void clear() { + // synchronized (mutex) {c.clear();} + // } + // public String toString() { + // synchronized (mutex) {return c.toString();} + // } + // // Override default methods in Collection + // @Override + // public void forEach(Consumer consumer) { + // synchronized (mutex) {c.forEach(consumer);} + // } + // @Override + // public boolean removeIf(Predicate filter) { + // synchronized (mutex) {return c.removeIf(filter);} + // } + // @Override + // public Spliterator spliterator() { + // return c.spliterator(); // Must be manually synched by user! + // } + // @Override + // public Stream stream() { + // return c.stream(); // Must be manually synched by user! + // } + // @Override + // public Stream parallelStream() { + // return c.parallelStream(); // Must be manually synched by user! + // } + // private void writeObject(ObjectOutputStream s) throws IOException { + // synchronized (mutex) {s.defaultWriteObject();} + // } + // } + + /** + * Returns a synchronized (thread-safe) set backed by the specified + * set. In order to guarantee serial access, it is critical that + * all access to the backing set is accomplished + * through the returned set.

+ * + * It is imperative that the user manually synchronize on the returned + * set when iterating over it: + *

+     *  Set s = Collections.synchronizedSet(new HashSet());
+     *      ...
+     *  synchronized (s) {
+     *      Iterator i = s.iterator(); // Must be in the synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * Failure to follow this advice may result in non-deterministic behavior. + * + *

The returned set will be serializable if the specified set is + * serializable. + * + * @param the class of the objects in the set + * @param s the set to be "wrapped" in a synchronized set. + * @return a synchronized view of the specified set. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Set synchronizedSet(Set s) { + // return new SynchronizedSet<>(s); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // static Set synchronizedSet(Set s, Object mutex) { + // return new SynchronizedSet<>(s, mutex); + // } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class SynchronizedSet + // extends SynchronizedCollection + // implements Set { + // private static final long serialVersionUID = 487447009682186044L; + + // SynchronizedSet(Set s) { + // super(s); + // } + // SynchronizedSet(Set s, Object mutex) { + // super(s, mutex); + // } + + // public boolean equals(Object o) { + // if (this == o) + // return true; + // synchronized (mutex) {return c.equals(o);} + // } + // public int hashCode() { + // synchronized (mutex) {return c.hashCode();} + // } + // } + + /** + * Returns a synchronized (thread-safe) sorted set backed by the specified + * sorted set. In order to guarantee serial access, it is critical that + * all access to the backing sorted set is accomplished + * through the returned sorted set (or its views).

+ * + * It is imperative that the user manually synchronize on the returned + * sorted set when iterating over it or any of its subSet, + * headSet, or tailSet views. + *

+     *  SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
+     *      ...
+     *  synchronized (s) {
+     *      Iterator i = s.iterator(); // Must be in the synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * or: + *
+     *  SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
+     *  SortedSet s2 = s.headSet(foo);
+     *      ...
+     *  synchronized (s) {  // Note: s, not s2!!!
+     *      Iterator i = s2.iterator(); // Must be in the synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * Failure to follow this advice may result in non-deterministic behavior. + * + *

The returned sorted set will be serializable if the specified + * sorted set is serializable. + * + * @param the class of the objects in the set + * @param s the sorted set to be "wrapped" in a synchronized sorted set. + * @return a synchronized view of the specified sorted set. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static SortedSet synchronizedSortedSet(SortedSet s) { + // return new SynchronizedSortedSet<>(s); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class SynchronizedSortedSet + // extends SynchronizedSet + // implements SortedSet + // { + // private static final long serialVersionUID = 8695801310862127406L; + + // private final SortedSet ss; + + // SynchronizedSortedSet(SortedSet s) { + // super(s); + // ss = s; + // } + // SynchronizedSortedSet(SortedSet s, Object mutex) { + // super(s, mutex); + // ss = s; + // } + + // public Comparator comparator() { + // synchronized (mutex) {return ss.comparator();} + // } + + // public SortedSet subSet(E fromElement, E toElement) { + // synchronized (mutex) { + // return new SynchronizedSortedSet<>( + // ss.subSet(fromElement, toElement), mutex); + // } + // } + // public SortedSet headSet(E toElement) { + // synchronized (mutex) { + // return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex); + // } + // } + // public SortedSet tailSet(E fromElement) { + // synchronized (mutex) { + // return new SynchronizedSortedSet<>(ss.tailSet(fromElement),mutex); + // } + // } + + // public E first() { + // synchronized (mutex) {return ss.first();} + // } + // public E last() { + // synchronized (mutex) {return ss.last();} + // } + // } + + /** + * Returns a synchronized (thread-safe) navigable set backed by the + * specified navigable set. In order to guarantee serial access, it is + * critical that all access to the backing navigable set is + * accomplished through the returned navigable set (or its views).

+ * + * It is imperative that the user manually synchronize on the returned + * navigable set when iterating over it or any of its {@code subSet}, + * {@code headSet}, or {@code tailSet} views. + *

+     *  NavigableSet s = Collections.synchronizedNavigableSet(new TreeSet());
+     *      ...
+     *  synchronized (s) {
+     *      Iterator i = s.iterator(); // Must be in the synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * or: + *
+     *  NavigableSet s = Collections.synchronizedNavigableSet(new TreeSet());
+     *  NavigableSet s2 = s.headSet(foo, true);
+     *      ...
+     *  synchronized (s) {  // Note: s, not s2!!!
+     *      Iterator i = s2.iterator(); // Must be in the synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * Failure to follow this advice may result in non-deterministic behavior. + * + *

The returned navigable set will be serializable if the specified + * navigable set is serializable. + * + * @param the class of the objects in the set + * @param s the navigable set to be "wrapped" in a synchronized navigable + * set + * @return a synchronized view of the specified navigable set + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static NavigableSet synchronizedNavigableSet(NavigableSet s) { + // return new SynchronizedNavigableSet<>(s); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class SynchronizedNavigableSet + // extends SynchronizedSortedSet + // implements NavigableSet + // { + // private static final long serialVersionUID = -5505529816273629798L; + + // private final NavigableSet ns; + + // SynchronizedNavigableSet(NavigableSet s) { + // super(s); + // ns = s; + // } + + // SynchronizedNavigableSet(NavigableSet s, Object mutex) { + // super(s, mutex); + // ns = s; + // } + // public E lower(E e) { synchronized (mutex) {return ns.lower(e);} } + // public E floor(E e) { synchronized (mutex) {return ns.floor(e);} } + // public E ceiling(E e) { synchronized (mutex) {return ns.ceiling(e);} } + // public E higher(E e) { synchronized (mutex) {return ns.higher(e);} } + // public E pollFirst() { synchronized (mutex) {return ns.pollFirst();} } + // public E pollLast() { synchronized (mutex) {return ns.pollLast();} } + + // public NavigableSet descendingSet() { + // synchronized (mutex) { + // return new SynchronizedNavigableSet<>(ns.descendingSet(), mutex); + // } + // } + + // public Iterator descendingIterator() + // { synchronized (mutex) { return descendingSet().iterator(); } } + + // public NavigableSet subSet(E fromElement, E toElement) { + // synchronized (mutex) { + // return new SynchronizedNavigableSet<>(ns.subSet(fromElement, true, toElement, false), mutex); + // } + // } + // public NavigableSet headSet(E toElement) { + // synchronized (mutex) { + // return new SynchronizedNavigableSet<>(ns.headSet(toElement, false), mutex); + // } + // } + // public NavigableSet tailSet(E fromElement) { + // synchronized (mutex) { + // return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, true), mutex); + // } + // } + + // public NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { + // synchronized (mutex) { + // return new SynchronizedNavigableSet<>(ns.subSet(fromElement, fromInclusive, toElement, toInclusive), mutex); + // } + // } + + // public NavigableSet headSet(E toElement, boolean inclusive) { + // synchronized (mutex) { + // return new SynchronizedNavigableSet<>(ns.headSet(toElement, inclusive), mutex); + // } + // } + + // public NavigableSet tailSet(E fromElement, boolean inclusive) { + // synchronized (mutex) { + // return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, inclusive), mutex); + // } + // } + // } + + /** + * Returns a synchronized (thread-safe) list backed by the specified + * list. In order to guarantee serial access, it is critical that + * all access to the backing list is accomplished + * through the returned list.

+ * + * It is imperative that the user manually synchronize on the returned + * list when iterating over it: + *

+     *  List list = Collections.synchronizedList(new ArrayList());
+     *      ...
+     *  synchronized (list) {
+     *      Iterator i = list.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * Failure to follow this advice may result in non-deterministic behavior. + * + *

The returned list will be serializable if the specified list is + * serializable. + * + * @param the class of the objects in the list + * @param list the list to be "wrapped" in a synchronized list. + * @return a synchronized view of the specified list. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static List synchronizedList(List list) { + // return (list instanceof RandomAccess ? + // new SynchronizedRandomAccessList<>(list) : + // new SynchronizedList<>(list)); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // static List synchronizedList(List list, Object mutex) { + // return (list instanceof RandomAccess ? + // new SynchronizedRandomAccessList<>(list, mutex) : + // new SynchronizedList<>(list, mutex)); + // } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class SynchronizedList + // extends SynchronizedCollection + // implements List { + // private static final long serialVersionUID = -7754090372962971524L; + + // final List list; + + // SynchronizedList(List list) { + // super(list); + // this.list = list; + // } + // SynchronizedList(List list, Object mutex) { + // super(list, mutex); + // this.list = list; + // } + + // public boolean equals(Object o) { + // if (this == o) + // return true; + // synchronized (mutex) {return list.equals(o);} + // } + // public int hashCode() { + // synchronized (mutex) {return list.hashCode();} + // } + + // public E get(int index) { + // synchronized (mutex) {return list.get(index);} + // } + // public E set(int index, E element) { + // synchronized (mutex) {return list.set(index, element);} + // } + // public void add(int index, E element) { + // synchronized (mutex) {list.add(index, element);} + // } + // public E remove(int index) { + // synchronized (mutex) {return list.remove(index);} + // } + + // public int indexOf(Object o) { + // synchronized (mutex) {return list.indexOf(o);} + // } + // public int lastIndexOf(Object o) { + // synchronized (mutex) {return list.lastIndexOf(o);} + // } + + // public boolean addAll(int index, Collection c) { + // synchronized (mutex) {return list.addAll(index, c);} + // } + + // public ListIterator listIterator() { + // return list.listIterator(); // Must be manually synched by user + // } + + // public ListIterator listIterator(int index) { + // return list.listIterator(index); // Must be manually synched by user + // } + + // public List subList(int fromIndex, int toIndex) { + // synchronized (mutex) { + // return new SynchronizedList<>(list.subList(fromIndex, toIndex), + // mutex); + // } + // } + + // @Override + // public void replaceAll(UnaryOperator operator) { + // synchronized (mutex) {list.replaceAll(operator);} + // } + // @Override + // public void sort(Comparator c) { + // synchronized (mutex) {list.sort(c);} + // } + + // /** + // * SynchronizedRandomAccessList instances are serialized as + // * SynchronizedList instances to allow them to be deserialized + // * in pre-1.4 JREs (which do not have SynchronizedRandomAccessList). + // * This method inverts the transformation. As a beneficial + // * side-effect, it also grafts the RandomAccess marker onto + // * SynchronizedList instances that were serialized in pre-1.4 JREs. + // * + // * Note: Unfortunately, SynchronizedRandomAccessList instances + // * serialized in 1.4.1 and deserialized in 1.4 will become + // * SynchronizedList instances, as this method was missing in 1.4. + // */ + // private Object readResolve() { + // return (list instanceof RandomAccess + // ? new SynchronizedRandomAccessList<>(list) + // : this); + // } + // } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class SynchronizedRandomAccessList + // extends SynchronizedList + // implements RandomAccess { + + // SynchronizedRandomAccessList(List list) { + // super(list); + // } + + // SynchronizedRandomAccessList(List list, Object mutex) { + // super(list, mutex); + // } + + // public List subList(int fromIndex, int toIndex) { + // synchronized (mutex) { + // return new SynchronizedRandomAccessList<>( + // list.subList(fromIndex, toIndex), mutex); + // } + // } + + // private static final long serialVersionUID = 1530674583602358482L; + + // /** + // * Allows instances to be deserialized in pre-1.4 JREs (which do + // * not have SynchronizedRandomAccessList). SynchronizedList has + // * a readResolve method that inverts this transformation upon + // * deserialization. + // */ + // private Object writeReplace() { + // return new SynchronizedList<>(list); + // } + // } + + /** + * Returns a synchronized (thread-safe) map backed by the specified + * map. In order to guarantee serial access, it is critical that + * all access to the backing map is accomplished + * through the returned map.

+ * + * It is imperative that the user manually synchronize on the returned + * map when iterating over any of its collection views: + *

+     *  Map m = Collections.synchronizedMap(new HashMap());
+     *      ...
+     *  Set s = m.keySet();  // Needn't be in synchronized block
+     *      ...
+     *  synchronized (m) {  // Synchronizing on m, not s!
+     *      Iterator i = s.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * Failure to follow this advice may result in non-deterministic behavior. + * + *

The returned map will be serializable if the specified map is + * serializable. + * + * @param the class of the map keys + * @param the class of the map values + * @param m the map to be "wrapped" in a synchronized map. + * @return a synchronized view of the specified map. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Map synchronizedMap(Map m) { + // return new SynchronizedMap<>(m); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static class SynchronizedMap + // implements Map, Serializable { + // private static final long serialVersionUID = 1978198479659022715L; + + // private final Map m; // Backing Map + // final Object mutex; // Object on which to synchronize + + // SynchronizedMap(Map m) { + // this.m = Objects.requireNonNull(m); + // mutex = this; + // } + + // SynchronizedMap(Map m, Object mutex) { + // this.m = m; + // this.mutex = mutex; + // } + + // public int size() { + // synchronized (mutex) {return m.size();} + // } + // public boolean isEmpty() { + // synchronized (mutex) {return m.isEmpty();} + // } + // public boolean containsKey(Object key) { + // synchronized (mutex) {return m.containsKey(key);} + // } + // public boolean containsValue(Object value) { + // synchronized (mutex) {return m.containsValue(value);} + // } + // public V get(Object key) { + // synchronized (mutex) {return m.get(key);} + // } + + // public V put(K key, V value) { + // synchronized (mutex) {return m.put(key, value);} + // } + // public V remove(Object key) { + // synchronized (mutex) {return m.remove(key);} + // } + // public void putAll(Map map) { + // synchronized (mutex) {m.putAll(map);} + // } + // public void clear() { + // synchronized (mutex) {m.clear();} + // } + + // private transient Set keySet; + // private transient Set> entrySet; + // private transient Collection values; + + // public Set keySet() { + // synchronized (mutex) { + // if (keySet==null) + // keySet = new SynchronizedSet<>(m.keySet(), mutex); + // return keySet; + // } + // } + + // public Set> entrySet() { + // synchronized (mutex) { + // if (entrySet==null) + // entrySet = new SynchronizedSet<>(m.entrySet(), mutex); + // return entrySet; + // } + // } + + // public Collection values() { + // synchronized (mutex) { + // if (values==null) + // values = new SynchronizedCollection<>(m.values(), mutex); + // return values; + // } + // } + + // public boolean equals(Object o) { + // if (this == o) + // return true; + // synchronized (mutex) {return m.equals(o);} + // } + // public int hashCode() { + // synchronized (mutex) {return m.hashCode();} + // } + // public String toString() { + // synchronized (mutex) {return m.toString();} + // } + + // // Override default methods in Map + // @Override + // public V getOrDefault(Object k, V defaultValue) { + // synchronized (mutex) {return m.getOrDefault(k, defaultValue);} + // } + // @Override + // public void forEach(BiConsumer action) { + // synchronized (mutex) {m.forEach(action);} + // } + // @Override + // public void replaceAll(BiFunction function) { + // synchronized (mutex) {m.replaceAll(function);} + // } + // @Override + // public V putIfAbsent(K key, V value) { + // synchronized (mutex) {return m.putIfAbsent(key, value);} + // } + // @Override + // public boolean remove(Object key, Object value) { + // synchronized (mutex) {return m.remove(key, value);} + // } + // @Override + // public boolean replace(K key, V oldValue, V newValue) { + // synchronized (mutex) {return m.replace(key, oldValue, newValue);} + // } + // @Override + // public V replace(K key, V value) { + // synchronized (mutex) {return m.replace(key, value);} + // } + // @Override + // public V computeIfAbsent(K key, + // Function mappingFunction) { + // synchronized (mutex) {return m.computeIfAbsent(key, mappingFunction);} + // } + // @Override + // public V computeIfPresent(K key, + // BiFunction remappingFunction) { + // synchronized (mutex) {return m.computeIfPresent(key, remappingFunction);} + // } + // @Override + // public V compute(K key, + // BiFunction remappingFunction) { + // synchronized (mutex) {return m.compute(key, remappingFunction);} + // } + // @Override + // public V merge(K key, V value, + // BiFunction remappingFunction) { + // synchronized (mutex) {return m.merge(key, value, remappingFunction);} + // } + + // private void writeObject(ObjectOutputStream s) throws IOException { + // synchronized (mutex) {s.defaultWriteObject();} + // } + // } + + /** + * Returns a synchronized (thread-safe) sorted map backed by the specified + * sorted map. In order to guarantee serial access, it is critical that + * all access to the backing sorted map is accomplished + * through the returned sorted map (or its views).

+ * + * It is imperative that the user manually synchronize on the returned + * sorted map when iterating over any of its collection views, or the + * collections views of any of its subMap, headMap or + * tailMap views. + *

+     *  SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
+     *      ...
+     *  Set s = m.keySet();  // Needn't be in synchronized block
+     *      ...
+     *  synchronized (m) {  // Synchronizing on m, not s!
+     *      Iterator i = s.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * or: + *
+     *  SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
+     *  SortedMap m2 = m.subMap(foo, bar);
+     *      ...
+     *  Set s2 = m2.keySet();  // Needn't be in synchronized block
+     *      ...
+     *  synchronized (m) {  // Synchronizing on m, not m2 or s2!
+     *      Iterator i = s.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * Failure to follow this advice may result in non-deterministic behavior. + * + *

The returned sorted map will be serializable if the specified + * sorted map is serializable. + * + * @param the class of the map keys + * @param the class of the map values + * @param m the sorted map to be "wrapped" in a synchronized sorted map. + * @return a synchronized view of the specified sorted map. + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static SortedMap synchronizedSortedMap(SortedMap m) { + // return new SynchronizedSortedMap<>(m); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class SynchronizedSortedMap + // extends SynchronizedMap + // implements SortedMap + // { + // private static final long serialVersionUID = -8798146769416483793L; + + // private final SortedMap sm; + + // SynchronizedSortedMap(SortedMap m) { + // super(m); + // sm = m; + // } + // SynchronizedSortedMap(SortedMap m, Object mutex) { + // super(m, mutex); + // sm = m; + // } + + // public Comparator comparator() { + // synchronized (mutex) {return sm.comparator();} + // } + + // public SortedMap subMap(K fromKey, K toKey) { + // synchronized (mutex) { + // return new SynchronizedSortedMap<>( + // sm.subMap(fromKey, toKey), mutex); + // } + // } + // public SortedMap headMap(K toKey) { + // synchronized (mutex) { + // return new SynchronizedSortedMap<>(sm.headMap(toKey), mutex); + // } + // } + // public SortedMap tailMap(K fromKey) { + // synchronized (mutex) { + // return new SynchronizedSortedMap<>(sm.tailMap(fromKey),mutex); + // } + // } + + // public K firstKey() { + // synchronized (mutex) {return sm.firstKey();} + // } + // public K lastKey() { + // synchronized (mutex) {return sm.lastKey();} + // } + // } + + /** + * Returns a synchronized (thread-safe) navigable map backed by the + * specified navigable map. In order to guarantee serial access, it is + * critical that all access to the backing navigable map is + * accomplished through the returned navigable map (or its views).

+ * + * It is imperative that the user manually synchronize on the returned + * navigable map when iterating over any of its collection views, or the + * collections views of any of its {@code subMap}, {@code headMap} or + * {@code tailMap} views. + *

+     *  NavigableMap m = Collections.synchronizedNavigableMap(new TreeMap());
+     *      ...
+     *  Set s = m.keySet();  // Needn't be in synchronized block
+     *      ...
+     *  synchronized (m) {  // Synchronizing on m, not s!
+     *      Iterator i = s.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * or: + *
+     *  NavigableMap m = Collections.synchronizedNavigableMap(new TreeMap());
+     *  NavigableMap m2 = m.subMap(foo, true, bar, false);
+     *      ...
+     *  Set s2 = m2.keySet();  // Needn't be in synchronized block
+     *      ...
+     *  synchronized (m) {  // Synchronizing on m, not m2 or s2!
+     *      Iterator i = s.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * 
+ * Failure to follow this advice may result in non-deterministic behavior. + * + *

The returned navigable map will be serializable if the specified + * navigable map is serializable. + * + * @param the class of the map keys + * @param the class of the map values + * @param m the navigable map to be "wrapped" in a synchronized navigable + * map + * @return a synchronized view of the specified navigable map. + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static NavigableMap synchronizedNavigableMap(NavigableMap m) { + // return new SynchronizedNavigableMap<>(m); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * A synchronized NavigableMap. + * + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class SynchronizedNavigableMap + // extends SynchronizedSortedMap + // implements NavigableMap + // { + // private static final long serialVersionUID = 699392247599746807L; + + // private final NavigableMap nm; + + // SynchronizedNavigableMap(NavigableMap m) { + // super(m); + // nm = m; + // } + // SynchronizedNavigableMap(NavigableMap m, Object mutex) { + // super(m, mutex); + // nm = m; + // } + + // public Entry lowerEntry(K key) + // { synchronized (mutex) { return nm.lowerEntry(key); } } + // public K lowerKey(K key) + // { synchronized (mutex) { return nm.lowerKey(key); } } + // public Entry floorEntry(K key) + // { synchronized (mutex) { return nm.floorEntry(key); } } + // public K floorKey(K key) + // { synchronized (mutex) { return nm.floorKey(key); } } + // public Entry ceilingEntry(K key) + // { synchronized (mutex) { return nm.ceilingEntry(key); } } + // public K ceilingKey(K key) + // { synchronized (mutex) { return nm.ceilingKey(key); } } + // public Entry higherEntry(K key) + // { synchronized (mutex) { return nm.higherEntry(key); } } + // public K higherKey(K key) + // { synchronized (mutex) { return nm.higherKey(key); } } + // public Entry firstEntry() + // { synchronized (mutex) { return nm.firstEntry(); } } + // public Entry lastEntry() + // { synchronized (mutex) { return nm.lastEntry(); } } + // public Entry pollFirstEntry() + // { synchronized (mutex) { return nm.pollFirstEntry(); } } + // public Entry pollLastEntry() + // { synchronized (mutex) { return nm.pollLastEntry(); } } + + // public NavigableMap descendingMap() { + // synchronized (mutex) { + // return + // new SynchronizedNavigableMap<>(nm.descendingMap(), mutex); + // } + // } + + // public NavigableSet keySet() { + // return navigableKeySet(); + // } + + // public NavigableSet navigableKeySet() { + // synchronized (mutex) { + // return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); + // } + // } + + // public NavigableSet descendingKeySet() { + // synchronized (mutex) { + // return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); + // } + // } + + + // public SortedMap subMap(K fromKey, K toKey) { + // synchronized (mutex) { + // return new SynchronizedNavigableMap<>( + // nm.subMap(fromKey, true, toKey, false), mutex); + // } + // } + // public SortedMap headMap(K toKey) { + // synchronized (mutex) { + // return new SynchronizedNavigableMap<>(nm.headMap(toKey, false), mutex); + // } + // } + // public SortedMap tailMap(K fromKey) { + // synchronized (mutex) { + // return new SynchronizedNavigableMap<>(nm.tailMap(fromKey, true),mutex); + // } + // } + + // public NavigableMap subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { + // synchronized (mutex) { + // return new SynchronizedNavigableMap<>( + // nm.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex); + // } + // } + + // public NavigableMap headMap(K toKey, boolean inclusive) { + // synchronized (mutex) { + // return new SynchronizedNavigableMap<>( + // nm.headMap(toKey, inclusive), mutex); + // } + // } + + // public NavigableMap tailMap(K fromKey, boolean inclusive) { + // synchronized (mutex) { + // return new SynchronizedNavigableMap<>( + // nm.tailMap(fromKey, inclusive), mutex); + // } + // } + // } + + // Dynamically typesafe collection wrappers + + /** + * Returns a dynamically typesafe view of the specified collection. + * Any attempt to insert an element of the wrong type will result in an + * immediate {@link ClassCastException}. Assuming a collection + * contains no incorrectly typed elements prior to the time a + * dynamically typesafe view is generated, and that all subsequent + * access to the collection takes place through the view, it is + * guaranteed that the collection cannot contain an incorrectly + * typed element. + * + *

The generics mechanism in the language provides compile-time + * (static) type checking, but it is possible to defeat this mechanism + * with unchecked casts. Usually this is not a problem, as the compiler + * issues warnings on all such unchecked operations. There are, however, + * times when static type checking alone is not sufficient. For example, + * suppose a collection is passed to a third-party library and it is + * imperative that the library code not corrupt the collection by + * inserting an element of the wrong type. + * + *

Another use of dynamically typesafe views is debugging. Suppose a + * program fails with a {@code ClassCastException}, indicating that an + * incorrectly typed element was put into a parameterized collection. + * Unfortunately, the exception can occur at any time after the erroneous + * element is inserted, so it typically provides little or no information + * as to the real source of the problem. If the problem is reproducible, + * one can quickly determine its source by temporarily modifying the + * program to wrap the collection with a dynamically typesafe view. + * For example, this declaration: + *

 {@code
+     *     Collection c = new HashSet<>();
+     * }
+ * may be replaced temporarily by this one: + *
 {@code
+     *     Collection c = Collections.checkedCollection(
+     *         new HashSet<>(), String.class);
+     * }
+ * Running the program again will cause it to fail at the point where + * an incorrectly typed element is inserted into the collection, clearly + * identifying the source of the problem. Once the problem is fixed, the + * modified declaration may be reverted back to the original. + * + *

The returned collection does not pass the hashCode and equals + * operations through to the backing collection, but relies on + * {@code Object}'s {@code equals} and {@code hashCode} methods. This + * is necessary to preserve the contracts of these operations in the case + * that the backing collection is a set or a list. + * + *

The returned collection will be serializable if the specified + * collection is serializable. + * + *

Since {@code null} is considered to be a value of any reference + * type, the returned collection permits insertion of null elements + * whenever the backing collection does. + * + * @param the class of the objects in the collection + * @param c the collection for which a dynamically typesafe view is to be + * returned + * @param type the type of element that {@code c} is permitted to hold + * @return a dynamically typesafe view of the specified collection + * @since 1.5 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Collection checkedCollection(Collection c, + Class type) { + // return new CheckedCollection<>(c, type); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + @SuppressWarnings("unchecked") + // DIFFBLUE MODEL LIBRARY - not used in model + // static T[] zeroLengthArray(Class type) { + // return (T[]) Array.newInstance(type, 0); + // } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class CheckedCollection implements Collection, Serializable { + // private static final long serialVersionUID = 1578914078182001775L; + + // final Collection c; + // final Class type; + + // @SuppressWarnings("unchecked") + // E typeCheck(Object o) { + // if (o != null && !type.isInstance(o)) + // throw new ClassCastException(badElementMsg(o)); + // return (E) o; + // } + + // private String badElementMsg(Object o) { + // return "Attempt to insert " + o.getClass() + + // " element into collection with element type " + type; + // } + + // CheckedCollection(Collection c, Class type) { + // this.c = Objects.requireNonNull(c, "c"); + // this.type = Objects.requireNonNull(type, "type"); + // } + + // public int size() { return c.size(); } + // public boolean isEmpty() { return c.isEmpty(); } + // public boolean contains(Object o) { return c.contains(o); } + // public Object[] toArray() { return c.toArray(); } + // public T[] toArray(T[] a) { return c.toArray(a); } + // public String toString() { return c.toString(); } + // public boolean remove(Object o) { return c.remove(o); } + // public void clear() { c.clear(); } + + // public boolean containsAll(Collection coll) { + // return c.containsAll(coll); + // } + // public boolean removeAll(Collection coll) { + // return c.removeAll(coll); + // } + // public boolean retainAll(Collection coll) { + // return c.retainAll(coll); + // } + + // public Iterator iterator() { + // // JDK-6363904 - unwrapped iterator could be typecast to + // // ListIterator with unsafe set() + // final Iterator it = c.iterator(); + // return new Iterator() { + // public boolean hasNext() { return it.hasNext(); } + // public E next() { return it.next(); } + // public void remove() { it.remove(); }}; + // } + + // public boolean add(E e) { return c.add(typeCheck(e)); } + + // private E[] zeroLengthElementArray; // Lazily initialized + + // private E[] zeroLengthElementArray() { + // return zeroLengthElementArray != null ? zeroLengthElementArray : + // (zeroLengthElementArray = zeroLengthArray(type)); + // } + + // @SuppressWarnings("unchecked") + // Collection checkedCopyOf(Collection coll) { + // Object[] a; + // try { + // E[] z = zeroLengthElementArray(); + // a = coll.toArray(z); + // // Defend against coll violating the toArray contract + // if (a.getClass() != z.getClass()) + // a = Arrays.copyOf(a, a.length, z.getClass()); + // } catch (ArrayStoreException ignore) { + // // To get better and consistent diagnostics, + // // we call typeCheck explicitly on each element. + // // We call clone() to defend against coll retaining a + // // reference to the returned array and storing a bad + // // element into it after it has been type checked. + // a = coll.toArray().clone(); + // for (Object o : a) + // typeCheck(o); + // } + // // A slight abuse of the type system, but safe here. + // return (Collection) Arrays.asList(a); + // } + + // public boolean addAll(Collection coll) { + // // Doing things this way insulates us from concurrent changes + // // in the contents of coll and provides all-or-nothing + // // semantics (which we wouldn't get if we type-checked each + // // element as we added it) + // return c.addAll(checkedCopyOf(coll)); + // } + + // // Override default methods in Collection + // @Override + // public void forEach(Consumer action) {c.forEach(action);} + // @Override + // public boolean removeIf(Predicate filter) { + // return c.removeIf(filter); + // } + // @Override + // public Spliterator spliterator() {return c.spliterator();} + // @Override + // public Stream stream() {return c.stream();} + // @Override + // public Stream parallelStream() {return c.parallelStream();} + // } + + /** + * Returns a dynamically typesafe view of the specified queue. + * Any attempt to insert an element of the wrong type will result in + * an immediate {@link ClassCastException}. Assuming a queue contains + * no incorrectly typed elements prior to the time a dynamically typesafe + * view is generated, and that all subsequent access to the queue + * takes place through the view, it is guaranteed that the + * queue cannot contain an incorrectly typed element. + * + *

A discussion of the use of dynamically typesafe views may be + * found in the documentation for the {@link #checkedCollection + * checkedCollection} method. + * + *

The returned queue will be serializable if the specified queue + * is serializable. + * + *

Since {@code null} is considered to be a value of any reference + * type, the returned queue permits insertion of {@code null} elements + * whenever the backing queue does. + * + * @param the class of the objects in the queue + * @param queue the queue for which a dynamically typesafe view is to be + * returned + * @param type the type of element that {@code queue} is permitted to hold + * @return a dynamically typesafe view of the specified queue + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Queue checkedQueue(Queue queue, Class type) { + // return new CheckedQueue<>(queue, type); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class CheckedQueue + // extends CheckedCollection + // implements Queue, Serializable + // { + // private static final long serialVersionUID = 1433151992604707767L; + // final Queue queue; + + // CheckedQueue(Queue queue, Class elementType) { + // super(queue, elementType); + // this.queue = queue; + // } + + // public E element() {return queue.element();} + // public boolean equals(Object o) {return o == this || c.equals(o);} + // public int hashCode() {return c.hashCode();} + // public E peek() {return queue.peek();} + // public E poll() {return queue.poll();} + // public E remove() {return queue.remove();} + // public boolean offer(E e) {return queue.offer(typeCheck(e));} + // } + + /** + * Returns a dynamically typesafe view of the specified set. + * Any attempt to insert an element of the wrong type will result in + * an immediate {@link ClassCastException}. Assuming a set contains + * no incorrectly typed elements prior to the time a dynamically typesafe + * view is generated, and that all subsequent access to the set + * takes place through the view, it is guaranteed that the + * set cannot contain an incorrectly typed element. + * + *

A discussion of the use of dynamically typesafe views may be + * found in the documentation for the {@link #checkedCollection + * checkedCollection} method. + * + *

The returned set will be serializable if the specified set is + * serializable. + * + *

Since {@code null} is considered to be a value of any reference + * type, the returned set permits insertion of null elements whenever + * the backing set does. + * + * @param the class of the objects in the set + * @param s the set for which a dynamically typesafe view is to be + * returned + * @param type the type of element that {@code s} is permitted to hold + * @return a dynamically typesafe view of the specified set + * @since 1.5 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Set checkedSet(Set s, Class type) { + // return new CheckedSet<>(s, type); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class CheckedSet extends CheckedCollection + // implements Set, Serializable + // { + // private static final long serialVersionUID = 4694047833775013803L; + + // CheckedSet(Set s, Class elementType) { super(s, elementType); } + + // public boolean equals(Object o) { return o == this || c.equals(o); } + // public int hashCode() { return c.hashCode(); } + // } + + /** + * Returns a dynamically typesafe view of the specified sorted set. + * Any attempt to insert an element of the wrong type will result in an + * immediate {@link ClassCastException}. Assuming a sorted set + * contains no incorrectly typed elements prior to the time a + * dynamically typesafe view is generated, and that all subsequent + * access to the sorted set takes place through the view, it is + * guaranteed that the sorted set cannot contain an incorrectly + * typed element. + * + *

A discussion of the use of dynamically typesafe views may be + * found in the documentation for the {@link #checkedCollection + * checkedCollection} method. + * + *

The returned sorted set will be serializable if the specified sorted + * set is serializable. + * + *

Since {@code null} is considered to be a value of any reference + * type, the returned sorted set permits insertion of null elements + * whenever the backing sorted set does. + * + * @param the class of the objects in the set + * @param s the sorted set for which a dynamically typesafe view is to be + * returned + * @param type the type of element that {@code s} is permitted to hold + * @return a dynamically typesafe view of the specified sorted set + * @since 1.5 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static SortedSet checkedSortedSet(SortedSet s, + Class type) { + // return new CheckedSortedSet<>(s, type); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class CheckedSortedSet extends CheckedSet + // implements SortedSet, Serializable + // { + // private static final long serialVersionUID = 1599911165492914959L; + + // private final SortedSet ss; + + // CheckedSortedSet(SortedSet s, Class type) { + // super(s, type); + // ss = s; + // } + + // public Comparator comparator() { return ss.comparator(); } + // public E first() { return ss.first(); } + // public E last() { return ss.last(); } + + // public SortedSet subSet(E fromElement, E toElement) { + // return checkedSortedSet(ss.subSet(fromElement,toElement), type); + // } + // public SortedSet headSet(E toElement) { + // return checkedSortedSet(ss.headSet(toElement), type); + // } + // public SortedSet tailSet(E fromElement) { + // return checkedSortedSet(ss.tailSet(fromElement), type); + // } + // } + +/** + * Returns a dynamically typesafe view of the specified navigable set. + * Any attempt to insert an element of the wrong type will result in an + * immediate {@link ClassCastException}. Assuming a navigable set + * contains no incorrectly typed elements prior to the time a + * dynamically typesafe view is generated, and that all subsequent + * access to the navigable set takes place through the view, it is + * guaranteed that the navigable set cannot contain an incorrectly + * typed element. + * + *

A discussion of the use of dynamically typesafe views may be + * found in the documentation for the {@link #checkedCollection + * checkedCollection} method. + * + *

The returned navigable set will be serializable if the specified + * navigable set is serializable. + * + *

Since {@code null} is considered to be a value of any reference + * type, the returned navigable set permits insertion of null elements + * whenever the backing sorted set does. + * + * @param the class of the objects in the set + * @param s the navigable set for which a dynamically typesafe view is to be + * returned + * @param type the type of element that {@code s} is permitted to hold + * @return a dynamically typesafe view of the specified navigable set + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static NavigableSet checkedNavigableSet(NavigableSet s, + Class type) { + // return new CheckedNavigableSet<>(s, type); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class CheckedNavigableSet extends CheckedSortedSet + // implements NavigableSet, Serializable + // { + // private static final long serialVersionUID = -5429120189805438922L; + + // private final NavigableSet ns; + + // CheckedNavigableSet(NavigableSet s, Class type) { + // super(s, type); + // ns = s; + // } + + // public E lower(E e) { return ns.lower(e); } + // public E floor(E e) { return ns.floor(e); } + // public E ceiling(E e) { return ns.ceiling(e); } + // public E higher(E e) { return ns.higher(e); } + // public E pollFirst() { return ns.pollFirst(); } + // public E pollLast() {return ns.pollLast(); } + // public NavigableSet descendingSet() + // { return checkedNavigableSet(ns.descendingSet(), type); } + // public Iterator descendingIterator() + // {return checkedNavigableSet(ns.descendingSet(), type).iterator(); } + + // public NavigableSet subSet(E fromElement, E toElement) { + // return checkedNavigableSet(ns.subSet(fromElement, true, toElement, false), type); + // } + // public NavigableSet headSet(E toElement) { + // return checkedNavigableSet(ns.headSet(toElement, false), type); + // } + // public NavigableSet tailSet(E fromElement) { + // return checkedNavigableSet(ns.tailSet(fromElement, true), type); + // } + + // public NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { + // return checkedNavigableSet(ns.subSet(fromElement, fromInclusive, toElement, toInclusive), type); + // } + + // public NavigableSet headSet(E toElement, boolean inclusive) { + // return checkedNavigableSet(ns.headSet(toElement, inclusive), type); + // } + + // public NavigableSet tailSet(E fromElement, boolean inclusive) { + // return checkedNavigableSet(ns.tailSet(fromElement, inclusive), type); + // } + // } + + /** + * Returns a dynamically typesafe view of the specified list. + * Any attempt to insert an element of the wrong type will result in + * an immediate {@link ClassCastException}. Assuming a list contains + * no incorrectly typed elements prior to the time a dynamically typesafe + * view is generated, and that all subsequent access to the list + * takes place through the view, it is guaranteed that the + * list cannot contain an incorrectly typed element. + * + *

A discussion of the use of dynamically typesafe views may be + * found in the documentation for the {@link #checkedCollection + * checkedCollection} method. + * + *

The returned list will be serializable if the specified list + * is serializable. + * + *

Since {@code null} is considered to be a value of any reference + * type, the returned list permits insertion of null elements whenever + * the backing list does. + * + * @param the class of the objects in the list + * @param list the list for which a dynamically typesafe view is to be + * returned + * @param type the type of element that {@code list} is permitted to hold + * @return a dynamically typesafe view of the specified list + * @since 1.5 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static List checkedList(List list, Class type) { + // return (list instanceof RandomAccess ? + // new CheckedRandomAccessList<>(list, type) : + // new CheckedList<>(list, type)); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class CheckedList + // extends CheckedCollection + // implements List + // { + // private static final long serialVersionUID = 65247728283967356L; + // final List list; + + // CheckedList(List list, Class type) { + // super(list, type); + // this.list = list; + // } + + // public boolean equals(Object o) { return o == this || list.equals(o); } + // public int hashCode() { return list.hashCode(); } + // public E get(int index) { return list.get(index); } + // public E remove(int index) { return list.remove(index); } + // public int indexOf(Object o) { return list.indexOf(o); } + // public int lastIndexOf(Object o) { return list.lastIndexOf(o); } + + // public E set(int index, E element) { + // return list.set(index, typeCheck(element)); + // } + + // public void add(int index, E element) { + // list.add(index, typeCheck(element)); + // } + + // public boolean addAll(int index, Collection c) { + // return list.addAll(index, checkedCopyOf(c)); + // } + // public ListIterator listIterator() { return listIterator(0); } + + // public ListIterator listIterator(final int index) { + // final ListIterator i = list.listIterator(index); + + // return new ListIterator() { + // public boolean hasNext() { return i.hasNext(); } + // public E next() { return i.next(); } + // public boolean hasPrevious() { return i.hasPrevious(); } + // public E previous() { return i.previous(); } + // public int nextIndex() { return i.nextIndex(); } + // public int previousIndex() { return i.previousIndex(); } + // public void remove() { i.remove(); } + + // public void set(E e) { + // i.set(typeCheck(e)); + // } + + // public void add(E e) { + // i.add(typeCheck(e)); + // } + + // @Override + // public void forEachRemaining(Consumer action) { + // i.forEachRemaining(action); + // } + // }; + // } + + // public List subList(int fromIndex, int toIndex) { + // return new CheckedList<>(list.subList(fromIndex, toIndex), type); + // } + + // /** + // * {@inheritDoc} + // * + // * @throws ClassCastException if the class of an element returned by the + // * operator prevents it from being added to this collection. The + // * exception may be thrown after some elements of the list have + // * already been replaced. + // */ + // @Override + // public void replaceAll(UnaryOperator operator) { + // Objects.requireNonNull(operator); + // list.replaceAll(e -> typeCheck(operator.apply(e))); + // } + + // @Override + // public void sort(Comparator c) { + // list.sort(c); + // } + // } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class CheckedRandomAccessList extends CheckedList + // implements RandomAccess + // { + // private static final long serialVersionUID = 1638200125423088369L; + + // CheckedRandomAccessList(List list, Class type) { + // super(list, type); + // } + + // public List subList(int fromIndex, int toIndex) { + // return new CheckedRandomAccessList<>( + // list.subList(fromIndex, toIndex), type); + // } + // } + + /** + * Returns a dynamically typesafe view of the specified map. + * Any attempt to insert a mapping whose key or value have the wrong + * type will result in an immediate {@link ClassCastException}. + * Similarly, any attempt to modify the value currently associated with + * a key will result in an immediate {@link ClassCastException}, + * whether the modification is attempted directly through the map + * itself, or through a {@link Map.Entry} instance obtained from the + * map's {@link Map#entrySet() entry set} view. + * + *

Assuming a map contains no incorrectly typed keys or values + * prior to the time a dynamically typesafe view is generated, and + * that all subsequent access to the map takes place through the view + * (or one of its collection views), it is guaranteed that the + * map cannot contain an incorrectly typed key or value. + * + *

A discussion of the use of dynamically typesafe views may be + * found in the documentation for the {@link #checkedCollection + * checkedCollection} method. + * + *

The returned map will be serializable if the specified map is + * serializable. + * + *

Since {@code null} is considered to be a value of any reference + * type, the returned map permits insertion of null keys or values + * whenever the backing map does. + * + * @param the class of the map keys + * @param the class of the map values + * @param m the map for which a dynamically typesafe view is to be + * returned + * @param keyType the type of key that {@code m} is permitted to hold + * @param valueType the type of value that {@code m} is permitted to hold + * @return a dynamically typesafe view of the specified map + * @since 1.5 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Map checkedMap(Map m, + Class keyType, + Class valueType) { + // return new CheckedMap<>(m, keyType, valueType); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static class CheckedMap + // implements Map, Serializable + // { + // private static final long serialVersionUID = 5742860141034234728L; + + // private final Map m; + // final Class keyType; + // final Class valueType; + + // private void typeCheck(Object key, Object value) { + // if (key != null && !keyType.isInstance(key)) + // throw new ClassCastException(badKeyMsg(key)); + + // if (value != null && !valueType.isInstance(value)) + // throw new ClassCastException(badValueMsg(value)); + // } + + // private BiFunction typeCheck( + // BiFunction func) { + // Objects.requireNonNull(func); + // return (k, v) -> { + // V newValue = func.apply(k, v); + // typeCheck(k, newValue); + // return newValue; + // }; + // } + + // private String badKeyMsg(Object key) { + // return "Attempt to insert " + key.getClass() + + // " key into map with key type " + keyType; + // } + + // private String badValueMsg(Object value) { + // return "Attempt to insert " + value.getClass() + + // " value into map with value type " + valueType; + // } + + // CheckedMap(Map m, Class keyType, Class valueType) { + // this.m = Objects.requireNonNull(m); + // this.keyType = Objects.requireNonNull(keyType); + // this.valueType = Objects.requireNonNull(valueType); + // } + + // public int size() { return m.size(); } + // public boolean isEmpty() { return m.isEmpty(); } + // public boolean containsKey(Object key) { return m.containsKey(key); } + // public boolean containsValue(Object v) { return m.containsValue(v); } + // public V get(Object key) { return m.get(key); } + // public V remove(Object key) { return m.remove(key); } + // public void clear() { m.clear(); } + // public Set keySet() { return m.keySet(); } + // public Collection values() { return m.values(); } + // public boolean equals(Object o) { return o == this || m.equals(o); } + // public int hashCode() { return m.hashCode(); } + // public String toString() { return m.toString(); } + + // public V put(K key, V value) { + // typeCheck(key, value); + // return m.put(key, value); + // } + + // @SuppressWarnings("unchecked") + // public void putAll(Map t) { + // // Satisfy the following goals: + // // - good diagnostics in case of type mismatch + // // - all-or-nothing semantics + // // - protection from malicious t + // // - correct behavior if t is a concurrent map + // Object[] entries = t.entrySet().toArray(); + // List> checked = new ArrayList<>(entries.length); + // for (Object o : entries) { + // Map.Entry e = (Map.Entry) o; + // Object k = e.getKey(); + // Object v = e.getValue(); + // typeCheck(k, v); + // checked.add( + // new AbstractMap.SimpleImmutableEntry<>((K)k, (V)v)); + // } + // for (Map.Entry e : checked) + // m.put(e.getKey(), e.getValue()); + // } + + // private transient Set> entrySet; + + // public Set> entrySet() { + // if (entrySet==null) + // entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); + // return entrySet; + // } + + // // Override default methods in Map + // @Override + // public void forEach(BiConsumer action) { + // m.forEach(action); + // } + + // @Override + // public void replaceAll(BiFunction function) { + // m.replaceAll(typeCheck(function)); + // } + + // @Override + // public V putIfAbsent(K key, V value) { + // typeCheck(key, value); + // return m.putIfAbsent(key, value); + // } + + // @Override + // public boolean remove(Object key, Object value) { + // return m.remove(key, value); + // } + + // @Override + // public boolean replace(K key, V oldValue, V newValue) { + // typeCheck(key, newValue); + // return m.replace(key, oldValue, newValue); + // } + + // @Override + // public V replace(K key, V value) { + // typeCheck(key, value); + // return m.replace(key, value); + // } + + // @Override + // public V computeIfAbsent(K key, + // Function mappingFunction) { + // Objects.requireNonNull(mappingFunction); + // return m.computeIfAbsent(key, k -> { + // V value = mappingFunction.apply(k); + // typeCheck(k, value); + // return value; + // }); + // } + + // @Override + // public V computeIfPresent(K key, + // BiFunction remappingFunction) { + // return m.computeIfPresent(key, typeCheck(remappingFunction)); + // } + + // @Override + // public V compute(K key, + // BiFunction remappingFunction) { + // return m.compute(key, typeCheck(remappingFunction)); + // } + + // @Override + // public V merge(K key, V value, + // BiFunction remappingFunction) { + // Objects.requireNonNull(remappingFunction); + // return m.merge(key, value, (v1, v2) -> { + // V newValue = remappingFunction.apply(v1, v2); + // typeCheck(null, newValue); + // return newValue; + // }); + // } + + // /** + // * We need this class in addition to CheckedSet as Map.Entry permits + // * modification of the backing Map via the setValue operation. This + // * class is subtle: there are many possible attacks that must be + // * thwarted. + // * + // * @serial exclude + // */ + // static class CheckedEntrySet implements Set> { + // private final Set> s; + // private final Class valueType; + + // CheckedEntrySet(Set> s, Class valueType) { + // this.s = s; + // this.valueType = valueType; + // } + + // public int size() { return s.size(); } + // public boolean isEmpty() { return s.isEmpty(); } + // public String toString() { return s.toString(); } + // public int hashCode() { return s.hashCode(); } + // public void clear() { s.clear(); } + + // public boolean add(Map.Entry e) { + // throw new UnsupportedOperationException(); + // } + // public boolean addAll(Collection> coll) { + // throw new UnsupportedOperationException(); + // } + + // public Iterator> iterator() { + // final Iterator> i = s.iterator(); + // final Class valueType = this.valueType; + + // return new Iterator>() { + // public boolean hasNext() { return i.hasNext(); } + // public void remove() { i.remove(); } + + // public Map.Entry next() { + // return checkedEntry(i.next(), valueType); + // } + // }; + // } + + // @SuppressWarnings("unchecked") + // public Object[] toArray() { + // Object[] source = s.toArray(); + + // /* + // * Ensure that we don't get an ArrayStoreException even if + // * s.toArray returns an array of something other than Object + // */ + // Object[] dest = (CheckedEntry.class.isInstance( + // source.getClass().getComponentType()) ? source : + // new Object[source.length]); + + // for (int i = 0; i < source.length; i++) + // dest[i] = checkedEntry((Map.Entry)source[i], + // valueType); + // return dest; + // } + + // @SuppressWarnings("unchecked") + // public T[] toArray(T[] a) { + // // We don't pass a to s.toArray, to avoid window of + // // vulnerability wherein an unscrupulous multithreaded client + // // could get his hands on raw (unwrapped) Entries from s. + // T[] arr = s.toArray(a.length==0 ? a : Arrays.copyOf(a, 0)); + + // for (int i=0; i)arr[i], + // valueType); + // if (arr.length > a.length) + // return arr; + + // System.arraycopy(arr, 0, a, 0, arr.length); + // if (a.length > arr.length) + // a[arr.length] = null; + // return a; + // } + + // /** + // * This method is overridden to protect the backing set against + // * an object with a nefarious equals function that senses + // * that the equality-candidate is Map.Entry and calls its + // * setValue method. + // */ + // public boolean contains(Object o) { + // if (!(o instanceof Map.Entry)) + // return false; + // Map.Entry e = (Map.Entry) o; + // return s.contains( + // (e instanceof CheckedEntry) ? e : checkedEntry(e, valueType)); + // } + + // /** + // * The bulk collection methods are overridden to protect + // * against an unscrupulous collection whose contains(Object o) + // * method senses when o is a Map.Entry, and calls o.setValue. + // */ + // public boolean containsAll(Collection c) { + // for (Object o : c) + // if (!contains(o)) // Invokes safe contains() above + // return false; + // return true; + // } + + // public boolean remove(Object o) { + // if (!(o instanceof Map.Entry)) + // return false; + // return s.remove(new AbstractMap.SimpleImmutableEntry + // <>((Map.Entry)o)); + // } + + // public boolean removeAll(Collection c) { + // return batchRemove(c, false); + // } + // public boolean retainAll(Collection c) { + // return batchRemove(c, true); + // } + // private boolean batchRemove(Collection c, boolean complement) { + // Objects.requireNonNull(c); + // boolean modified = false; + // Iterator> it = iterator(); + // while (it.hasNext()) { + // if (c.contains(it.next()) != complement) { + // it.remove(); + // modified = true; + // } + // } + // return modified; + // } + + // public boolean equals(Object o) { + // if (o == this) + // return true; + // if (!(o instanceof Set)) + // return false; + // Set that = (Set) o; + // return that.size() == s.size() + // && containsAll(that); // Invokes safe containsAll() above + // } + + // static CheckedEntry checkedEntry(Map.Entry e, + // Class valueType) { + // return new CheckedEntry<>(e, valueType); + // } + + // /** + // * This "wrapper class" serves two purposes: it prevents + // * the client from modifying the backing Map, by short-circuiting + // * the setValue method, and it protects the backing Map against + // * an ill-behaved Map.Entry that attempts to modify another + // * Map.Entry when asked to perform an equality check. + // */ + // private static class CheckedEntry implements Map.Entry { + // private final Map.Entry e; + // private final Class valueType; + + // CheckedEntry(Map.Entry e, Class valueType) { + // this.e = Objects.requireNonNull(e); + // this.valueType = Objects.requireNonNull(valueType); + // } + + // public K getKey() { return e.getKey(); } + // public V getValue() { return e.getValue(); } + // public int hashCode() { return e.hashCode(); } + // public String toString() { return e.toString(); } + + // public V setValue(V value) { + // if (value != null && !valueType.isInstance(value)) + // throw new ClassCastException(badValueMsg(value)); + // return e.setValue(value); + // } + + // private String badValueMsg(Object value) { + // return "Attempt to insert " + value.getClass() + + // " value into map with value type " + valueType; + // } + + // public boolean equals(Object o) { + // if (o == this) + // return true; + // if (!(o instanceof Map.Entry)) + // return false; + // return e.equals(new AbstractMap.SimpleImmutableEntry + // <>((Map.Entry)o)); + // } + // } + // } + // } + + /** + * Returns a dynamically typesafe view of the specified sorted map. + * Any attempt to insert a mapping whose key or value have the wrong + * type will result in an immediate {@link ClassCastException}. + * Similarly, any attempt to modify the value currently associated with + * a key will result in an immediate {@link ClassCastException}, + * whether the modification is attempted directly through the map + * itself, or through a {@link Map.Entry} instance obtained from the + * map's {@link Map#entrySet() entry set} view. + * + *

Assuming a map contains no incorrectly typed keys or values + * prior to the time a dynamically typesafe view is generated, and + * that all subsequent access to the map takes place through the view + * (or one of its collection views), it is guaranteed that the + * map cannot contain an incorrectly typed key or value. + * + *

A discussion of the use of dynamically typesafe views may be + * found in the documentation for the {@link #checkedCollection + * checkedCollection} method. + * + *

The returned map will be serializable if the specified map is + * serializable. + * + *

Since {@code null} is considered to be a value of any reference + * type, the returned map permits insertion of null keys or values + * whenever the backing map does. + * + * @param the class of the map keys + * @param the class of the map values + * @param m the map for which a dynamically typesafe view is to be + * returned + * @param keyType the type of key that {@code m} is permitted to hold + * @param valueType the type of value that {@code m} is permitted to hold + * @return a dynamically typesafe view of the specified map + * @since 1.5 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static SortedMap checkedSortedMap(SortedMap m, + Class keyType, + Class valueType) { + // return new CheckedSortedMap<>(m, keyType, valueType); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class CheckedSortedMap extends CheckedMap + // implements SortedMap, Serializable + // { + // private static final long serialVersionUID = 1599671320688067438L; + + // private final SortedMap sm; + + // CheckedSortedMap(SortedMap m, + // Class keyType, Class valueType) { + // super(m, keyType, valueType); + // sm = m; + // } + + // public Comparator comparator() { return sm.comparator(); } + // public K firstKey() { return sm.firstKey(); } + // public K lastKey() { return sm.lastKey(); } + + // public SortedMap subMap(K fromKey, K toKey) { + // return checkedSortedMap(sm.subMap(fromKey, toKey), + // keyType, valueType); + // } + // public SortedMap headMap(K toKey) { + // return checkedSortedMap(sm.headMap(toKey), keyType, valueType); + // } + // public SortedMap tailMap(K fromKey) { + // return checkedSortedMap(sm.tailMap(fromKey), keyType, valueType); + // } + // } + + /** + * Returns a dynamically typesafe view of the specified navigable map. + * Any attempt to insert a mapping whose key or value have the wrong + * type will result in an immediate {@link ClassCastException}. + * Similarly, any attempt to modify the value currently associated with + * a key will result in an immediate {@link ClassCastException}, + * whether the modification is attempted directly through the map + * itself, or through a {@link Map.Entry} instance obtained from the + * map's {@link Map#entrySet() entry set} view. + * + *

Assuming a map contains no incorrectly typed keys or values + * prior to the time a dynamically typesafe view is generated, and + * that all subsequent access to the map takes place through the view + * (or one of its collection views), it is guaranteed that the + * map cannot contain an incorrectly typed key or value. + * + *

A discussion of the use of dynamically typesafe views may be + * found in the documentation for the {@link #checkedCollection + * checkedCollection} method. + * + *

The returned map will be serializable if the specified map is + * serializable. + * + *

Since {@code null} is considered to be a value of any reference + * type, the returned map permits insertion of null keys or values + * whenever the backing map does. + * + * @param type of map keys + * @param type of map values + * @param m the map for which a dynamically typesafe view is to be + * returned + * @param keyType the type of key that {@code m} is permitted to hold + * @param valueType the type of value that {@code m} is permitted to hold + * @return a dynamically typesafe view of the specified map + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static NavigableMap checkedNavigableMap(NavigableMap m, + Class keyType, + Class valueType) { + // return new CheckedNavigableMap<>(m, keyType, valueType); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class CheckedNavigableMap extends CheckedSortedMap + // implements NavigableMap, Serializable + // { + // private static final long serialVersionUID = -4852462692372534096L; + + // private final NavigableMap nm; + + // CheckedNavigableMap(NavigableMap m, + // Class keyType, Class valueType) { + // super(m, keyType, valueType); + // nm = m; + // } + + // public Comparator comparator() { return nm.comparator(); } + // public K firstKey() { return nm.firstKey(); } + // public K lastKey() { return nm.lastKey(); } + + // public Entry lowerEntry(K key) { + // Entry lower = nm.lowerEntry(key); + // return (null != lower) + // ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(lower, valueType) + // : null; + // } + + // public K lowerKey(K key) { return nm.lowerKey(key); } + + // public Entry floorEntry(K key) { + // Entry floor = nm.floorEntry(key); + // return (null != floor) + // ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(floor, valueType) + // : null; + // } + + // public K floorKey(K key) { return nm.floorKey(key); } + + // public Entry ceilingEntry(K key) { + // Entry ceiling = nm.ceilingEntry(key); + // return (null != ceiling) + // ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(ceiling, valueType) + // : null; + // } + + // public K ceilingKey(K key) { return nm.ceilingKey(key); } + + // public Entry higherEntry(K key) { + // Entry higher = nm.higherEntry(key); + // return (null != higher) + // ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(higher, valueType) + // : null; + // } + + // public K higherKey(K key) { return nm.higherKey(key); } + + // public Entry firstEntry() { + // Entry first = nm.firstEntry(); + // return (null != first) + // ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(first, valueType) + // : null; + // } + + // public Entry lastEntry() { + // Entry last = nm.lastEntry(); + // return (null != last) + // ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(last, valueType) + // : null; + // } + + // public Entry pollFirstEntry() { + // Entry entry = nm.pollFirstEntry(); + // return (null == entry) + // ? null + // : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType); + // } + + // public Entry pollLastEntry() { + // Entry entry = nm.pollLastEntry(); + // return (null == entry) + // ? null + // : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType); + // } + + // public NavigableMap descendingMap() { + // return checkedNavigableMap(nm.descendingMap(), keyType, valueType); + // } + + // public NavigableSet keySet() { + // return navigableKeySet(); + // } + + // public NavigableSet navigableKeySet() { + // return checkedNavigableSet(nm.navigableKeySet(), keyType); + // } + + // public NavigableSet descendingKeySet() { + // return checkedNavigableSet(nm.descendingKeySet(), keyType); + // } + + // @Override + // public NavigableMap subMap(K fromKey, K toKey) { + // return checkedNavigableMap(nm.subMap(fromKey, true, toKey, false), + // keyType, valueType); + // } + + // @Override + // public NavigableMap headMap(K toKey) { + // return checkedNavigableMap(nm.headMap(toKey, false), keyType, valueType); + // } + + // @Override + // public NavigableMap tailMap(K fromKey) { + // return checkedNavigableMap(nm.tailMap(fromKey, true), keyType, valueType); + // } + + // public NavigableMap subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { + // return checkedNavigableMap(nm.subMap(fromKey, fromInclusive, toKey, toInclusive), keyType, valueType); + // } + + // public NavigableMap headMap(K toKey, boolean inclusive) { + // return checkedNavigableMap(nm.headMap(toKey, inclusive), keyType, valueType); + // } + + // public NavigableMap tailMap(K fromKey, boolean inclusive) { + // return checkedNavigableMap(nm.tailMap(fromKey, inclusive), keyType, valueType); + // } + // } + + // Empty collections + + /** + * Returns an iterator that has no elements. More precisely, + * + *

    + *
  • {@link Iterator#hasNext hasNext} always returns {@code + * false}.
  • + *
  • {@link Iterator#next next} always throws {@link + * NoSuchElementException}.
  • + *
  • {@link Iterator#remove remove} always throws {@link + * IllegalStateException}.
  • + *
+ * + *

Implementations of this method are permitted, but not + * required, to return the same object from multiple invocations. + * + * @param type of elements, if there were any, in the iterator + * @return an empty iterator + * @since 1.7 + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static Iterator emptyIterator() { + // return (Iterator) EmptyIterator.EMPTY_ITERATOR; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static class EmptyIterator implements Iterator { + // static final EmptyIterator EMPTY_ITERATOR + // = new EmptyIterator<>(); + + // public boolean hasNext() { return false; } + // public E next() { throw new NoSuchElementException(); } + // public void remove() { throw new IllegalStateException(); } + // @Override + // public void forEachRemaining(Consumer action) { + // Objects.requireNonNull(action); + // } + // } + + /** + * Returns a list iterator that has no elements. More precisely, + * + *
    + *
  • {@link Iterator#hasNext hasNext} and {@link + * ListIterator#hasPrevious hasPrevious} always return {@code + * false}.
  • + *
  • {@link Iterator#next next} and {@link ListIterator#previous + * previous} always throw {@link NoSuchElementException}.
  • + *
  • {@link Iterator#remove remove} and {@link ListIterator#set + * set} always throw {@link IllegalStateException}.
  • + *
  • {@link ListIterator#add add} always throws {@link + * UnsupportedOperationException}.
  • + *
  • {@link ListIterator#nextIndex nextIndex} always returns + * {@code 0}.
  • + *
  • {@link ListIterator#previousIndex previousIndex} always + * returns {@code -1}.
  • + *
+ * + *

Implementations of this method are permitted, but not + * required, to return the same object from multiple invocations. + * + * @param type of elements, if there were any, in the iterator + * @return an empty list iterator + * @since 1.7 + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static ListIterator emptyListIterator() { + // return (ListIterator) EmptyListIterator.EMPTY_ITERATOR; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static class EmptyListIterator + // extends EmptyIterator + // implements ListIterator + // { + // static final EmptyListIterator EMPTY_ITERATOR + // = new EmptyListIterator<>(); + + // public boolean hasPrevious() { return false; } + // public E previous() { throw new NoSuchElementException(); } + // public int nextIndex() { return 0; } + // public int previousIndex() { return -1; } + // public void set(E e) { throw new IllegalStateException(); } + // public void add(E e) { throw new UnsupportedOperationException(); } + // } + + /** + * Returns an enumeration that has no elements. More precisely, + * + *
    + *
  • {@link Enumeration#hasMoreElements hasMoreElements} always + * returns {@code false}.
  • + *
  • {@link Enumeration#nextElement nextElement} always throws + * {@link NoSuchElementException}.
  • + *
+ * + *

Implementations of this method are permitted, but not + * required, to return the same object from multiple invocations. + * + * @param the class of the objects in the enumeration + * @return an empty enumeration + * @since 1.7 + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static Enumeration emptyEnumeration() { + // return (Enumeration) EmptyEnumeration.EMPTY_ENUMERATION; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + // DIFFBLUE MODEL LIBRARY - not used in model + // private static class EmptyEnumeration implements Enumeration { + // static final EmptyEnumeration EMPTY_ENUMERATION + // = new EmptyEnumeration<>(); + + // public boolean hasMoreElements() { return false; } + // public E nextElement() { throw new NoSuchElementException(); } + // } + + /** + * The empty set (immutable). This set is serializable. + * + * @see #emptySet() + */ + @SuppressWarnings("rawtypes") + public static final Set EMPTY_SET = new EmptySet<>(); + + /** + * Returns an empty set (immutable). This set is serializable. + * Unlike the like-named field, this method is parameterized. + * + *

This example illustrates the type-safe way to obtain an empty set: + *

+     *     Set<String> s = Collections.emptySet();
+     * 
+ * @implNote Implementations of this method need not create a separate + * {@code Set} object for each call. Using this method is likely to have + * comparable cost to using the like-named field. (Unlike this method, the + * field does not provide type safety.) + * + * @param the class of the objects in the set + * @return the empty set + * + * @see #EMPTY_SET + * @since 1.5 + * + * @diffblue.fullSupport + */ + @SuppressWarnings("unchecked") + public static final Set emptySet() { + return (Set) EMPTY_SET; + } + + /** + * @serial include + */ + private static class EmptySet + extends AbstractSet + implements Serializable + { + // DIFFBLUE MODELS LIBRARY - Not used in model + // private static final long serialVersionUID = 1582296315990362920L; + + // DIFFBLUE MODELS LIBRARY + // Most of these methods are trivial so we only test size() + // to ensure methods are called properly. + + public Iterator iterator() { return emptyIterator(); } + + public int size() {return 0;} + public boolean isEmpty() {return true;} + + public boolean contains(Object obj) {return false;} + public boolean containsAll(Collection c) { return c.isEmpty(); } + + public Object[] toArray() { return new Object[0]; } + + public T[] toArray(T[] a) { + if (a.length > 0) + a[0] = null; + return a; + } + + // Override default methods in Collection + @Override + public void forEach(Consumer action) { + Objects.requireNonNull(action); + } + @Override + public boolean removeIf(Predicate filter) { + Objects.requireNonNull(filter); + return false; + } + @Override + public Spliterator spliterator() { return Spliterators.emptySpliterator(); } + + // DIFFBLUE MODELS LIBRARY - not used in model + // // Preserves singleton property + // private Object readResolve() { + // return EMPTY_SET; + // } + } + + /** + * Returns an empty sorted set (immutable). This set is serializable. + * + *

This example illustrates the type-safe way to obtain an empty + * sorted set: + *

 {@code
+     *     SortedSet s = Collections.emptySortedSet();
+     * }
+ * + * @implNote Implementations of this method need not create a separate + * {@code SortedSet} object for each call. + * + * @param type of elements, if there were any, in the set + * @return the empty sorted set + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static SortedSet emptySortedSet() { + // return (SortedSet) UnmodifiableNavigableSet.EMPTY_NAVIGABLE_SET; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns an empty navigable set (immutable). This set is serializable. + * + *

This example illustrates the type-safe way to obtain an empty + * navigable set: + *

 {@code
+     *     NavigableSet s = Collections.emptyNavigableSet();
+     * }
+ * + * @implNote Implementations of this method need not + * create a separate {@code NavigableSet} object for each call. + * + * @param type of elements, if there were any, in the set + * @return the empty navigable set + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static NavigableSet emptyNavigableSet() { + // return (NavigableSet) UnmodifiableNavigableSet.EMPTY_NAVIGABLE_SET; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * The empty list (immutable). This list is serializable. + * + * @see #emptyList() + */ + @SuppressWarnings("rawtypes") + public static final List EMPTY_LIST = new EmptyList<>(); + + /** + * Returns an empty list (immutable). This list is serializable. + * + *

This example illustrates the type-safe way to obtain an empty list: + *

+     *     List<String> s = Collections.emptyList();
+     * 
+ * + * @implNote + * Implementations of this method need not create a separate List + * object for each call. Using this method is likely to have comparable + * cost to using the like-named field. (Unlike this method, the field does + * not provide type safety.) + * + * @param type of elements, if there were any, in the list + * @return an empty immutable list + * + * @see #EMPTY_LIST + * @since 1.5 + * + * @diffblue.fullSupport + */ + @SuppressWarnings("unchecked") + public static final List emptyList() { + return (List) EMPTY_LIST; + } + + /** + * @serial include + */ + private static class EmptyList + extends AbstractList + implements RandomAccess, Serializable { + // DIFFBLUE MODELS LIBRARY + // private static final long serialVersionUID = 8842843931221139166L; + + // DIFFBLUE MODELS LIBRARY + // Most of these methods are trivial so we only test size() + // to ensure methods are called properly. + + public Iterator iterator() { + return emptyIterator(); + } + public ListIterator listIterator() { + return emptyListIterator(); + } + + public int size() {return 0;} + public boolean isEmpty() {return true;} + + public boolean contains(Object obj) {return false;} + public boolean containsAll(Collection c) { return c.isEmpty(); } + + public Object[] toArray() { return new Object[0]; } + + public T[] toArray(T[] a) { + if (a.length > 0) + a[0] = null; + return a; + } + + public E get(int index) { + throw new IndexOutOfBoundsException("Index: "+index); + } + + public boolean equals(Object o) { + return (o instanceof List) && ((List)o).isEmpty(); + } + + public int hashCode() { return 1; } + + @Override + public boolean removeIf(Predicate filter) { + Objects.requireNonNull(filter); + return false; + } + @Override + public void replaceAll(UnaryOperator operator) { + Objects.requireNonNull(operator); + } + @Override + public void sort(Comparator c) { + } + + // Override default methods in Collection + @Override + public void forEach(Consumer action) { + Objects.requireNonNull(action); + } + + @Override + public Spliterator spliterator() { return Spliterators.emptySpliterator(); } + + // DIFFBLUE MODELS LIBRARY - Not used in model + // // Preserves singleton property + // private Object readResolve() { + // return EMPTY_LIST; + // } + } + + /** + * The empty map (immutable). This map is serializable. + * + * @see #emptyMap() + * @since 1.3 + */ + @SuppressWarnings("rawtypes") + public static final Map EMPTY_MAP = new EmptyMap<>(); + + /** + * Returns an empty map (immutable). This map is serializable. + * + *

This example illustrates the type-safe way to obtain an empty map: + *

+     *     Map<String, Date> s = Collections.emptyMap();
+     * 
+ * @implNote Implementations of this method need not create a separate + * {@code Map} object for each call. Using this method is likely to have + * comparable cost to using the like-named field. (Unlike this method, the + * field does not provide type safety.) + * + * @param the class of the map keys + * @param the class of the map values + * @return an empty map + * @see #EMPTY_MAP + * @since 1.5 + * + * @diffblue.fullSupport + */ + @SuppressWarnings("unchecked") + public static final Map emptyMap() { + return (Map) EMPTY_MAP; + } + + /** + * Returns an empty sorted map (immutable). This map is serializable. + * + *

This example illustrates the type-safe way to obtain an empty map: + *

 {@code
+     *     SortedMap s = Collections.emptySortedMap();
+     * }
+ * + * @implNote Implementations of this method need not create a separate + * {@code SortedMap} object for each call. + * + * @param the class of the map keys + * @param the class of the map values + * @return an empty sorted map + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static final SortedMap emptySortedMap() { + // return (SortedMap) UnmodifiableNavigableMap.EMPTY_NAVIGABLE_MAP; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns an empty navigable map (immutable). This map is serializable. + * + *

This example illustrates the type-safe way to obtain an empty map: + *

 {@code
+     *     NavigableMap s = Collections.emptyNavigableMap();
+     * }
+ * + * @implNote Implementations of this method need not create a separate + * {@code NavigableMap} object for each call. + * + * @param the class of the map keys + * @param the class of the map values + * @return an empty navigable map + * @since 1.8 + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static final NavigableMap emptyNavigableMap() { + // return (NavigableMap) UnmodifiableNavigableMap.EMPTY_NAVIGABLE_MAP; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + private static class EmptyMap + extends AbstractMap + implements Serializable + { + // DIFFBLUE MODELS LIBRARY + // private static final long serialVersionUID = 6428348081105594320L; + + // DIFFBLUE MODELS LIBRARY + // Most of these methods are trivial so we only test size() + // to ensure methods are called properly. + + public int size() {return 0;} + public boolean isEmpty() {return true;} + public boolean containsKey(Object key) {return false;} + public boolean containsValue(Object value) {return false;} + public V get(Object key) {return null;} + public Set keySet() {return emptySet();} + public Collection values() {return emptySet();} + public Set> entrySet() {return emptySet();} + + public boolean equals(Object o) { + return (o instanceof Map) && ((Map)o).isEmpty(); + } + + public int hashCode() {return 0;} + + // Override default methods in Map + @Override + @SuppressWarnings("unchecked") + public V getOrDefault(Object k, V defaultValue) { + return defaultValue; + } + + @Override + public void forEach(BiConsumer action) { + Objects.requireNonNull(action); + } + + @Override + public void replaceAll(BiFunction function) { + Objects.requireNonNull(function); + } + + @Override + public V putIfAbsent(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object key, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean replace(K key, V oldValue, V newValue) { + throw new UnsupportedOperationException(); + } + + @Override + public V replace(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public V computeIfAbsent(K key, + Function mappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public V computeIfPresent(K key, + BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public V compute(K key, + BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public V merge(K key, V value, + BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + // // Preserves singleton property + // private Object readResolve() { + // return EMPTY_MAP; + // } + } + + // Singleton collections + + /** + * Returns an immutable set containing only the specified object. + * The returned set is serializable. + * + * @param the class of the objects in the set + * @param o the sole object to be stored in the returned set. + * @return an immutable set containing only the specified object. + * + * @diffblue.fullSupport + */ + public static Set singleton(T o) { + return new SingletonSet<>(o); + } + + static Iterator singletonIterator(final E e) { + return new Iterator() { + private boolean hasNext = true; + public boolean hasNext() { + return hasNext; + } + public E next() { + if (hasNext) { + hasNext = false; + return e; + } + throw new NoSuchElementException(); + } + public void remove() { + throw new UnsupportedOperationException(); + } + @Override + public void forEachRemaining(Consumer action) { + Objects.requireNonNull(action); + if (hasNext) { + action.accept(e); + hasNext = false; + } + } + }; + } + + /** + * Creates a {@code Spliterator} with only the specified element + * + * @param Type of elements + * @return A singleton {@code Spliterator} + */ + static Spliterator singletonSpliterator(final T element) { + return new Spliterator() { + long est = 1; + + @Override + public Spliterator trySplit() { + return null; + } + + @Override + public boolean tryAdvance(Consumer consumer) { + Objects.requireNonNull(consumer); + if (est > 0) { + est--; + consumer.accept(element); + return true; + } + return false; + } + + @Override + public void forEachRemaining(Consumer consumer) { + tryAdvance(consumer); + } + + @Override + public long estimateSize() { + return est; + } + + @Override + public int characteristics() { + int value = (element != null) ? Spliterator.NONNULL : 0; + + return value | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE | + Spliterator.DISTINCT | Spliterator.ORDERED; + } + }; + } + + /** + * @serial include + */ + private static class SingletonSet + extends AbstractSet + implements Serializable + { + // DIFFBLUE MODELS LIBRARY - Not used in model + // private static final long serialVersionUID = 3193687207550431679L; + + private final E element; + + SingletonSet(E e) {element = e;} + + public Iterator iterator() { + return singletonIterator(element); + } + + public int size() {return 1;} + + public boolean contains(Object o) {return eq(o, element);} + + // Override default methods for Collection + @Override + public void forEach(Consumer action) { + action.accept(element); + } + @Override + public Spliterator spliterator() { + return singletonSpliterator(element); + } + @Override + public boolean removeIf(Predicate filter) { + throw new UnsupportedOperationException(); + } + } + + /** + * Returns an immutable list containing only the specified object. + * The returned list is serializable. + * + * @param the class of the objects in the list + * @param o the sole object to be stored in the returned list. + * @return an immutable list containing only the specified object. + * @since 1.3 + * + * @diffblue.fullSupport + */ + public static List singletonList(T o) { + return new SingletonList<>(o); + } + + /** + * @serial include + */ + private static class SingletonList + extends AbstractList + implements RandomAccess, Serializable { + + // DIFFBLUE MODELS LIBRARY - not used in model + // private static final long serialVersionUID = 3093736618740652951L; + + private final E element; + + SingletonList(E obj) {element = obj;} + + public Iterator iterator() { + return singletonIterator(element); + } + + public int size() {return 1;} + + public boolean contains(Object obj) {return eq(obj, element);} + + public E get(int index) { + if (index != 0) + throw new IndexOutOfBoundsException("Index: "+index+", Size: 1"); + return element; + } + + // Override default methods for Collection + @Override + public void forEach(Consumer action) { + action.accept(element); + } + @Override + public boolean removeIf(Predicate filter) { + throw new UnsupportedOperationException(); + } + @Override + public void replaceAll(UnaryOperator operator) { + throw new UnsupportedOperationException(); + } + @Override + public void sort(Comparator c) { + } + @Override + public Spliterator spliterator() { + return singletonSpliterator(element); + } + } + + /** + * Returns an immutable map, mapping only the specified key to the + * specified value. The returned map is serializable. + * + * @param the class of the map keys + * @param the class of the map values + * @param key the sole key to be stored in the returned map. + * @param value the value to which the returned map maps key. + * @return an immutable map containing only the specified key-value + * mapping. + * @since 1.3 + * + * @diffblue.fullSupport + */ + public static Map singletonMap(K key, V value) { + return new SingletonMap<>(key, value); + } + + /** + * @serial include + */ + private static class SingletonMap + extends AbstractMap + implements Serializable { + // private static final long serialVersionUID = -6979724477215052911L; + + private final K k; + private final V v; + + SingletonMap(K key, V value) { + k = key; + v = value; + } + + public int size() {return 1;} + public boolean isEmpty() {return false;} + public boolean containsKey(Object key) {return eq(key, k);} + public boolean containsValue(Object value) {return eq(value, v);} + public V get(Object key) {return (eq(key, k) ? v : null);} + + // private transient Set keySet; + // private transient Set> entrySet; + // private transient Collection values; + + public Set keySet() { + // if (keySet==null) + // keySet = singleton(k); + // return keySet; + return singleton(k); + } + + public Set> entrySet() { + // if (entrySet==null) + // entrySet = Collections.>singleton( + // new SimpleImmutableEntry<>(k, v)); + // return entrySet; + return Collections.>singleton( + new SimpleImmutableEntry<>(k, v)); + } + + public Collection values() { + // if (values==null) + // values = singleton(v); + // return values; + return singleton(v); + } + + // Override default methods in Map + @Override + public V getOrDefault(Object key, V defaultValue) { + return eq(key, k) ? v : defaultValue; + } + + @Override + public void forEach(BiConsumer action) { + action.accept(k, v); + } + + @Override + public void replaceAll(BiFunction function) { + throw new UnsupportedOperationException(); + } + + @Override + public V putIfAbsent(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object key, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean replace(K key, V oldValue, V newValue) { + throw new UnsupportedOperationException(); + } + + @Override + public V replace(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public V computeIfAbsent(K key, + Function mappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public V computeIfPresent(K key, + BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public V compute(K key, + BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public V merge(K key, V value, + BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + } + + // Miscellaneous + + /** + * Returns an immutable list consisting of n copies of the + * specified object. The newly allocated data object is tiny (it contains + * a single reference to the data object). This method is useful in + * combination with the List.addAll method to grow lists. + * The returned list is serializable. + * + * @param the class of the object to copy and of the objects + * in the returned list. + * @param n the number of elements in the returned list. + * @param o the element to appear repeatedly in the returned list. + * @return an immutable list consisting of n copies of the + * specified object. + * @throws IllegalArgumentException if {@code n < 0} + * @see List#addAll(Collection) + * @see List#addAll(int, Collection) + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static List nCopies(int n, T o) { + // if (n < 0) + // throw new IllegalArgumentException("List length = " + n); + // return new CopiesList<>(n, o); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static class CopiesList + // extends AbstractList + // implements RandomAccess, Serializable + // { + // private static final long serialVersionUID = 2739099268398711800L; + + // final int n; + // final E element; + + // CopiesList(int n, E e) { + // assert n >= 0; + // this.n = n; + // element = e; + // } + + // public int size() { + // return n; + // } + + // public boolean contains(Object obj) { + // return n != 0 && eq(obj, element); + // } + + // public int indexOf(Object o) { + // return contains(o) ? 0 : -1; + // } + + // public int lastIndexOf(Object o) { + // return contains(o) ? n - 1 : -1; + // } + + // public E get(int index) { + // if (index < 0 || index >= n) + // throw new IndexOutOfBoundsException("Index: "+index+ + // ", Size: "+n); + // return element; + // } + + // public Object[] toArray() { + // final Object[] a = new Object[n]; + // if (element != null) + // Arrays.fill(a, 0, n, element); + // return a; + // } + + // @SuppressWarnings("unchecked") + // public T[] toArray(T[] a) { + // final int n = this.n; + // if (a.length < n) { + // a = (T[])java.lang.reflect.Array + // .newInstance(a.getClass().getComponentType(), n); + // if (element != null) + // Arrays.fill(a, 0, n, element); + // } else { + // Arrays.fill(a, 0, n, element); + // if (a.length > n) + // a[n] = null; + // } + // return a; + // } + + // public List subList(int fromIndex, int toIndex) { + // if (fromIndex < 0) + // throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); + // if (toIndex > n) + // throw new IndexOutOfBoundsException("toIndex = " + toIndex); + // if (fromIndex > toIndex) + // throw new IllegalArgumentException("fromIndex(" + fromIndex + + // ") > toIndex(" + toIndex + ")"); + // return new CopiesList<>(toIndex - fromIndex, element); + // } + + // // Override default methods in Collection + // @Override + // public Stream stream() { + // return IntStream.range(0, n).mapToObj(i -> element); + // } + + // @Override + // public Stream parallelStream() { + // return IntStream.range(0, n).parallel().mapToObj(i -> element); + // } + + // @Override + // public Spliterator spliterator() { + // return stream().spliterator(); + // } + // } + + /** + * Returns a comparator that imposes the reverse of the natural + * ordering on a collection of objects that implement the + * {@code Comparable} interface. (The natural ordering is the ordering + * imposed by the objects' own {@code compareTo} method.) This enables a + * simple idiom for sorting (or maintaining) collections (or arrays) of + * objects that implement the {@code Comparable} interface in + * reverse-natural-order. For example, suppose {@code a} is an array of + * strings. Then:
+     *          Arrays.sort(a, Collections.reverseOrder());
+     * 
sorts the array in reverse-lexicographic (alphabetical) order.

+ * + * The returned comparator is serializable. + * + * @param the class of the objects compared by the comparator + * @return A comparator that imposes the reverse of the natural + * ordering on a collection of objects that implement + * the Comparable interface. + * @see Comparable + * + * @diffblue.untested + * @diffblue.noSupport + */ + @SuppressWarnings("unchecked") + public static Comparator reverseOrder() { + // return (Comparator) ReverseComparator.REVERSE_ORDER; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static class ReverseComparator + // implements Comparator>, Serializable { + + // private static final long serialVersionUID = 7207038068494060240L; + + // static final ReverseComparator REVERSE_ORDER + // = new ReverseComparator(); + + // public int compare(Comparable c1, Comparable c2) { + // return c2.compareTo(c1); + // } + + // private Object readResolve() { return Collections.reverseOrder(); } + + // @Override + // public Comparator> reversed() { + // return Comparator.naturalOrder(); + // } + // } + + /** + * Returns a comparator that imposes the reverse ordering of the specified + * comparator. If the specified comparator is {@code null}, this method is + * equivalent to {@link #reverseOrder()} (in other words, it returns a + * comparator that imposes the reverse of the natural ordering on + * a collection of objects that implement the Comparable interface). + * + *

The returned comparator is serializable (assuming the specified + * comparator is also serializable or {@code null}). + * + * @param the class of the objects compared by the comparator + * @param cmp a comparator who's ordering is to be reversed by the returned + * comparator or {@code null} + * @return A comparator that imposes the reverse ordering of the + * specified comparator. + * @since 1.5 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Comparator reverseOrder(Comparator cmp) { + // if (cmp == null) + // return reverseOrder(); + + // if (cmp instanceof ReverseComparator2) + // return ((ReverseComparator2)cmp).cmp; + + // return new ReverseComparator2<>(cmp); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static class ReverseComparator2 implements Comparator, + // Serializable + // { + // private static final long serialVersionUID = 4374092139857L; + + // /** + // * The comparator specified in the static factory. This will never + // * be null, as the static factory returns a ReverseComparator + // * instance if its argument is null. + // * + // * @serial + // */ + // final Comparator cmp; + + // ReverseComparator2(Comparator cmp) { + // assert cmp != null; + // this.cmp = cmp; + // } + + // public int compare(T t1, T t2) { + // return cmp.compare(t2, t1); + // } + + // public boolean equals(Object o) { + // return (o == this) || + // (o instanceof ReverseComparator2 && + // cmp.equals(((ReverseComparator2)o).cmp)); + // } + + // public int hashCode() { + // return cmp.hashCode() ^ Integer.MIN_VALUE; + // } + + // @Override + // public Comparator reversed() { + // return cmp; + // } + // } + + /** + * Returns an enumeration over the specified collection. This provides + * interoperability with legacy APIs that require an enumeration + * as input. + * + * @param the class of the objects in the collection + * @param c the collection for which an enumeration is to be returned. + * @return an enumeration over the specified collection. + * @see Enumeration + * + * @diffblue.untested + */ + public static Enumeration enumeration(final Collection c) { + return new Enumeration() { + private final Iterator i = c.iterator(); + + public boolean hasMoreElements() { + return i.hasNext(); + } + + public T nextElement() { + return i.next(); + } + }; + } + + /** + * Returns an array list containing the elements returned by the + * specified enumeration in the order they are returned by the + * enumeration. This method provides interoperability between + * legacy APIs that return enumerations and new APIs that require + * collections. + * + * @param the class of the objects returned by the enumeration + * @param e enumeration providing elements for the returned + * array list + * @return an array list containing the elements returned + * by the specified enumeration. + * @since 1.4 + * @see Enumeration + * @see ArrayList + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static ArrayList list(Enumeration e) { + // ArrayList l = new ArrayList<>(); + // while (e.hasMoreElements()) + // l.add(e.nextElement()); + // return l; + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * Returns true if the specified arguments are equal, or both null. + * + * NB: Do not replace with Object.equals until JDK-8015417 is resolved. + */ + static boolean eq(Object o1, Object o2) { + return o1==null ? o2==null : o1.equals(o2); + } + + /** + * Returns the number of elements in the specified collection equal to the + * specified object. More formally, returns the number of elements + * e in the collection such that + * (o == null ? e == null : o.equals(e)). + * + * @param c the collection in which to determine the frequency + * of o + * @param o the object whose frequency is to be determined + * @return the number of elements in {@code c} equal to {@code o} + * @throws NullPointerException if c is null + * @since 1.5 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static int frequency(Collection c, Object o) { + // int result = 0; + // if (o == null) { + // for (Object e : c) + // if (e == null) + // result++; + // } else { + // for (Object e : c) + // if (o.equals(e)) + // result++; + // } + // return result; + CProver.notModelled(); + return CProver.nondetInt(); + } + + /** + * Returns {@code true} if the two specified collections have no + * elements in common. + * + *

Care must be exercised if this method is used on collections that + * do not comply with the general contract for {@code Collection}. + * Implementations may elect to iterate over either collection and test + * for containment in the other collection (or to perform any equivalent + * computation). If either collection uses a nonstandard equality test + * (as does a {@link SortedSet} whose ordering is not compatible with + * equals, or the key set of an {@link IdentityHashMap}), both + * collections must use the same nonstandard equality test, or the + * result of this method is undefined. + * + *

Care must also be exercised when using collections that have + * restrictions on the elements that they may contain. Collection + * implementations are allowed to throw exceptions for any operation + * involving elements they deem ineligible. For absolute safety the + * specified collections should contain only elements which are + * eligible elements for both collections. + * + *

Note that it is permissible to pass the same collection in both + * parameters, in which case the method will return {@code true} if and + * only if the collection is empty. + * + * @param c1 a collection + * @param c2 a collection + * @return {@code true} if the two specified collections have no + * elements in common. + * @throws NullPointerException if either collection is {@code null}. + * @throws NullPointerException if one collection contains a {@code null} + * element and {@code null} is not an eligible element for the other collection. + * (optional) + * @throws ClassCastException if one collection contains an element that is + * of a type which is ineligible for the other collection. + * (optional) + * @since 1.5 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static boolean disjoint(Collection c1, Collection c2) { + // // The collection to be used for contains(). Preference is given to + // // the collection who's contains() has lower O() complexity. + // Collection contains = c2; + // // The collection to be iterated. If the collections' contains() impl + // // are of different O() complexity, the collection with slower + // // contains() will be used for iteration. For collections who's + // // contains() are of the same complexity then best performance is + // // achieved by iterating the smaller collection. + // Collection iterate = c1; + + // // Performance optimization cases. The heuristics: + // // 1. Generally iterate over c1. + // // 2. If c1 is a Set then iterate over c2. + // // 3. If either collection is empty then result is always true. + // // 4. Iterate over the smaller Collection. + // if (c1 instanceof Set) { + // // Use c1 for contains as a Set's contains() is expected to perform + // // better than O(N/2) + // iterate = c2; + // contains = c1; + // } else if (!(c2 instanceof Set)) { + // // Both are mere Collections. Iterate over smaller collection. + // // Example: If c1 contains 3 elements and c2 contains 50 elements and + // // assuming contains() requires ceiling(N/2) comparisons then + // // checking for all c1 elements in c2 would require 75 comparisons + // // (3 * ceiling(50/2)) vs. checking all c2 elements in c1 requiring + // // 100 comparisons (50 * ceiling(3/2)). + // int c1size = c1.size(); + // int c2size = c2.size(); + // if (c1size == 0 || c2size == 0) { + // // At least one collection is empty. Nothing will match. + // return true; + // } + + // if (c1size > c2size) { + // iterate = c2; + // contains = c1; + // } + // } + + // for (Object e : iterate) { + // if (contains.contains(e)) { + // // Found a common element. Collections are not disjoint. + // return false; + // } + // } + + // // No common elements were found. + // return true; + CProver.notModelled(); + return CProver.nondetBoolean(); + } + + /** + * Adds all of the specified elements to the specified collection. + * Elements to be added may be specified individually or as an array. + * The behavior of this convenience method is identical to that of + * c.addAll(Arrays.asList(elements)), but this method is likely + * to run significantly faster under most implementations. + * + *

When elements are specified individually, this method provides a + * convenient way to add a few elements to an existing collection: + *

+     *     Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");
+     * 
+ * + * @param the class of the elements to add and of the collection + * @param c the collection into which elements are to be inserted + * @param elements the elements to insert into c + * @return true if the collection changed as a result of the call + * @throws UnsupportedOperationException if c does not support + * the add operation + * @throws NullPointerException if elements contains one or more + * null values and c does not permit null elements, or + * if c or elements are null + * @throws IllegalArgumentException if some property of a value in + * elements prevents it from being added to c + * @see Collection#addAll(Collection) + * @since 1.5 + * + * @diffblue.fullSupport + */ + @SafeVarargs + public static boolean addAll(Collection c, T... elements) { + boolean result = false; + for (T element : elements) + result |= c.add(element); + return result; + } + + /** + * Returns a set backed by the specified map. The resulting set displays + * the same ordering, concurrency, and performance characteristics as the + * backing map. In essence, this factory method provides a {@link Set} + * implementation corresponding to any {@link Map} implementation. There + * is no need to use this method on a {@link Map} implementation that + * already has a corresponding {@link Set} implementation (such as {@link + * HashMap} or {@link TreeMap}). + * + *

Each method invocation on the set returned by this method results in + * exactly one method invocation on the backing map or its keySet + * view, with one exception. The addAll method is implemented + * as a sequence of put invocations on the backing map. + * + *

The specified map must be empty at the time this method is invoked, + * and should not be accessed directly after this method returns. These + * conditions are ensured if the map is created empty, passed directly + * to this method, and no reference to the map is retained, as illustrated + * in the following code fragment: + *

+     *    Set<Object> weakHashSet = Collections.newSetFromMap(
+     *        new WeakHashMap<Object, Boolean>());
+     * 
+ * + * @param the class of the map keys and of the objects in the + * returned set + * @param map the backing map + * @return the set backed by the map + * @throws IllegalArgumentException if map is not empty + * @since 1.6 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Set newSetFromMap(Map map) { + // return new SetFromMap<>(map); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // private static class SetFromMap extends AbstractSet + // implements Set, Serializable + // { + // private final Map m; // The backing map + // private transient Set s; // Its keySet + + // SetFromMap(Map map) { + // if (!map.isEmpty()) + // throw new IllegalArgumentException("Map is non-empty"); + // m = map; + // s = map.keySet(); + // } + + // public void clear() { m.clear(); } + // public int size() { return m.size(); } + // public boolean isEmpty() { return m.isEmpty(); } + // public boolean contains(Object o) { return m.containsKey(o); } + // public boolean remove(Object o) { return m.remove(o) != null; } + // public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; } + // public Iterator iterator() { return s.iterator(); } + // public Object[] toArray() { return s.toArray(); } + // public T[] toArray(T[] a) { return s.toArray(a); } + // public String toString() { return s.toString(); } + // public int hashCode() { return s.hashCode(); } + // public boolean equals(Object o) { return o == this || s.equals(o); } + // public boolean containsAll(Collection c) {return s.containsAll(c);} + // public boolean removeAll(Collection c) {return s.removeAll(c);} + // public boolean retainAll(Collection c) {return s.retainAll(c);} + // // addAll is the only inherited implementation + + // // Override default methods in Collection + // @Override + // public void forEach(Consumer action) { + // s.forEach(action); + // } + // @Override + // public boolean removeIf(Predicate filter) { + // return s.removeIf(filter); + // } + + // @Override + // public Spliterator spliterator() {return s.spliterator();} + // @Override + // public Stream stream() {return s.stream();} + // @Override + // public Stream parallelStream() {return s.parallelStream();} + + // private static final long serialVersionUID = 2454657854757543876L; + + // private void readObject(java.io.ObjectInputStream stream) + // throws IOException, ClassNotFoundException + // { + // stream.defaultReadObject(); + // s = m.keySet(); + // } + // } + + /** + * Returns a view of a {@link Deque} as a Last-in-first-out (Lifo) + * {@link Queue}. Method add is mapped to push, + * remove is mapped to pop and so on. This + * view can be useful when you would like to use a method + * requiring a Queue but you need Lifo ordering. + * + *

Each method invocation on the queue returned by this method + * results in exactly one method invocation on the backing deque, with + * one exception. The {@link Queue#addAll addAll} method is + * implemented as a sequence of {@link Deque#addFirst addFirst} + * invocations on the backing deque. + * + * @param the class of the objects in the deque + * @param deque the deque + * @return the queue + * @since 1.6 + * + * @diffblue.untested + * @diffblue.noSupport + */ + public static Queue asLifoQueue(Deque deque) { + // return new AsLIFOQueue<>(deque); + CProver.notModelled(); + return CProver.nondetWithoutNullForNotModelled(); + } + + /** + * @serial include + */ + // DIFFBLUE MODEL LIBRARY - not used in model + // static class AsLIFOQueue extends AbstractQueue + // implements Queue, Serializable { + // private static final long serialVersionUID = 1802017725587941708L; + // private final Deque q; + // AsLIFOQueue(Deque q) { this.q = q; } + // public boolean add(E e) { q.addFirst(e); return true; } + // public boolean offer(E e) { return q.offerFirst(e); } + // public E poll() { return q.pollFirst(); } + // public E remove() { return q.removeFirst(); } + // public E peek() { return q.peekFirst(); } + // public E element() { return q.getFirst(); } + // public void clear() { q.clear(); } + // public int size() { return q.size(); } + // public boolean isEmpty() { return q.isEmpty(); } + // public boolean contains(Object o) { return q.contains(o); } + // public boolean remove(Object o) { return q.remove(o); } + // public Iterator iterator() { return q.iterator(); } + // public Object[] toArray() { return q.toArray(); } + // public T[] toArray(T[] a) { return q.toArray(a); } + // public String toString() { return q.toString(); } + // public boolean containsAll(Collection c) {return q.containsAll(c);} + // public boolean removeAll(Collection c) {return q.removeAll(c);} + // public boolean retainAll(Collection c) {return q.retainAll(c);} + // // We use inherited addAll; forwarding addAll would be wrong + + // // Override default methods in Collection + // @Override + // public void forEach(Consumer action) {q.forEach(action);} + // @Override + // public boolean removeIf(Predicate filter) { + // return q.removeIf(filter); + // } + // @Override + // public Spliterator spliterator() {return q.spliterator();} + // @Override + // public Stream stream() {return q.stream();} + // @Override + // public Stream parallelStream() {return q.parallelStream();} + // } +}