function ArrayIndex( x ) {
	var opts;
	var err;
	var get;
	var dt;
	var t;
	var v;
	if ( !(this instanceof ArrayIndex) ) {
		if ( arguments.length > 1 ) {
			return new ArrayIndex( x, arguments[ 1 ] );
		}
		return new ArrayIndex( x );
	}
	if ( !isCollection( x ) ) {
		throw new TypeError( format( 'invalid argument. First argument must be an array-like object. Value: `%s`.', x ) );
	}
	dt = dtype( x );

	// When provided a "generic" array or an array of an unknown data type, attempt to infer the type of index array...
	if ( dt === 'generic' || dt === null ) {
		if ( x.length > 0 ) {
			get = resolveGetter( x );
			v = get( x, 0 );

			// Infer the "type" of index array from the first element...
			if ( isBoolean( v ) ) {
				t = 'bool';
			} else if ( isInteger( v ) ) {
				t = 'int';
			} else {
				throw new TypeError( 'invalid argument. First argument must be a valid index array.' );
			}
		} else {
			t = 'int';
		}
	} else if ( dt === 'int32' ) {
		t = 'int';
	} else if ( dt === 'uint8' ) {
		t = 'mask';
	} else if ( dt === 'bool' ) {
		t = 'bool';
	} else {
		throw new TypeError( 'invalid argument. First argument must be a valid index array.' );
	}
	// Resolve index options:
	opts = defaults();
	if ( arguments.length > 1 ) {
		err = validate( opts, arguments[ 1 ] );
		if ( err ) {
			throw err;
		}
	}
	// Add the array index to the index cache:
	cache.push({
		'id': generateId(),
		'ref': this,
		'data': x,
		'type': t,
		'dtype': dt,
		'persist': opts.persist
	});

	// Store a reference to the cache node:
	setReadOnly( this, '_node', cache.last() );

	// Initialize a boolean flag indicating whether an array index object has been invalidated (i.e., freed):
	setNonEnumerable( this, '_invalidated', false );

	return this;
}
Array index constructor.

@constructor
@param {Collection} x - input array
@param {Options} [options] - function options
@param {boolean} [options.persist=false] - boolean indicating whether to continue persisting an index object after first usage
@throws {TypeError} first argument must be an array-like object
@throws {TypeError} first argument must be a valid index array
@throws {TypeError} options argument must be an object
@throws {TypeError} must provide valid options
@returns {ArrayIndex} ArrayIndex instance

@example
var Uint8Array = require( '@stdlib/array/uint8' );

var x = new Uint8Array( [ 1, 0, 1, 0 ] );

var idx = new ArrayIndex( x );
// returns <ArrayIndex>