/*=============================================================================#
 # Copyright (c) 2009, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.data;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;


/**
 * This is the abstract one-dimensional data store for an R data type.
 * <p>
 * Data stores are not directly R objects but are used in the data objects
 * {@link RVector} and {@link RArray}.</p>
 * <p>
 * There are store types for each atomic type of R (namely the types/modes
 * numeric, complex, logical, character and raw) and a special
 * type for factors.  To get the type of a RStore the method {@link #getStoreType()}
 * should be used.  The available data types are:</p>
 * <ul>
 *   <li>{@link #LOGICAL}</li>
 *   <li>{@link #INTEGER}</li>
 *   <li>{@link #NUMERIC}</li>
 *   <li>{@link #COMPLEX}</li>
 *   <li>{@link #CHARACTER}</li>
 *   <li>{@link #RAW}</li>
 *   <li>{@link #FACTOR}</li>
 * </ul>
 * <p>
 * The Java value can be accessed by the getter methods for the different
 * data types.  The indexes are zero-based like in Java and not one-base like in R.
 * Because Java doesn't provide NA for primitive data types directly,
 * the data store provides the methods {@link #isNA(int)} and {@link #setNA(int)}
 * to detect and set such values.
 * If the value at an index of the store is NA, the return value of the other getter
 * methods is undefined.</p>
 * <p>
 * Indexes are zero-based (as usual in Java) and not one-base like in R.</p>
 */
@NonNullByDefault
public interface RStore<P> {
	
	
	/**
	 * Constant indicating a store for R data type <code>logical<code>.
	 * 
	 * <p>The story object is an instance of {@link RLogicalStore}.
	 * The {@link #getBaseVectorRClassName() class name} is
	 * <code>{@link RObject#CLASSNAME_LOGICAL logical}</code>.</p>
	 * 
	 * @see #getLogi(int)
	 * @see #setLogi(int, boolean)
	 */
	byte LOGICAL=         0x00000001;
	
	/**
	 * Constant indicating a store for R data type <code>integer<code>.
	 * 
	 * <p>The story object is an instance of {@link RIntegerStore}.
	 * The {@link #getBaseVectorRClassName() class name} is
	 * <code>{@link RObject#CLASSNAME_INTEGER integer}</code>.</p>
	 * 
	 * @see #getInt(int)
	 * @see #setInt(int, int)
	 */
	byte INTEGER=         0x00000002;
	
	/**
	 * Constant indicating a store for R data type <code>logical<code>.
	 * 
	 * <p>The story object is an instance of {@link RNumericStore}.
	 * The {@link #getBaseVectorRClassName() class name} is
	 * <code>{@link RObject#CLASSNAME_NUMERIC numeric}</code>.</p>
	 * 
	 * @see #getNum(int)
	 * @see #setNum(int, double)
	 */
	byte NUMERIC=         0x00000003;
	
	/**
	 * Constant indicating a store for R data type <code>complex<code>.
	 * 
	 * <p>The story object is an instance of {@link RComplexStore}.
	 * The {@link #getBaseVectorRClassName() class name} is
	 * <code>{@link RObject#CLASSNAME_COMPLEX complex}</code>.</p>
	 * 
	 * @see #getCplxRe(int)
	 * @see #getCplxIm(int)
	 * @see #setCplx(int, double, double)
	 */
	byte COMPLEX=         0x00000004;
	
	/**
	 * Constant indicating a store for R data type <code>character<code>.
	 * 
	 * <p>The story object is an instance of {@link RCharacterStore}.
	 * The {@link #getBaseVectorRClassName() class name} is
	 * <code>{@link RObject#CLASSNAME_CHARACTER character}</code>.</p>
	 * 
	 * @see #getChar(int)
	 * @see #setChar(int, String)
	 */
	byte CHARACTER=       0x00000005;
	
	/**
	 * Constant indicating a store for R data type <code>raw<code>.
	 * 
	 * <p>Note that raw data doesn't support NAs.</p>
	 * 
	 * <p>The story object is an instance of {@link RRawStore}.
	 * The {@link #getBaseVectorRClassName() class name} is
	 * <code>{@link RObject#CLASSNAME_RAW raw}</code>.</p>
	 * 
	 * @see #getRaw(int)
	 * @see #setRaw(int, byte)
	 */
	byte RAW=             0x00000006;
	
	/**
	 * Constant indicating a special store extending the integer
	 * data type for R objects extending the R class <code>factor<code>.
	 * 
	 * <p>The story object is an instance of {@link RFactorStore}.
	 * The {@link #getBaseVectorRClassName() class name} is
	 * <code>{@link RObject#CLASSNAME_FACTOR factor}</code> or
	 * <code>{@link RObject#CLASSNAME_ORDERED ordered}</code>.
	 * 
	 * @see RFactorStore#getInt(int)
	 * @see RFactorStore#getChar(int)
	 * @see RFactorStore#setInt(int, int)
	 * @see RFactorStore#setChar(int, String)
	 **/
	byte FACTOR=          0x0000000a;
	
	
	/**
	 * Returns the constant indicating the type of this RStore.
	 * 
	 * @return one of the constant defined in the {@link RStore} interface
	 */
	byte getStoreType();
	
	/**
	 * Returns the R class name a vector with this data store and no other
	 * class definitions will have.
	 * 
	 * @return the class name
	 */
	String getBaseVectorRClassName();
	
	/**
	 * Returns the length of this data store.
	 * 
	 * <p>If this is a data store dummy for structure only R objects in Java
	 * ({@link RObjectFactory#F_ONLY_STRUCT}), the value is <code>-1</code>.
	 * 
	 * @return the length or <code>-1</code>
	 */
	long getLength();
	
	/**
	 * Tests if the value at the specified index is NA.
	 * <p>
	 * Note that the analogous method to the R function <code>is.na(x)</code>
	 * is {@link #isMissing(int)}; this method returns <code>false</code> for NaN values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return <code>true</code>, if the value at the specified index is NA, otherwise <code>false</code>
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	boolean isNA(int idx);
	
	/**
	 * Tests if the value at the specified index is NA.
	 * <p>
	 * Note that the analogous method to the R function <code>is.na(x)</code>
	 * is {@link #isMissing(int)}; this method returns <code>false</code> for NaN values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return <code>true</code>, if the value at the specified index is NA, otherwise <code>false</code>
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	boolean isNA(long idx);
	
	/**
	 * Tests if the value at the specified index is NA <b>or</b> NaN (if supported by data type).
	 * It works by analogy with the R function <code>is.na(x)</code>.
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return <code>true</code>, if the value at the specified index is NA or NaN, otherwise <code>false</code>
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	boolean isMissing(int idx);
	
	/**
	 * Tests if the value at the specified index is NA <b>or</b> NaN (if supported by data type).
	 * It works by analogy with the R function <code>is.na(x)</code>.
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return <code>true</code>, if the value at the specified index is NA or NaN, otherwise <code>false</code>
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	boolean isMissing(long idx);
	
	/**
	 * Sets the value at the specified index to NA.
	 * <p>
	 * Note that raw doesn't support NAs.</p>.
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param idx the index of the value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setNA(int idx);
	
	/**
	 * Sets the value at the specified index to NA.
	 * <p>
	 * Note that raw doesn't support NAs.</p>.
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param idx the index of the value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setNA(long idx);
	
	/**
	 * Return the logical/boolean value at the specified index.
	 * <p>
	 * Logical values in R matches exactly the Java boolean values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current logical value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	boolean getLogi(int idx);
	
	/**
	 * Return the logical/boolean value at the specified index.
	 * <p>
	 * Logical values in R matches exactly the Java boolean values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current logical value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	boolean getLogi(long idx);
	
	/**
	 * Sets the logical/boolean value at the specified index.
	 * <p>
	 * Logical values in R matches exactly the Java boolean values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param logical the logical value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setLogi(int idx, boolean logical);
	
	/**
	 * Sets the logical/boolean value at the specified index.
	 * <p>
	 * Logical values in R matches exactly the Java boolean values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param logical the logical value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setLogi(long idx, boolean logical);
	
	/**
	 * Return the integer/int value at the specified index.
	 * <p>
	 * Integer values in R matches exactly the Java int values, except
	 * {@link Integer#MIN_VALUE} which doesn't exists in R and is mapped to NA.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current integer value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	int getInt(int idx);
	
	/**
	 * Return the integer/int value at the specified index.
	 * <p>
	 * Integer values in R matches exactly the Java int values, except
	 * {@link Integer#MIN_VALUE} which doesn't exists in R and is mapped to NA.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current integer value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	int getInt(long idx);
	
	/**
	 * Sets the integer/int value at the specified index.
	 * <p>
	 * Integer values in R matches exactly the Java int values, except
	 * {@link Integer#MIN_VALUE} which doesn't exists in R and is mapped to NA.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param integer the integer value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setInt(int idx, int integer);
	
	/**
	 * Sets the integer/int value at the specified index.
	 * <p>
	 * Integer values in R matches exactly the Java int values, except
	 * {@link Integer#MIN_VALUE} which doesn't exists in R and is mapped to NA.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param integer the integer value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setInt(long idx, int integer);
	
	/**
	 * Return the numeric/real/double value at the specified index.
	 * <p>
	 * Numeric values in R matches exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {@link Double#isNaN(double)},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current real value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	double getNum(int idx);
	
	/**
	 * Return the numeric/real/double value at the specified index.
	 * <p>
	 * Numeric values in R matches exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {@link Double#isNaN(double)},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current real value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	double getNum(long idx);
	
	/**
	 * Sets the numeric/real/double value at the specified index.
	 * <p>
	 * Numeric values in R matches exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {@link Double#NaN},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param numeric the real value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setNum(int idx, double numeric);
	
	/**
	 * Sets the numeric/real/double value at the specified index.
	 * <p>
	 * Numeric values in R matches exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {@link Double#NaN},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param numeric the real value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setNum(long idx, double numeric);
	
	/**
	 * Returns the real part the complex number value at the specified index.
	 * <p>
	 * The numeric values of the parts of the complex number in R matches
	 * exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {Double#isNaN(double)},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current real part of the complex number value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	double getCplxRe(int idx);
	
	/**
	 * Returns the real part the complex number value at the specified index.
	 * <p>
	 * The numeric values of the parts of the complex number in R matches
	 * exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {Double#isNaN(double)},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current real part of the complex number value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	double getCplxRe(long idx);
	
	/**
	 * Returns the imaginary part the complex number value at the specified index.
	 * <p>
	 * The numeric values of the parts of the complex number in R matches
	 * exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {Double#isNaN(double)},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current imaginary part of the complex number value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	double getCplxIm(int idx);
	
	/**
	 * Returns the imaginary part the complex number value at the specified index.
	 * <p>
	 * The numeric values of the parts of the complex number in R matches
	 * exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {Double#isNaN(double)},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current imaginary part of the complex number value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	double getCplxIm(long idx);
	
	/**
	 * Sets the complex number value at the specified index.
	 * <p>
	 * The numeric values of the parts of the complex number in R matches
	 * exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {@link Double#NaN},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param real the real part of the complex number value
	 * @param imaginary the imaginary part of the complex number value
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setCplx(int idx, double real, double imaginary);
	
	/**
	 * Sets the complex number value at the specified index.
	 * <p>
	 * The numeric values of the parts of the complex number in R matches
	 * exactly the Java double values.
	 * Also NaN, Inf and -Inf respectively {@link Double#NaN},
	 * {@link Double#POSITIVE_INFINITY} and {@link Double#NEGATIVE_INFINITY} are
	 * supported.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param real the real part of the complex number value
	 * @param imaginary the imaginary part of the complex number value
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setCplx(long idx, double real, double imaginary);
	
	/**
	 * Returns the character value at the specified index.
	 * <p>
	 * R character values matches exactly Java string values, if R supports
	 * UTF encoding.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current character value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	String getChar(int idx);
	
	/**
	 * Returns the character value at the specified index.
	 * <p>
	 * R character values matches exactly Java string values, if R supports
	 * UTF encoding.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current character value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	String getChar(long idx);
	
	/**
	 * Sets the character/String value at the specified index.
	 * <p>
	 * R character values matches exactly Java string values, if R supports
	 * UTF encoding.</p>
	 * <p>
	 * No quoting or escaping is required. Quoting or escaping the value
	 * would change the real value.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param character the character value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setChar(int idx, String character);
	
	/**
	 * Sets the character/String value at the specified index.
	 * <p>
	 * R character values matches exactly Java string values, if R supports
	 * UTF encoding.</p>
	 * <p>
	 * No quoting or escaping is required. Quoting or escaping the value
	 * would change the real value.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param character the character value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setChar(long idx, String character);
	
	/**
	 * Returns the raw/byte value at the specified index.
	 * <p>
	 * R raw values matches exactly Java byte values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current raw value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	byte getRaw(int idx);
	
	/**
	 * Returns the raw/byte value at the specified index.
	 * <p>
	 * R raw values matches exactly Java byte values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return the current raw value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	byte getRaw(long idx);
	
	/**
	 * Sets the raw/byte value at the specified index.
	 * <p>
	 * R raw values matches exactly Java byte values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param raw the raw value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setRaw(int idx, byte raw);
	
	/**
	 * Sets the raw/byte value at the specified index.
	 * <p>
	 * R raw values matches exactly Java byte values.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @param raw the raw value to set
	 * @throws UnsupportedOperationException if the store is not modifiable
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	void setRaw(long idx, byte raw);
	
	/**
	 * Returns the value at the specified index as Java object. The subtypes of
	 * RStore defines more specific array types.
	 * <p>
	 * R NA values are represented as <code>null</code>. Java primitives are converted
	 * into its wrapper classes.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return an object for the current value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	@Nullable P get(int idx);
	
	/**
	 * Returns the value at the specified index as Java object. The subtypes of
	 * RStore defines more specific array types.
	 * <p>
	 * R NA values are represented as <code>null</code>. Java primitives are converted
	 * into its wrapper classes.</p>
	 * 
	 * @param idx the index (zero-based) of the value
	 * @return an object for the current value
	 * @throws IndexOutOfBoundsException if the index is out of range
	 *     (idx &lt; 0 || idx &gt;= length()).
	 */
	@Nullable P get(long idx);
	
	/**
	 * Returns the values of the store as Java object array. The subtypes of
	 * RStore defines more specific array types.
	 * <p>
	 * The array is newly created for each call of this method. It has the
	 * length {@link #getLength()}. R NA values are represented as <code>null</code>
	 * in the array. Java primitives are converted into its wrapper classes.</p>
	 * 
	 * @return a object array with the values of the store
	 */
	@Nullable P [] toArray();
	
	boolean allEqual(RStore<?> other);
	
	
	/**
	 * Returns if the store contains the a NA value.
	 * 
	 * @return <code>true</code> if the store contains a NA value, otherwise false
	 * 
	 * @since de.walware.rj.data 2.1
	 */
	boolean containsNA();
	
	/**
	 * Returns the index of the first NA value in the store.
	 * 
	 * @return index (zero-base) of first equal value, otherwise <code>-1</code>
	 * 
	 * @since de.walware.rj.data 2.1
	 */
	long indexOfNA();
	
	/**
	 * Returns the index of the first NA value in the store, starting from the specified index.
	 * 
	 * @param fromIdx index (zero-based) from which to start the search
	 * @return index (zero-based) of first equal value, otherwise <code>-1</code>
	 * 
	 * @since de.walware.rj.data 2.1
	 */
	long indexOfNA(long fromIdx);
	
	/**
	 * Returns if the store contains the specified integer value.
	 * 
	 * @param value the value to search for
	 * @return <code>true</code> if the store contains the value, otherwise false
	 */
	boolean contains(final int integer);
	
	/**
	 * Returns the index of the first value in the store equal to the of the specified integer
	 * value.
	 * 
	 * @param integer the value to search for
	 * @return index (zero-based) of first equal value, otherwise <code>-1</code>
	 */
	long indexOf(int integer);
	
	/**
	 * Returns the index of the first value in the store equal to the of the specified integer
	 * value, starting from the specified index.
	 * 
	 * @param integer the value to search for
	 * @param fromIdx index (zero-based) from which to start the search
	 * @return index (zero-based) of first equal value, otherwise <code>-1</code>
	 */
	long indexOf(int integer, long fromIdx);
	
	/**
	 * Returns if the store contains the specified character value.
	 * 
	 * @param value the value to search for
	 * @return <code>true</code> if the store contains the value, otherwise false
	 */
	boolean contains(final String value);
	
	/**
	 * Returns the index of the first value in the store equal to the of the specified character
	 * value.
	 * 
	 * @param character the value to search for
	 * @return index (zero-base) of first equal value, otherwise <code>-1</code>
	 */
	long indexOf(String character);
	
	/**
	 * Returns the index of the first value in the store equal to the of the specified character
	 * value, starting from the specified index.
	 * 
	 * @param character the value to search for
	 * @param fromIdx index (zero-based) from which to start the search
	 * @return index (zero-based) of first equal value, otherwise <code>-1</code>
	 */
	long indexOf(String character, long fromIdx);
	
}
