function Complex128Array() {
	var byteOffset;
	var nargs;
	var buf;
	var len;

	nargs = arguments.length;
	if ( !(this instanceof Complex128Array) ) {
		if ( nargs === 0 ) {
			return new Complex128Array();
		}
		if ( nargs === 1 ) {
			return new Complex128Array( arguments[0] );
		}
		if ( nargs === 2 ) {
			return new Complex128Array( arguments[0], arguments[1] );
		}
		return new Complex128Array( arguments[0], arguments[1], arguments[2] );
	}
	// Create the underlying data buffer...
	if ( nargs === 0 ) {
		buf = new Float64Array( 0 ); // backward-compatibility
	} else if ( nargs === 1 ) {
		if ( isNonNegativeInteger( arguments[0] ) ) {
			buf = new Float64Array( arguments[0]*2 );
		} else if ( isCollection( arguments[0] ) ) {
			buf = arguments[ 0 ];
			len = buf.length;

			// If provided a "generic" array, peak at the first value, and, if the value is a complex number, try to process as an array of complex numbers, falling back to "normal" typed array initialization if we fail and ensuring consistency if the first value had not been a complex number...
			if ( len && isArray( buf ) && isComplexLike( buf[0] ) ) {
				buf = fromArray( new Float64Array( len*2 ), buf );
				if ( buf === null ) {
					// We failed and we are now forced to allocate a new array :-(
					if ( !isEven( len ) ) {
						throw new RangeError( format( 'invalid argument. Array-like object arguments must have a length which is a multiple of two. Length: `%u`.', len ) );
					}
					// We failed, so fall back to directly setting values...
					buf = new Float64Array( arguments[0] );
				}
			} else {
				if ( isComplex64Array( buf ) ) {
					buf = reinterpret64( buf, 0 );
				} else if ( isComplex128Array( buf ) ) {
					buf = reinterpret128( buf, 0 );
				} else if ( !isEven( len ) ) {
					throw new RangeError( format( 'invalid argument. Array-like object and typed array arguments must have a length which is a multiple of two. Length: `%u`.', len ) );
				}
				buf = new Float64Array( buf );
			}
		} else if ( isArrayBuffer( arguments[0] ) ) {
			buf = arguments[ 0 ];
			if ( !isInteger( buf.byteLength/BYTES_PER_ELEMENT ) ) {
				throw new RangeError( format( 'invalid argument. ArrayBuffer byte length must be a multiple of %u. Byte length: `%u`.', BYTES_PER_ELEMENT, buf.byteLength ) );
			}
			buf = new Float64Array( buf );
		} else if ( isObject( arguments[0] ) ) {
			buf = arguments[ 0 ];
			if ( HAS_ITERATOR_SYMBOL === false ) {
				throw new TypeError( format( 'invalid argument. Environment lacks Symbol.iterator support. Must provide a length, ArrayBuffer, typed array, or array-like object. Value: `%s`.', buf ) );
			}
			if ( !isFunction( buf[ ITERATOR_SYMBOL ] ) ) {
				throw new TypeError( format( 'invalid argument. Must provide a length, ArrayBuffer, typed array, array-like object, or an iterable. Value: `%s`.', buf ) );
			}
			buf = buf[ ITERATOR_SYMBOL ]();
			if ( !isFunction( buf.next ) ) {
				throw new TypeError( format( 'invalid argument. Must provide a length, ArrayBuffer, typed array, array-like object, or an iterable. Value: `%s`.', buf ) );
			}
			buf = fromIterator( buf );
			if ( buf instanceof Error ) {
				throw buf;
			}
			buf = new Float64Array( buf );
		} else {
			throw new TypeError( format( 'invalid argument. Must provide a length, ArrayBuffer, typed array, array-like object, or an iterable. Value: `%s`.', arguments[0] ) );
		}
	} else {
		buf = arguments[ 0 ];
		if ( !isArrayBuffer( buf ) ) {
			throw new TypeError( format( 'invalid argument. First argument must be an ArrayBuffer. Value: `%s`.', buf ) );
		}
		byteOffset = arguments[ 1 ];
		if ( !isNonNegativeInteger( byteOffset ) ) {
			throw new TypeError( format( 'invalid argument. Byte offset must be a nonnegative integer. Value: `%s`.', byteOffset ) );
		}
		if ( !isInteger( byteOffset/BYTES_PER_ELEMENT ) ) {
			throw new RangeError( format( 'invalid argument. Byte offset must be a multiple of %u. Value: `%u`.', BYTES_PER_ELEMENT, byteOffset ) );
		}
		if ( nargs === 2 ) {
			len = buf.byteLength - byteOffset;
			if ( !isInteger( len/BYTES_PER_ELEMENT ) ) {
				throw new RangeError( format( 'invalid arguments. ArrayBuffer view byte length must be a multiple of %u. View byte length: `%u`.', BYTES_PER_ELEMENT, len ) );
			}
			buf = new Float64Array( buf, byteOffset );
		} else {
			len = arguments[ 2 ];
			if ( !isNonNegativeInteger( len ) ) {
				throw new TypeError( format( 'invalid argument. Length must be a nonnegative integer. Value: `%s`.', len ) );
			}
			if ( (len*BYTES_PER_ELEMENT) > (buf.byteLength-byteOffset) ) {
				throw new RangeError( format( 'invalid arguments. ArrayBuffer has insufficient capacity. Either decrease the array length or provide a bigger buffer. Minimum capacity: `%u`.', len*BYTES_PER_ELEMENT ) );
			}
			buf = new Float64Array( buf, byteOffset, len*2 );
		}
	}
	setReadOnly( this, '_buffer', buf );
	setReadOnly( this, '_length', buf.length/2 );

	return this;
}
128-bit complex number array constructor.

@constructor
@param {(NonNegativeInteger|Collection|ArrayBuffer|Iterable)} [arg] - length, typed array, array-like object, buffer, or iterable
@param {NonNegativeInteger} [byteOffset=0] - byte offset
@param {NonNegativeInteger} [length] - view length
@throws {RangeError} ArrayBuffer byte length must be a multiple of `16`
@throws {RangeError} array-like object and typed array input arguments must have a length which is a multiple of two
@throws {TypeError} if provided only a single argument, must provide a valid argument
@throws {TypeError} byte offset must be a nonnegative integer
@throws {RangeError} byte offset must be a multiple of `16`
@throws {TypeError} view length must be a positive multiple of `16`
@throws {RangeError} must provide sufficient memory to accommodate byte offset and view length requirements
@throws {TypeError} an iterator must return either a two element array containing real and imaginary components or a complex number
@returns {Complex128Array} complex number array

@example
var arr = new Complex128Array();
// returns <Complex128Array>

var len = arr.length;
// returns 0

@example
var arr = new Complex128Array( 2 );
// returns <Complex128Array>

var len = arr.length;
// returns 2

@example
var arr = new Complex128Array( [ 1.0, -1.0 ] );
// returns <Complex128Array>

var len = arr.length;
// returns 1

@example
var ArrayBuffer = require( '@stdlib/array/buffer' );

var buf = new ArrayBuffer( 32 );
var arr = new Complex128Array( buf );
// returns <Complex128Array>

var len = arr.length;
// returns 2

@example
var ArrayBuffer = require( '@stdlib/array/buffer' );

var buf = new ArrayBuffer( 32 );
var arr = new Complex128Array( buf, 16 );
// returns <Complex128Array>

var len = arr.length;
// returns 1

@example
var ArrayBuffer = require( '@stdlib/array/buffer' );

var buf = new ArrayBuffer( 64 );
var arr = new Complex128Array( buf, 16, 2 );
// returns <Complex128Array>

var len = arr.length;
// returns 2