diff --git a/bool/README.md b/bool/README.md new file mode 100644 index 00000000..8b44a8ba --- /dev/null +++ b/bool/README.md @@ -0,0 +1,511 @@ + + +# BooleanArray + +> Boolean array. + + + +
+ +
+ + + + + +
+ +## Usage + +```javascript +var BooleanArray = require( '@stdlib/array/bool' ); +``` + + + +#### BooleanArray() + +Creates a boolean array. + +```javascript +var arr = new BooleanArray(); +// returns +``` + +#### BooleanArray( length ) + +Creates a boolean array having a specified `length`. + +```javascript +var arr = new BooleanArray( 10 ); +// returns + +var len = arr.length; +// returns 10 +``` + +#### BooleanArray( booleanarray ) + +Creates a boolean array from another boolean array. + +```javascript +var arr1 = new BooleanArray( [ true, false, false, true ] ); +// returns + +var arr2 = new BooleanArray( arr1 ); +// returns + +var len = arr2.length; +// returns 4 +``` + +#### BooleanArray( typedarray ) + +Creates a boolean array from a [typed array][@stdlib/array/typed]. + +```javascript +var Uint8Array = require( '@stdlib/array/uint8' ); + +var buf = new Uint8Array( [ 1, 0, 0, 1 ] ); +// returns [ 1, 0, 0, 1 ] + +var arr = new BooleanArray( buf ); +// returns + +var len = arr.length; +// returns 4 +``` + +#### BooleanArray( obj ) + +Creates a boolean array from an array-like object or iterable. + +```javascript +// From an array of booleans: +var arr1 = new BooleanArray( [ true, false, false, true ] ); +// returns + +var len = arr1.length; +// returns 4 + +// From an array containing non-booleans: +var arr2 = new BooleanArray( [ {}, null, '', 4 ] ); + +len = arr2.length; +// returns 4 +``` + +#### BooleanArray( buffer\[, byteOffset\[, length]] ) + +Returns a boolean array view of an [`ArrayBuffer`][@stdlib/array/buffer]. + +```javascript +var ArrayBuffer = require( '@stdlib/array/buffer' ); +var buf = new ArrayBuffer( 240 ); + +var arr1 = new BooleanArray( buf ); +// returns + +var len = arr1.length; +// returns 240 + +var arr2 = new BooleanArray( buf, 8 ); +// returns + +len = arr2.length; +// returns 232 + +var arr3 = new BooleanArray( buf, 8, 20 ); +// returns + +len = arr3.length; +// returns 20 +``` + +* * * + +### Properties + + + +#### BooleanArray.BYTES_PER_ELEMENT + +Static property returning the size (in bytes) of each array element. + +```javascript +var nbytes = BooleanArray.BYTES_PER_ELEMENT; +// returns 1 +``` + + + +#### BooleanArray.name + +Static property returning the constructor name. + +```javascript +var str = BooleanArray.name; +// returns 'BooleanArray' +``` + + + +#### BooleanArray.prototype.buffer + +Pointer to the underlying data buffer. + +```javascript +var arr = new BooleanArray( 2 ); +// returns + +var buf = arr.buffer; +// returns +``` + + + +#### BooleanArray.prototype.byteLength + +Size (in bytes) of the array. + +```javascript +var arr = new BooleanArray( 10 ); +// returns + +var nbytes = arr.byteLength; +// returns 10 +``` + + + +#### BooleanArray.prototype.byteOffset + +Offset (in bytes) of the array from the start of its underlying `ArrayBuffer`. + +```javascript +var ArrayBuffer = require( '@stdlib/array/buffer' ); + +var arr = new BooleanArray( 10 ); +// returns + +var offset = arr.byteOffset; +// returns 0 + +var buf = new ArrayBuffer( 240 ); +arr = new BooleanArray( buf, 64 ); +// returns + +offset = arr.byteOffset; +// returns 64 +``` + + + +#### BooleanArray.prototype.BYTES_PER_ELEMENT + +Size (in bytes) of each array element. + +```javascript +var arr = new BooleanArray( 10 ); +// returns + +var nbytes = arr.BYTES_PER_ELEMENT; +// returns 1 +``` + + + +#### BooleanArray.prototype.length + +Number of array elements. + +```javascript +var arr = new BooleanArray( 10 ); +// returns + +var len = arr.length; +// returns 10 +``` + +* * * + +### Methods + + + +#### BooleanArray.from( src\[, clbk\[, thisArg]] ) + +Creates a new boolean array from an array-like object or an iterable. + +```javascript +var arr = BooleanArray.from( [ true, false ] ); +// returns + +var len = arr.length; +// returns 2 +``` + +To invoke a function for each `src` value, provide a callback function. + +```javascript +function map( v ) { + return !v; +} + +// Create a source array: +var src = [ true, false ]; + +// Create a new boolean array by inverting the source array: +var arr = BooleanArray.from( src, map ); +// returns + +var len = arr.length; +// returns 2 + +var v = arr.get( 0 ); +// returns false + +v = arr.get( 1 ); +// returns true +``` + +A callback function is provided two arguments: + +- **value**: source value. +- **index**: source index. + +To set the callback execution context, provide a `thisArg`. + +```javascript +function map( v ) { + this.count += 1; + return !v; +} + +// Create a source array: +var src = [ true, false ]; + +// Define an execution context: +var ctx = { + 'count': 0 +}; + +// Create a new boolean array by inverting the source array: +var arr = BooleanArray.from( src, map, ctx ); +// returns + +var len = arr.length; +// returns 2 + +var n = ctx.count; +// returns 2 +``` + + + +#### BooleanArray.of( element0\[, element1\[, ...elementN]] ) + +Creates a new boolean array from a variable number of arguments. + +```javascript +var arr = BooleanArray.of( true, false, false, true ); +// returns + +var len = arr.length; +// returns 4 +``` + + + +#### BooleanArray.prototype.get( i ) + +Returns an array element located at a nonnegative integer position (index) `i`. + +```javascript +var arr = new BooleanArray( 10 ); + +// Set the first element: +arr.set( true, 0 ); + +// Get the first element: +var v = arr.get( 0 ); +// returns true +``` + +If provided an out-of-bounds index, the method returns `undefined`. + +```javascript +var arr = new BooleanArray( 10 ); + +var v = arr.get( 100 ); +// returns undefined +``` + + + +#### BooleanArray.prototype.set( v\[, i] ) + +Sets one or more array elements. + +```javascript +var arr = new BooleanArray( 10 ); + +// Get the first element: +var v = arr.get( 0 ); +// returns false + +// Set the first element: +arr.set( true ); + +// Get the first element: +v = arr.get( 0 ); +// returns true +``` + +By default, the method sets array elements starting at position (index) `i = 0`. To set elements starting elsewhere in the array, provide an index argument `i`. + +```javascript +var arr = new BooleanArray( 10 ); + +// Get the fifth element: +var v = arr.get( 4 ); +// returns false + +// Set the fifth element: +arr.set( true, 4 ); + +// Get the fifth element: +v = arr.get( 4 ); +// returns true +``` + +In addition to providing a single value, to set one or more array elements, provide an array-like object containing truthy and falsy values + +```javascript +var arr = new BooleanArray( 10 ); + +// Define an array of values: +var buf = [ '', 1, null ]; + +// Set the fifth, sixth, and seventh elements: +arr.set( buf, 4 ); + +// Get the sixth element: +var v = arr.get( 5 ); +// returns true +``` + +A few notes: + +- If `i` is out-of-bounds, the method throws an error. +- If a target array cannot accommodate all values (i.e., the length of source array plus `i` exceeds the target array length), the method throws an error. +- If provided a [typed array][@stdlib/array/typed] which shares an [`ArrayBuffer`][@stdlib/array/buffer] with the target array, the method will intelligently copy the source range to the destination range. + +
+ + + + + +
+ +* * * + +## Notes + +- While a `BooleanArray` _strives_ to maintain (but does not **guarantee**) consistency with [typed arrays][@stdlib/array/typed], significant deviations from ECMAScript-defined [typed array][@stdlib/array/typed] behavior are as follows: + + - The constructor does **not** require the `new` operator. + - Accessing array elements using bracket syntax (e.g., `X[i]`) is **not** supported. Instead, one **must** use the `.get()` method. + +
+ + + + + +
+ +* * * + +## Examples + + + +```javascript +var Uint8Array = require( '@stdlib/array/uint8' ); +var logEach = require( '@stdlib/console/log-each' ); +var BooleanArray = require( '@stdlib/array/bool' ); + +// Create a boolean array by specifying a length: +var out = new BooleanArray( 3 ); +logEach( '%s', out ); + +// Create a boolean array from an array of booleans: +var arr = [ true, false, true ]; +out = new BooleanArray( arr ); +logEach( '%s', out ); + +// Create a boolean array from an array buffer: +arr = new Uint8Array( [ 1, 0, 1, 1, 0, 1 ] ); +out = new BooleanArray( arr.buffer ); +logEach( '%s', out ); + +// Create a boolean array from an array buffer view: +arr = new Uint8Array( [ 1, 0, 1, 1, 0, 1 ] ); +out = new BooleanArray( arr.buffer, 1, 2 ); +logEach( '%s', out ); + +console.log( '%s', false ); +``` + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + diff --git a/bool/benchmark/benchmark.from.js b/bool/benchmark/benchmark.from.js new file mode 100644 index 00000000..46739e5d --- /dev/null +++ b/bool/benchmark/benchmark.from.js @@ -0,0 +1,310 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var Uint8Array = require( './../../uint8' ); +var ITERATOR_SYMBOL = require( '@stdlib/symbol/iterator' ); +var pkg = require( './../package.json' ).name; +var BooleanArray = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'skip': ( ITERATOR_SYMBOL === null ) +}; + + +// MAIN // + +bench( pkg+'::typed_array:from', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new Uint8Array( 0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.from( buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::typed_array:from:len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new Uint8Array( 5 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.from( buf ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::typed_array,clbk:from:len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new Uint8Array( 5 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.from( buf, clbk ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function clbk( v ) { + return !v; + } +}); + +bench( pkg+'::array:from', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = []; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.from( buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::array:from:len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = [ true, true, true, true, true ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.from( buf ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::array,clbk:from:len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = [ true, true, true, true, true ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.from( buf, clbk ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function clbk( v ) { + return !v; + } +}); + +bench( pkg+'::iterable:from', opts, function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.from( createIterable() ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function createIterable() { + var out = {}; + out[ ITERATOR_SYMBOL ] = iterator; + return out; + + function iterator() { + return { + 'next': next + }; + } + + function next() { + return { + 'done': true + }; + } + } +}); + +bench( pkg+'::iterable:from:len=5', opts, function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.from( createIterable() ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function createIterable() { + var out = {}; + out[ ITERATOR_SYMBOL ] = iterator; + return out; + + function iterator() { + var it = { + 'next': next, + 'i': 0, + 'N': 5 + }; + return it; + + function next() { + it.i += 1; + if ( it.i <= it.N ) { + return { + 'value': true + }; + } + return { + 'done': true + }; + } + } + } +}); + +bench( pkg+'::iterable,clbk:from:len=5', opts, function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.from( createIterable(), clbk ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function createIterable() { + var out = {}; + out[ ITERATOR_SYMBOL ] = iterator; + return out; + + function iterator() { + var it = { + 'next': next, + 'i': 0, + 'N': 5 + }; + return it; + + function next() { + it.i += 1; + if ( it.i <= it.N ) { + return { + 'value': true + }; + } + return { + 'done': true + }; + } + } + } + + function clbk( v ) { + return !v; + } +}); diff --git a/bool/benchmark/benchmark.get.js b/bool/benchmark/benchmark.get.js new file mode 100644 index 00000000..597b1a30 --- /dev/null +++ b/bool/benchmark/benchmark.get.js @@ -0,0 +1,57 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ); +var pkg = require( './../package.json' ).name; +var BooleanArray = require( './../lib' ); + + +// MAIN // + +bench( pkg+':get', function benchmark( b ) { + var arr; + var N; + var v; + var i; + + arr = []; + for ( i = 0; i < 10; i++ ) { + arr.push( i%2 ); + } + arr = new BooleanArray( arr ); + N = arr.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr.get( i%N ); + if ( typeof v !== 'boolean' ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( !isBoolean( v ) ) { + b.fail( 'should return a boolean' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/bool/benchmark/benchmark.js b/bool/benchmark/benchmark.js new file mode 100644 index 00000000..09470637 --- /dev/null +++ b/bool/benchmark/benchmark.js @@ -0,0 +1,337 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var ArrayBuffer = require( './../../buffer' ); +var Uint8Array = require( './../../uint8' ); +var isArrayBuffer = require( '@stdlib/assert/is-arraybuffer' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var ITERATOR_SYMBOL = require( '@stdlib/symbol/iterator' ); +var pkg = require( './../package.json' ).name; +var BooleanArray = require( './../lib' ); + + +// VARIABLES // + +var opts = { + 'skip': ( ITERATOR_SYMBOL === null ) +}; + + +// MAIN // + +bench( pkg+'::instantiation,new', function benchmark( b ) { + var arr; + var i; + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new BooleanArray(); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,no_new', function benchmark( b ) { + var ctor; + var arr; + var i; + + ctor = BooleanArray; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = ctor(); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,length', function benchmark( b ) { + var arr; + var i; + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new BooleanArray( 0 ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,typed_array', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new Uint8Array( 0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new BooleanArray( buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,array', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = []; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new BooleanArray( buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,iterable', opts, function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new BooleanArray( createIterable() ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function createIterable() { + var out = {}; + out[ ITERATOR_SYMBOL ] = iterator; + return out; + + function iterator() { + return { + 'next': next + }; + } + + function next() { + return { + 'done': true + }; + } + } +}); + +bench( pkg+'::instantiation,arraybuffer', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new ArrayBuffer( 0 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new BooleanArray( buf ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,arraybuffer,byte_offset', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new ArrayBuffer( 8 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new BooleanArray( buf, 8 ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::instantiation,arraybuffer,byte_offset,length', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = new ArrayBuffer( 8 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new BooleanArray( buf, 8, 0 ); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:buffer', function benchmark( b ) { + var arr; + var v; + var i; + + arr = new BooleanArray(); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + // Note: the following may be optimized away due to loop invariant code motion and/or other compiler optimizations, rendering this benchmark meaningless... + v = arr.buffer; + if ( typeof v !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( !isArrayBuffer( v ) ) { + b.fail( 'should return an ArrayBuffer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:byteLength', function benchmark( b ) { + var arr; + var v; + var i; + + arr = new BooleanArray(); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + // Note: the following may be optimized away due to loop invariant code motion and/or other compiler optimizations, rendering this benchmark meaningless... + v = arr.byteLength; + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( v ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:byteOffset', function benchmark( b ) { + var arr; + var v; + var i; + + arr = new BooleanArray(); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + // Note: the following may be optimized away due to loop invariant code motion and/or other compiler optimizations, rendering this benchmark meaningless... + v = arr.byteOffset; + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( v ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::get:length', function benchmark( b ) { + var arr; + var v; + var i; + + arr = new BooleanArray(); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + // Note: the following may be optimized away due to loop invariant code motion and/or other compiler optimizations, rendering this benchmark meaningless... + v = arr.length; + if ( v !== v ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !isNonNegativeInteger( v ) ) { + b.fail( 'should return a nonnegative integer' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/bool/benchmark/benchmark.length.js b/bool/benchmark/benchmark.length.js new file mode 100644 index 00000000..2f1bc80e --- /dev/null +++ b/bool/benchmark/benchmark.length.js @@ -0,0 +1,92 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var pkg = require( './../package.json' ).name; +var BooleanArray = require( './../lib' ); + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - array length +* @returns {Function} benchmark function +*/ +function createBenchmark( len ) { + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = new BooleanArray( len ); + if ( arr.length !== len ) { + b.fail( 'unexpected length' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var f; + var i; + + min = 1; // 10^min + max = 6; // 10^max + + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + f = createBenchmark( len ); + bench( pkg+':len='+len, f ); + } +} + +main(); diff --git a/bool/benchmark/benchmark.of.js b/bool/benchmark/benchmark.of.js new file mode 100644 index 00000000..87fd2c3e --- /dev/null +++ b/bool/benchmark/benchmark.of.js @@ -0,0 +1,69 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var pkg = require( './../package.json' ).name; +var BooleanArray = require( './../lib' ); + + +// MAIN // + +bench( pkg+':of', function benchmark( b ) { + var arr; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.of(); + if ( arr.length !== 0 ) { + b.fail( 'should have length 0' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':len=5', function benchmark( b ) { + var buf; + var arr; + var i; + + buf = [ true, true, true, true, true ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + arr = BooleanArray.of.apply( BooleanArray, buf ); + if ( arr.length !== 5 ) { + b.fail( 'should have length 5' ); + } + } + b.toc(); + if ( !(arr instanceof BooleanArray) ) { + b.fail( 'should return an instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/bool/benchmark/benchmark.set.js b/bool/benchmark/benchmark.set.js new file mode 100644 index 00000000..7c14e3a2 --- /dev/null +++ b/bool/benchmark/benchmark.set.js @@ -0,0 +1,119 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var Uint8Array = require( './../../uint8' ); +var pkg = require( './../package.json' ).name; +var BooleanArray = require( './../lib' ); + + +// MAIN // + +bench( pkg+'::boolean:set', function benchmark( b ) { + var values; + var arr; + var N; + var v; + var i; + + values = []; + for ( i = 0; i < 10; i++ ) { + values.push( i%2 ); + } + arr = new BooleanArray( values ); + N = arr.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr.set( values[ (i+1)%N ] ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::array:set', function benchmark( b ) { + var values; + var arr; + var N; + var v; + var i; + + values = []; + for ( i = 0; i < 10; i++ ) { + values.push( i%2 ); + } + arr = new BooleanArray( values ); + N = arr.length; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr.set( [ values[ (i+1)%N ] ] ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+'::typed_array:set', function benchmark( b ) { + var values; + var arr; + var buf; + var N; + var v; + var i; + + values = new Uint8Array( 20 ); + N = values.length; + for ( i = 0; i < N; i++ ) { + values[ i ] = i % 2; + } + arr = new BooleanArray( values ); + buf = new Uint8Array( 1 ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + buf[ 0 ] = values[ i%N ]; + v = arr.set( buf ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/bool/benchmark/benchmark.set.length.js b/bool/benchmark/benchmark.set.length.js new file mode 100644 index 00000000..4f481380 --- /dev/null +++ b/bool/benchmark/benchmark.set.length.js @@ -0,0 +1,116 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var pow = require( '@stdlib/math/base/special/pow' ); +var randu = require( '@stdlib/random/base/randu' ); +var pkg = require( './../package.json' ).name; +var BooleanArray = require( './../lib' ); + + +// FUNCTIONS // + +/** +* Creates a benchmark function. +* +* @private +* @param {PositiveInteger} len - array length +* @returns {Function} benchmark function +*/ +function createBenchmark( len ) { + var values; + var arr1; + var arr2; + var arr3; + var N; + var i; + + arr1 = []; + arr2 = []; + arr3 = []; + for ( i = 0; i < len; i++ ) { + arr1.push( i > (len/2) ); + arr2.push( randu() > 0.5 ); + arr3.push( randu() < 0.2 ); + } + arr1 = new BooleanArray( arr1 ); + + values = [ + new BooleanArray( arr2 ), + new BooleanArray( arr3 ) + ]; + N = values.length; + + return benchmark; + + /** + * Benchmark function. + * + * @private + * @param {Benchmark} b - benchmark instance + */ + function benchmark( b ) { + var v; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = arr1.set( values[ i%N ] ); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + } + b.toc(); + if ( typeof v !== 'undefined' ) { + b.fail( 'should return undefined' ); + } + b.pass( 'benchmark finished' ); + b.end(); + } +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var len; + var min; + var max; + var f; + var i; + + min = 1; // 10^min + max = 4; // 10^max + + for ( i = min; i <= max; i++ ) { + len = pow( 10, i ); + f = createBenchmark( len ); + bench( pkg+':set:len='+len, f ); + } +} + +main(); diff --git a/bool/examples/index.js b/bool/examples/index.js new file mode 100644 index 00000000..76abe9eb --- /dev/null +++ b/bool/examples/index.js @@ -0,0 +1,44 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var Uint8Array = require( './../../uint8' ); +var logEach = require( '@stdlib/console/log-each' ); +var BooleanArray = require( './../lib' ); + +// Create a boolean array by specifying a length: +var out = new BooleanArray( 3 ); +logEach( '%s', out ); + +// Create a boolean array from an array of booleans: +var arr = [ true, false, true ]; +out = new BooleanArray( arr ); +logEach( '%s', out ); + +// Create a boolean array from an array buffer: +arr = new Uint8Array( [ 1, 0, 1, 1, 0, 1 ] ); +out = new BooleanArray( arr.buffer ); +logEach( '%s', out ); + +// Create a boolean array from an array buffer view: +arr = new Uint8Array( [ 1, 0, 1, 1, 0, 1 ] ); +out = new BooleanArray( arr.buffer, 1, 2 ); +logEach( '%s', out ); + +console.log( '%s', false ); diff --git a/bool/lib/from_array.js b/bool/lib/from_array.js new file mode 100644 index 00000000..1a884020 --- /dev/null +++ b/bool/lib/from_array.js @@ -0,0 +1,50 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var Boolean = require( '@stdlib/boolean/ctor' ); + + +// MAIN // + +/** +* Fills an output array with "boolean" values. +* +* @private +* @param {Uint8Array} buf - output array +* @param {Array} arr - input array +* @returns {Uint8Array} output array +*/ +function fromArray( buf, arr ) { + var len; + var i; + + len = arr.length; + for ( i = 0; i < len; i++ ) { + buf[ i ] = Boolean( arr[ i ] ); + } + return buf; +} + + +// EXPORTS // + +module.exports = fromArray; diff --git a/bool/lib/from_iterator.js b/bool/lib/from_iterator.js new file mode 100644 index 00000000..4062b95c --- /dev/null +++ b/bool/lib/from_iterator.js @@ -0,0 +1,53 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var Boolean = require( '@stdlib/boolean/ctor' ); + + +// MAIN // + +/** +* Returns an array of iterated values. +* +* @private +* @param {Object} it - iterator +* @returns {Array} output array +*/ +function fromIterator( it ) { + var out; + var v; + + out = []; + while ( true ) { + v = it.next(); + if ( v.done ) { + break; + } + out.push( Boolean( v.value ) ); + } + return out; +} + + +// EXPORTS // + +module.exports = fromIterator; diff --git a/bool/lib/from_iterator_map.js b/bool/lib/from_iterator_map.js new file mode 100644 index 00000000..2bce56cb --- /dev/null +++ b/bool/lib/from_iterator_map.js @@ -0,0 +1,58 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var Boolean = require( '@stdlib/boolean/ctor' ); + + +// MAIN // + +/** +* Returns an array of iterated values. +* +* @private +* @param {Object} it - iterator +* @param {Function} clbk - callback to invoke for each iterated value +* @param {*} thisArg - invocation context +* @returns {Array} output array +*/ +function fromIteratorMap( it, clbk, thisArg ) { + var out; + var v; + var i; + + out = []; + i = -1; + while ( true ) { + v = it.next(); + if ( v.done ) { + break; + } + i += 1; + out.push( Boolean( clbk.call( thisArg, v.value, i ) ) ); + } + return out; +} + + +// EXPORTS // + +module.exports = fromIteratorMap; diff --git a/bool/lib/index.js b/bool/lib/index.js new file mode 100644 index 00000000..b44e4f2f --- /dev/null +++ b/bool/lib/index.js @@ -0,0 +1,94 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Boolean array. +* +* @module @stdlib/array/bool +* +* @example +* var BooleanArray = require( '@stdlib/array/bool' ); +* +* var arr = new BooleanArray(); +* // returns +* +* var len = arr.length; +* // returns 0 +* +* @example +* var BooleanArray = require( '@stdlib/array/bool' ); +* +* var arr = new BooleanArray( 2 ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* var BooleanArray = require( '@stdlib/array/bool' ); +* +* var arr = new BooleanArray( [ true, false ] ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* var BooleanArray = require( '@stdlib/array/bool' ); +* +* var buf = new ArrayBuffer( 16 ); +* var arr = new BooleanArray( buf ); +* // returns +* +* var len = arr.length; +* // returns 16 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* var BooleanArray = require( '@stdlib/array/bool' ); +* +* var buf = new ArrayBuffer( 16 ); +* var arr = new BooleanArray( buf, 8 ); +* // returns +* +* var len = arr.length; +* // returns 8 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* var BooleanArray = require( '@stdlib/array/bool' ); +* +* var buf = new ArrayBuffer( 32 ); +* var arr = new BooleanArray( buf, 8, 2 ); +* // returns +* +* var len = arr.length; +* // returns 2 +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/bool/lib/main.js b/bool/lib/main.js new file mode 100644 index 00000000..10972642 --- /dev/null +++ b/bool/lib/main.js @@ -0,0 +1,612 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-restricted-syntax, no-invalid-this */ + +'use strict'; + +// MODULES // + +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var isCollection = require( '@stdlib/assert/is-collection' ); +var isArrayBuffer = require( '@stdlib/assert/is-arraybuffer' ); +var isObject = require( '@stdlib/assert/is-object' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var hasIteratorSymbolSupport = require( '@stdlib/assert/has-iterator-symbol-support' ); +var ITERATOR_SYMBOL = require( '@stdlib/symbol/iterator' ); +var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); +var setReadOnlyAccessor = require( '@stdlib/utils/define-nonenumerable-read-only-accessor' ); +var Uint8Array = require( './../../uint8' ); +var Boolean = require( '@stdlib/boolean/ctor' ); +var getter = require( './../../base/getter' ); +var accessorGetter = require( './../../base/accessor-getter' ); +var format = require( '@stdlib/string/format' ); +var fromIterator = require( './from_iterator.js' ); +var fromIteratorMap = require( './from_iterator_map.js' ); +var fromArray = require( './from_array.js' ); + + +// VARIABLES // + +var BYTES_PER_ELEMENT = Uint8Array.BYTES_PER_ELEMENT; +var HAS_ITERATOR_SYMBOL = hasIteratorSymbolSupport(); + + +// FUNCTIONS // + +/** +* Returns a boolean indicating if a value is a `BooleanArray`. +* +* @private +* @param {*} value - value to test +* @returns {boolean} boolean indicating if a value is a `BooleanArray` +*/ +function isBooleanArray( value ) { + return ( + typeof value === 'object' && + value !== null && + value.constructor.name === 'BooleanArray' && + value.BYTES_PER_ELEMENT === BYTES_PER_ELEMENT + ); +} + +/** +* Returns a boolean indicating if a value is a boolean typed array constructor. +* +* @private +* @param {*} value - value to test +* @returns {boolean} boolean indicating if a value is a boolean typed array constructor +*/ +function isBooleanArrayConstructor( value ) { + return ( value === BooleanArray); +} + + +// MAIN // + +/** +* Boolean array constructor. +* +* @constructor +* @param {(NonNegativeInteger|Collection|ArrayBuffer|Iterable)} [arg] - length, typed array, array-like object, buffer, or an iterable +* @param {NonNegativeInteger} [byteOffset=0] - byte offset +* @param {NonNegativeInteger} [length] - view length +* @throws {TypeError} if provided only a single argument, must provide a valid argument +* @throws {TypeError} byte offset must be a nonnegative integer +* @throws {RangeError} must provide sufficient memory to accommodate byte offset and view length requirements +* @returns {BooleanArray} boolean array +* +* @example +* var arr = new BooleanArray(); +* // returns +* +* var len = arr.length; +* // returns 0 +* +* @example +* var arr = new BooleanArray( 2 ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* var arr = new BooleanArray( [ true, false ] ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* +* var buf = new ArrayBuffer( 16 ); +* var arr = new BooleanArray( buf ); +* // returns +* +* var len = arr.length; +* // returns 16 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* +* var buf = new ArrayBuffer( 16 ); +* var arr = new BooleanArray( buf, 8 ); +* // returns +* +* var len = arr.length; +* // returns 8 +* +* @example +* var ArrayBuffer = require( '@stdlib/array/buffer' ); +* +* var buf = new ArrayBuffer( 32 ); +* var arr = new BooleanArray( buf, 8, 2 ); +* // returns +* +* var len = arr.length; +* // returns 2 +*/ +function BooleanArray() { + var byteOffset; + var nargs; + var buf; + var len; + var arg; + + nargs = arguments.length; + if ( !(this instanceof BooleanArray) ) { + if ( nargs === 0 ) { + return new BooleanArray(); + } + if ( nargs === 1 ) { + return new BooleanArray( arguments[0] ); + } + if ( nargs === 2 ) { + return new BooleanArray( arguments[0], arguments[1] ); + } + return new BooleanArray( arguments[0], arguments[1], arguments[2] ); + } + // Create the underlying data buffer... + if ( nargs === 0 ) { + buf = new Uint8Array( 0 ); // backward-compatibility + } else if ( nargs === 1 ) { + arg = arguments[ 0 ]; + if ( isNonNegativeInteger( arg ) ) { + buf = new Uint8Array( arg ); + } else if ( isCollection( arg ) ) { + buf = fromArray( new Uint8Array( arg.length ), arg ); + } else if ( isArrayBuffer( arg ) ) { + buf = new Uint8Array( arg ); + } else if ( isObject( arg ) ) { + 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`.', arg ) ); + } + if ( !isFunction( arg[ ITERATOR_SYMBOL ] ) ) { + throw new TypeError( format( 'invalid argument. Must provide a length, ArrayBuffer, typed array, array-like object, or an iterable. Value: `%s`.', arg ) ); + } + buf = arg[ 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`.', arg ) ); + } + buf = new Uint8Array( fromIterator( buf ) ); + } else { + throw new TypeError( format( 'invalid argument. Must provide a length, ArrayBuffer, typed array, array-like object, or an iterable. Value: `%s`.', arg ) ); + } + } 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 ( nargs === 2 ) { + buf = new Uint8Array( 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 Uint8Array( buf, byteOffset, len ); + } + } + setReadOnly( this, '_buffer', buf ); + setReadOnly( this, '_length', buf.length ); + + return this; +} + +/** +* Size (in bytes) of each array element. +* +* @name BYTES_PER_ELEMENT +* @memberof BooleanArray +* @readonly +* @type {PositiveInteger} +* @default 1 +* +* @example +* var nbytes = BooleanArray.BYTES_PER_ELEMENT; +* // returns 1 +*/ +setReadOnly( BooleanArray, 'BYTES_PER_ELEMENT', BYTES_PER_ELEMENT ); + +/** +* Constructor name. +* +* @name name +* @memberof BooleanArray +* @readonly +* @type {string} +* @default 'BooleanArray' +* +* @example +* var str = BooleanArray.name; +* // returns 'BooleanArray' +*/ +setReadOnly( BooleanArray, 'name', 'BooleanArray' ); + +/** +* Creates a new boolean array from an array-like object or an iterable. +* +* @name from +* @memberof BooleanArray +* @type {Function} +* @param {(Collection|Iterable)} src - array-like object or iterable +* @param {Function} [clbk] - callback to invoke for each source element +* @param {*} [thisArg] - context +* @throws {TypeError} `this` context must be a constructor +* @throws {TypeError} `this` must be a boolean array +* @throws {TypeError} first argument must be an array-like object or an iterable +* @throws {TypeError} second argument must be a function +* @returns {BooleanArray} boolean array +* +* @example +* var arr = BooleanArray.from( [ true, false ] ); +* // returns +* +* var len = arr.length; +* // returns 2 +* +* @example +* function clbk( v ) { +* return !v; +* } +* +* var arr = BooleanArray.from( [ true, false ], clbk ); +* // returns +* +* var len = arr.length; +* // returns 2 +*/ +setReadOnly( BooleanArray, 'from', function from( src ) { + var thisArg; + var nargs; + var clbk; + var out; + var buf; + var tmp; + var get; + var len; + var i; + if ( !isFunction( this ) ) { + throw new TypeError( 'invalid invocation. `this` context must be a constructor.' ); + } + if ( !isBooleanArrayConstructor( this ) ) { + throw new TypeError( 'invalid invocation. `this` is not a boolean array.' ); + } + nargs = arguments.length; + if ( nargs > 1 ) { + clbk = arguments[ 1 ]; + if ( !isFunction( clbk ) ) { + throw new TypeError( format( 'invalid argument. Second argument must be a function. Value: `%s`.', clbk ) ); + } + if ( nargs > 2 ) { + thisArg = arguments[ 2 ]; + } + } + if ( isCollection( src ) ) { + if ( clbk ) { + len = src.length; + if ( src.get && src.set ) { + get = accessorGetter( 'default' ); + } else { + get = getter( 'default' ); + } + out = new this( len ); + buf = out._buffer; // eslint-disable-line no-underscore-dangle + for ( i = 0; i < len; i++ ) { + buf[ i ] = Boolean( clbk.call( thisArg, get( src, i ), i ) ); + } + return out; + } + return new this( src ); + } + if ( isObject( src ) && HAS_ITERATOR_SYMBOL && isFunction( src[ ITERATOR_SYMBOL ] ) ) { // eslint-disable-line max-len + buf = src[ ITERATOR_SYMBOL ](); + if ( !isFunction( buf.next ) ) { + throw new TypeError( format( 'invalid argument. First argument must be an array-like object or an iterable. Value: `%s`.', src ) ); + } + if ( clbk ) { + tmp = fromIteratorMap( buf, clbk, thisArg ); + } else { + tmp = fromIterator( buf ); + } + len = tmp.length; + out = new this( len ); + buf = out._buffer; // eslint-disable-line no-underscore-dangle + for ( i = 0; i < len; i++ ) { + buf[ i ] = tmp[ i ]; + } + return out; + } + throw new TypeError( format( 'invalid argument. First argument must be an array-like object or an iterable. Value: `%s`.', src ) ); +}); + +/** +* Creates a new boolean array from a variable number of arguments. +* +* @name of +* @memberof BooleanArray +* @type {Function} +* @param {...*} element - array elements +* @throws {TypeError} `this` context must be a constructor +* @throws {TypeError} `this` must be a boolean array +* @returns {BooleanArray} boolean array +* +* @example +* var arr = BooleanArray.of( true, true, true, true ); +* // returns +* +* var len = arr.length; +* // returns 4 +*/ +setReadOnly( BooleanArray, 'of', function of() { + var args; + var i; + if ( !isFunction( this ) ) { + throw new TypeError( 'invalid invocation. `this` context must be a constructor.' ); + } + if ( !isBooleanArrayConstructor( this ) ) { + throw new TypeError( 'invalid invocation. `this` is not a boolean array.' ); + } + args = []; + for ( i = 0; i < arguments.length; i++ ) { + args.push( arguments[ i ] ); + } + return new this( args ); +}); + +/** +* Pointer to the underlying data buffer. +* +* @name buffer +* @memberof BooleanArray.prototype +* @readonly +* @type {ArrayBuffer} +* +* @example +* var arr = new BooleanArray( 10 ); +* +* var buf = arr.buffer; +* // returns +*/ +setReadOnlyAccessor( BooleanArray.prototype, 'buffer', function get() { + return this._buffer.buffer; +}); + +/** +* Size (in bytes) of the array. +* +* @name byteLength +* @memberof BooleanArray.prototype +* @readonly +* @type {NonNegativeInteger} +* +* @example +* var arr = new BooleanArray( 10 ); +* +* var byteLength = arr.byteLength; +* // returns 10 +*/ +setReadOnlyAccessor( BooleanArray.prototype, 'byteLength', function get() { + return this._buffer.byteLength; +}); + +/** +* Offset (in bytes) of the array from the start of its underlying `ArrayBuffer`. +* +* @name byteOffset +* @memberof BooleanArray.prototype +* @readonly +* @type {NonNegativeInteger} +* +* @example +* var arr = new BooleanArray( 10 ); +* +* var byteOffset = arr.byteOffset; +* // returns 0 +*/ +setReadOnlyAccessor( BooleanArray.prototype, 'byteOffset', function get() { + return this._buffer.byteOffset; +}); + +/** +* Size (in bytes) of each array element. +* +* @name BYTES_PER_ELEMENT +* @memberof BooleanArray.prototype +* @readonly +* @type {PositiveInteger} +* @default 1 +* +* @example +* var arr = new BooleanArray( 10 ); +* +* var nbytes = arr.BYTES_PER_ELEMENT; +* // returns 1 +*/ +setReadOnly( BooleanArray.prototype, 'BYTES_PER_ELEMENT', BooleanArray.BYTES_PER_ELEMENT ); + +/** +* Returns an array element. +* +* @name get +* @memberof BooleanArray.prototype +* @type {Function} +* @param {NonNegativeInteger} idx - element index +* @throws {TypeError} `this` must be a boolean array +* @throws {TypeError} must provide a nonnegative integer +* @returns {(boolean|void)} array element +* +* @example +* var arr = new BooleanArray( 10 ); +* +* var v = arr.get( 0 ); +* // returns false +* +* arr.set( [ true, false ], 0 ); +* +* v = arr.get( 0 ); +* // returns true +* +* v = arr.get( 100 ); +* // returns undefined +*/ +setReadOnly( BooleanArray.prototype, 'get', function get( idx ) { + if ( !isBooleanArray( this ) ) { + throw new TypeError( 'invalid invocation. `this` is not a boolean array.' ); + } + if ( !isNonNegativeInteger( idx ) ) { + throw new TypeError( format( 'invalid argument. Must provide a nonnegative integer. Value: `%s`.', idx ) ); + } + if ( idx >= this._length ) { + return; + } + return Boolean( this._buffer[ idx ] ); +}); + +/** +* Number of array elements. +* +* @name length +* @memberof BooleanArray.prototype +* @readonly +* @type {NonNegativeInteger} +* +* @example +* var arr = new BooleanArray( 10 ); +* +* var len = arr.length; +* // returns 10 +*/ +setReadOnlyAccessor( BooleanArray.prototype, 'length', function get() { + return this._length; +}); + +/** +* Sets an array element. +* +* ## Notes +* +* - When provided a typed array, we must check whether the source array shares the same buffer as the target array and whether the underlying memory overlaps. In particular, we are concerned with the following scenario: +* +* ```text +* buf: --------------------- +* src: --------------------- +* ``` +* +* In the above, as we copy values from `src`, we will overwrite values in the `src` view, resulting in duplicated values copied into the end of `buf`, which is not intended. Hence, to avoid overwriting source values, we must **copy** source values to a temporary array. +* +* In the other overlapping scenario, +* +* ```text +* buf: --------------------- +* src: --------------------- +* ``` +* +* by the time we begin copying into the overlapping region, we are copying from the end of `src`, a non-overlapping region, which means we don't run the risk of copying copied values, rather than the original `src` values, as intended. +* +* @name set +* @memberof BooleanArray.prototype +* @type {Function} +* @param {(Collection|BooleanArray|*)} value - value(s) +* @param {NonNegativeInteger} [i=0] - element index at which to start writing values +* @throws {TypeError} `this` must be a boolean array +* @throws {TypeError} index argument must be a nonnegative integer +* @throws {RangeError} index argument is out-of-bounds +* @throws {RangeError} target array lacks sufficient storage to accommodate source values +* @returns {void} +* +* @example +* var arr = new BooleanArray( 10 ); +* +* var v = arr.get( 0 ); +* // returns false +* +* arr.set( [ true, false ], 0 ); +* +* v = arr.get( 0 ); +* // returns true +*/ +setReadOnly( BooleanArray.prototype, 'set', function set( value ) { + var sbuf; + var idx; + var buf; + var tmp; + var N; + var i; + var j; + if ( !isBooleanArray( this ) ) { + throw new TypeError( 'invalid invocation. `this` is not a boolean array.' ); + } + buf = this._buffer; + if ( arguments.length > 1 ) { + idx = arguments[ 1 ]; + if ( !isNonNegativeInteger( idx ) ) { + throw new TypeError( format( 'invalid argument. Index argument must be a nonnegative integer. Value: `%s`.', idx ) ); + } + } else { + idx = 0; + } + if ( isCollection( value ) ) { + N = value.length; + if ( idx+N > this._length ) { + throw new RangeError( 'invalid arguments. Target array lacks sufficient storage to accommodate source values.' ); + } + if ( isBooleanArray( value ) ) { + sbuf = value._buffer; // eslint-disable-line no-underscore-dangle + } else { + sbuf = value; + } + // Check for overlapping memory... + j = buf.byteOffset + (idx*BYTES_PER_ELEMENT); + if ( + sbuf.buffer === buf.buffer && + ( + sbuf.byteOffset < j && + sbuf.byteOffset+sbuf.byteLength > j + ) + ) { + // We need to copy source values... + tmp = new Uint8Array( sbuf.length ); + for ( i = 0; i < sbuf.length; i++ ) { + tmp[ i ] = sbuf[ i ]; // TODO: handle accessor arrays + } + sbuf = tmp; + } + for ( i = 0; i < N; idx++, i++ ) { + buf[ idx ] = ( sbuf[ i ] ) ? 1 : 0; + } + return; + } + if ( idx >= this._length ) { + throw new RangeError( format( 'invalid argument. Index argument is out-of-bounds. Value: `%u`.', idx ) ); + } + buf[ idx ] = ( value ) ? 1 : 0; +}); + + +// EXPORTS // + +module.exports = BooleanArray; diff --git a/bool/package.json b/bool/package.json new file mode 100644 index 00000000..094f6642 --- /dev/null +++ b/bool/package.json @@ -0,0 +1,67 @@ +{ + "name": "@stdlib/array/bool", + "version": "0.0.0", + "description": "BooleanArray.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdtypes", + "types", + "data", + "structure", + "array", + "typed", + "typed array", + "typed-array", + "booleanarray", + "boolean", + "bool", + "binary", + "mask" + ] +} diff --git a/bool/test/test.from.js b/bool/test/test.from.js new file mode 100644 index 00000000..8e6f3322 --- /dev/null +++ b/bool/test/test.from.js @@ -0,0 +1,654 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var proxyquire = require( 'proxyquire' ); +var Uint8Array = require( './../../float32' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var BooleanArray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof BooleanArray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'attached to the main export is a `from` method for creating a boolean array from an array-like object or iterable', function test( t ) { + var arr; + + t.strictEqual( hasOwnProp( BooleanArray, 'from' ), true, 'has property' ); + t.strictEqual( isFunction( BooleanArray.from ), true, 'has method' ); + + arr = BooleanArray.from( [] ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the method throws an error if invoked with a `this` context which is not a constructor', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + [] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.from.call( value, [] ); + }; + } +}); + +tape( 'the method throws an error if invoked with a `this` context which is not a boolean array constructor', function test( t ) { + var values; + var i; + + values = [ + {}, + null, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.from.call( value, [] ); + }; + } +}); + +tape( 'the method throws an error if not provided an iterable or array-like object', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.from( value ); + }; + } +}); + +tape( 'the method throws an error if not provided an iterable or array-like object (callback)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.from( value, clbk ); + }; + } + + function clbk() { + return true; + } +}); + +tape( 'the method throws an error if not provided an iterable or array-like object (callback, thisArg)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.from( value, clbk, {} ); + }; + } + + function clbk() { + return true; + } +}); + +tape( 'the method throws an error if provided a second argument which is not a function', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + [] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.from( [], value ); + }; + } +}); + +tape( 'the method throws an error if provided a second argument which is not a function (thisArg)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + [] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.from( [], value, {} ); + }; + } +}); + +tape( 'the method returns a boolean array', function test( t ) { + var arr; + var v; + + // Generic array: + arr = BooleanArray.from( [] ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = BooleanArray.from( [ true, true, true, true ] ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 4, 'returns expected value' ); + + // Generic array containing non-booleans: + arr = BooleanArray.from( [ 'beep' ] ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 1, 'returns expected value' ); + + arr = BooleanArray.from( [ null, 4 ] ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + arr = BooleanArray.from( [ true, {}, '' ] ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 3, 'returns expected value' ); + + // Typed array: + arr = BooleanArray.from( new Uint8Array( 0 ) ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = BooleanArray.from( new Uint8Array( [ 1, 1 ] ) ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + // Boolean typed array: + arr = BooleanArray.from( new BooleanArray( 0 ) ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = BooleanArray.from( new BooleanArray( [ true, false ] ) ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'the method returns a boolean array (iterable)', function test( t ) { + var BooleanArray; + var iter; + var arr; + var v; + + BooleanArray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport, + '@stdlib/symbol/iterator': '__SYMBOL_ITERATOR__' + }); + + iter = { + 'next': next, + 'i': 0, + 'N': 4 + }; + arr = BooleanArray.from( createIterable( iter ) ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, iter.N, 'returns expected value' ); + + t.end(); + + function hasSupport() { + return true; + } + + function createIterable( iterator ) { + var it = {}; + it[ '__SYMBOL_ITERATOR__' ] = iterable; + return it; + + function iterable() { + return iterator; + } + } + + function next() { + iter.i += 1; + if ( iter.i <= iter.N ) { + return { + 'value': true + }; + } + return { + 'done': true + }; + } +}); + +tape( 'the method supports providing a "map" function which is invoked for each source element', function test( t ) { + var arr; + var v; + + // Generic array: + arr = BooleanArray.from( [], clbk1 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = BooleanArray.from( [ true, true, true, true ], clbk1 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 4, 'returns expected value' ); + + // Generic array containing non-booleans: + arr = BooleanArray.from( [ 'beep' ], clbk2 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 1, 'returns expected value' ); + + arr = BooleanArray.from( [ null ], clbk2 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 1, 'returns expected value' ); + + arr = BooleanArray.from( [ [], {} ], clbk1 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + arr = BooleanArray.from( [ 4, 5 ], clbk1 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + // Typed array: + arr = BooleanArray.from( new Uint8Array( 0 ), clbk1 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = BooleanArray.from( new Uint8Array( [ 1, 1 ] ), clbk1 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + // Boolean typed array: + arr = BooleanArray.from( new BooleanArray( 0 ), clbk2 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = BooleanArray.from( new BooleanArray( [ true, true ] ), clbk2 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + t.end(); + + function clbk1( v ) { + return v; + } + + function clbk2() { + return true; + } +}); + +tape( 'the method supports providing a "map" function which is invoked for each iterated value', function test( t ) { + var BooleanArray; + var iter; + var arr; + var v; + + BooleanArray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport, + '@stdlib/symbol/iterator': '__SYMBOL_ITERATOR__' + }); + + iter = { + 'next': next, + 'i': 0, + 'N': 4 + }; + arr = BooleanArray.from( createIterable( iter ), clbk ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, iter.N, 'returns expected value' ); + + t.end(); + + function hasSupport() { + return true; + } + + function createIterable( iterator ) { + var it = {}; + it[ '__SYMBOL_ITERATOR__' ] = iterable; + return it; + + function iterable() { + return iterator; + } + } + + function next() { + iter.i += 1; + if ( iter.i <= iter.N ) { + return { + 'value': true + }; + } + return { + 'done': true + }; + } + + function clbk( v ) { + return !v; + } +}); + +tape( 'the method supports providing a `this` context for a provided map function', function test( t ) { + var arr; + var ctx; + + ctx = { + 'count': 0 + }; + arr = BooleanArray.from( [ true, true, true, true ], clbk1, ctx ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + t.strictEqual( ctx.count, 4, 'returns expected value' ); + + t.end(); + + function clbk1( v ) { + this.count += 1; // eslint-disable-line no-invalid-this + return v; + } +}); + +tape( 'the method supports providing a `this` context for a provided map function (iterable)', function test( t ) { + var BooleanArray; + var iter; + var ctx; + var arr; + + BooleanArray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport, + '@stdlib/symbol/iterator': '__SYMBOL_ITERATOR__' + }); + + iter = { + 'next': next, + 'i': 0, + 'N': 4 + }; + ctx = { + 'count': 0 + }; + + arr = BooleanArray.from( createIterable( iter ), clbk, ctx ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + t.strictEqual( ctx.count, 4, 'returns expected value' ); + + t.end(); + + function hasSupport() { + return true; + } + + function createIterable( iterator ) { + var it = {}; + it[ '__SYMBOL_ITERATOR__' ] = iterable; + return it; + + function iterable() { + return iterator; + } + } + + function next() { + iter.i += 1; + if ( iter.i <= iter.N ) { + return { + 'value': true + }; + } + return { + 'done': true + }; + } + + function clbk( v ) { + this.count += 1; // eslint-disable-line no-invalid-this + return v; + } +}); + +tape( 'the method throws an error if provided a non-iterable object (non-ES2015+)', function test( t ) { + var BooleanArray; + var values; + var i; + + BooleanArray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport + }); + + values = [ + {}, + { + '0': 1, + '1': 2, + '2': 3 + } + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.from( value ); + }; + } + + function hasSupport() { + return false; + } +}); + +tape( 'the method throws an error if provided a non-iterable object (ES2015+)', function test( t ) { + var BooleanArray; + var values; + var i; + + BooleanArray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport, + '@stdlib/symbol/iterator': '__SYMBOL_ITERATOR__' + }); + + values = [ + {}, + { + '0': 1, + '1': 2, + '2': 3 + }, + { + '__SYMBOL_ITERATOR__': null + }, + { + '__SYMBOL_ITERATOR__': 'beep' + }, + { + '__SYMBOL_ITERATOR__': nonIterable1 + }, + { + '__SYMBOL_ITERATOR__': nonIterable2 + } + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.from( value ); + }; + } + + function hasSupport() { + return true; + } + + function nonIterable1() { + return null; + } + + function nonIterable2() { + return {}; + } +}); diff --git a/bool/test/test.get.js b/bool/test/test.get.js new file mode 100644 index 00000000..0352bf54 --- /dev/null +++ b/bool/test/test.get.js @@ -0,0 +1,135 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var Boolean = require( '@stdlib/boolean/ctor' ); +var BooleanArray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof BooleanArray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'attached to the prototype of the main export is a `get` method for returning an array element', function test( t ) { + t.strictEqual( hasOwnProp( BooleanArray.prototype, 'get' ), true, 'has property' ); + t.strictEqual( isFunction( BooleanArray.prototype.get ), true, 'has method' ); + t.end(); +}); + +tape( 'the method throws an error if invoked with a `this` context which is not a boolean array instance', function test( t ) { + var values; + var arr; + var i; + + arr = new BooleanArray( 5 ); + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + [] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return arr.get.call( value, 0 ); + }; + } +}); + +tape( 'the method throws an error if provided an index argument which is not a nonnegative integer', function test( t ) { + var values; + var arr; + var i; + + arr = new BooleanArray( 10 ); + + values = [ + '5', + -5, + 3.14, + NaN, + true, + false, + null, + void 0, + {}, + [], + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return arr.get( value ); + }; + } +}); + +tape( 'the method returns `undefined` if provided an index which exceeds array dimensions', function test( t ) { + var arr; + var v; + var i; + + arr = new BooleanArray( 10 ); + for ( i = 0; i < arr.length; i++ ) { + v = arr.get( arr.length+i ); + t.strictEqual( v, void 0, 'returns expected value for index '+(arr.length+i) ); + } + t.end(); +}); + +tape( 'the method returns an array element', function test( t ) { + var arr; + var v; + var i; + + arr = []; + for ( i = 0; i < 10; i++ ) { + arr.push( i%2 ); + } + arr = new BooleanArray( arr ); + + for ( i = 0; i < arr.length; i++ ) { + v = arr.get( i ); + t.strictEqual( v, Boolean( i%2 ), 'returns expected value for index '+i ); + } + t.end(); +}); diff --git a/bool/test/test.js b/bool/test/test.js new file mode 100644 index 00000000..879a11a3 --- /dev/null +++ b/bool/test/test.js @@ -0,0 +1,660 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var proxyquire = require( 'proxyquire' ); +var ArrayBuffer = require( './../../buffer' ); +var Uint8Array = require( './../../uint8' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isArrayBuffer = require( '@stdlib/assert/is-arraybuffer' ); +var BooleanArray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof BooleanArray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function is a constructor', function test( t ) { + var arr = new BooleanArray( 0 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor does not require the `new` keyword', function test( t ) { + var ctor; + var arr; + + ctor = BooleanArray; + + arr = ctor( 0 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); +}); + +tape( 'the constructor returns a boolean array (no argument)', function test( t ) { + var arr = new BooleanArray(); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor returns a boolean array (no argument, no new)', function test( t ) { + var ctor; + var arr; + + ctor = BooleanArray; + + arr = ctor(); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); +}); + +tape( 'the constructor returns a boolean array (length)', function test( t ) { + var arr = new BooleanArray( 10 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor returns a boolean array (length, no new)', function test( t ) { + var ctor; + var arr; + + ctor = BooleanArray; + + arr = ctor( 10 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); +}); + +tape( 'the constructor returns a boolean array (array)', function test( t ) { + var arr = new BooleanArray( [] ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor returns a boolean array (array, no new)', function test( t ) { + var ctor; + var arr; + + ctor = BooleanArray; + + arr = ctor( [] ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); +}); + +tape( 'the constructor returns a boolean array (typed array)', function test( t ) { + var arr = new BooleanArray( new Uint8Array( 0 ) ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor returns a boolean array (typed array, no new)', function test( t ) { + var ctor; + var arr; + + ctor = BooleanArray; + + arr = ctor( new Uint8Array( 0 ) ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); +}); + +tape( 'the constructor returns a boolean array (iterable)', function test( t ) { + var BooleanArray; + var arr; + + BooleanArray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport, + '@stdlib/symbol/iterator': '__SYMBOL_ITERATOR__' + }); + + arr = new BooleanArray( createIterable() ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); + + function hasSupport() { + return true; + } + + function createIterable() { + var it = {}; + it[ '__SYMBOL_ITERATOR__' ] = iterable; + return it; + + function iterable() { + return { + 'next': next + }; + } + + function next() { + return { + 'done': true + }; + } + } +}); + +tape( 'the constructor returns a boolean array (iterable, no new)', function test( t ) { + var ctor; + var arr; + + ctor = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport, + '@stdlib/symbol/iterator': '__SYMBOL_ITERATOR__' + }); + + arr = ctor( createIterable() ); + t.strictEqual( arr instanceof ctor, true, 'returns an instance' ); + + t.end(); + + function hasSupport() { + return true; + } + + function createIterable() { + var it = {}; + it[ '__SYMBOL_ITERATOR__' ] = iterable; + return it; + + function iterable() { + return { + 'next': next + }; + } + + function next() { + return { + 'done': true + }; + } + } +}); + +tape( 'the constructor returns a boolean array (ArrayBuffer)', function test( t ) { + var arr = new BooleanArray( new ArrayBuffer( 0 ) ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor returns a boolean array (ArrayBuffer, no new)', function test( t ) { + var ctor; + var arr; + + ctor = BooleanArray; + + arr = ctor( new ArrayBuffer( 0 ) ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); +}); + +tape( 'the constructor returns a boolean array (ArrayBuffer, byte offset)', function test( t ) { + var arr = new BooleanArray( new ArrayBuffer( 8 ), 8 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor returns a boolean array (ArrayBuffer, byte offset, no new)', function test( t ) { + var ctor; + var arr; + + ctor = BooleanArray; + + arr = ctor( new ArrayBuffer( 8 ), 8 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); +}); + +tape( 'the constructor returns a boolean array (ArrayBuffer, byte offset, length)', function test( t ) { + var arr = new BooleanArray( new ArrayBuffer( 8 ), 8, 0 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + t.end(); +}); + +tape( 'the constructor returns a boolean array (ArrayBuffer, byte offset, length, no new)', function test( t ) { + var ctor; + var arr; + + ctor = BooleanArray; + + arr = ctor( new ArrayBuffer( 8 ), 8, 0 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); +}); + +tape( 'attached to the constructor is a property returning the number of bytes per array element', function test( t ) { + t.strictEqual( hasOwnProp( BooleanArray, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( BooleanArray.BYTES_PER_ELEMENT, 1, 'returns expected value' ); + t.end(); +}); + +tape( 'attached to the constructor is a property returning the constructor name', function test( t ) { + t.strictEqual( hasOwnProp( BooleanArray, 'name' ), true, 'has property' ); + t.strictEqual( BooleanArray.name, 'BooleanArray', 'returns expected value' ); + t.end(); +}); + +tape( 'the constructor returns an instance having a `BYTES_PER_ELEMENT` property returning the number of bytes per array element', function test( t ) { + var arr; + + t.strictEqual( hasOwnProp( BooleanArray.prototype, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( BooleanArray.prototype.BYTES_PER_ELEMENT, 1, 'returns expected value' ); + + arr = new BooleanArray( 0 ); + t.strictEqual( arr.BYTES_PER_ELEMENT, 1, 'returns expected value' ); + + t.end(); +}); + +tape( 'the constructor returns an instance having a `buffer` property for returning the underlying memory (i.e., ArrayBuffer)', function test( t ) { + var arr; + var buf; + + arr = new BooleanArray( 0 ); + buf = arr.buffer; + t.strictEqual( isArrayBuffer( buf ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the constructor returns an instance having a `byteLength` property for returning the number of bytes belonging to the array view', function test( t ) { + var arr; + var v; + + arr = new BooleanArray( 0 ); + v = arr.byteLength; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = new BooleanArray( new ArrayBuffer( 64 ), 8 ); + v = arr.byteLength; + t.strictEqual( v, 56, 'returns expected value' ); + + arr = new BooleanArray( new ArrayBuffer( 64 ), 64 ); + v = arr.byteLength; + t.strictEqual( v, 0, 'returns expected value' ); + + t.end(); +}); + +tape( 'the constructor returns an instance having a `byteOffset` property for returning the byte offset pointing to the first array element in the underlying memory', function test( t ) { + var arr; + var v; + + arr = new BooleanArray( 0 ); + v = arr.byteOffset; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = new BooleanArray( new ArrayBuffer( 64 ), 32 ); + v = arr.byteOffset; + t.strictEqual( v, 32, 'returns expected value' ); + + arr = new BooleanArray( new ArrayBuffer( 64 ), 64 ); + v = arr.byteOffset; + t.strictEqual( v, 64, 'returns expected value' ); + + t.end(); +}); + +tape( 'the constructor returns an instance having a `length` property for returning the number of array elements', function test( t ) { + var arr; + var v; + + // No arguments: + arr = new BooleanArray(); + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + // Explicit array length: + arr = new BooleanArray( 0 ); + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = new BooleanArray( 10 ); + v = arr.length; + t.strictEqual( v, 10, 'returns expected value' ); + + // Generic array: + arr = new BooleanArray( [] ); + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = new BooleanArray( [ true, false, true, false ] ); + v = arr.length; + t.strictEqual( v, 4, 'returns expected value' ); + + // Typed array: + arr = new BooleanArray( new Uint8Array( 0 ) ); + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = new BooleanArray( new Uint8Array( [ 1, 1 ] ) ); + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + // Boolean typed array: + arr = new BooleanArray( new BooleanArray( 0 ) ); + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = new BooleanArray( new BooleanArray( [ true, true ] ) ); + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + // ArrayBuffer: + arr = new BooleanArray( new ArrayBuffer( 64 ), 32 ); + v = arr.length; + t.strictEqual( v, 32, 'returns expected value' ); + + arr = new BooleanArray( new ArrayBuffer( 64 ), 64 ); + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + arr = new BooleanArray( new ArrayBuffer( 64 ), 32, 2 ); + v = arr.length; + t.strictEqual( v, 2, 'returns expected value' ); + + t.end(); +}); + +tape( 'the constructor returns an instance having a `length` property for returning the number of array elements (iterable)', function test( t ) { + var BooleanArray; + var iter; + var arr; + var v; + + BooleanArray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport, + '@stdlib/symbol/iterator': '__SYMBOL_ITERATOR__' + }); + + iter = { + 'next': next, + 'i': 0, + 'N': 4 + }; + arr = new BooleanArray( createIterable( iter ) ); + v = arr.length; + t.strictEqual( v, iter.N, 'returns expected value' ); + + t.end(); + + function hasSupport() { + return true; + } + + function createIterable( iterator ) { + var it = {}; + it[ '__SYMBOL_ITERATOR__' ] = iterable; + return it; + + function iterable() { + return iterator; + } + } + + function next() { + iter.i += 1; + if ( iter.i <= iter.N ) { + return { + 'value': true + }; + } + return { + 'done': true + }; + } +}); + +tape( 'the constructor throws an error if provided a non-iterable object (non-ES2015+)', function test( t ) { + var BooleanArray; + var values; + var i; + + BooleanArray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport + }); + + values = [ + {}, + { + '0': 1, + '1': 2, + '2': 3 + } + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return new BooleanArray( value ); + }; + } + + function hasSupport() { + return false; + } +}); + +tape( 'the constructor throws an error if provided a non-iterable object (ES2015+)', function test( t ) { + var BooleanArray; + var values; + var i; + + BooleanArray = proxyquire( './../lib/main.js', { + '@stdlib/assert/has-iterator-symbol-support': hasSupport, + '@stdlib/symbol/iterator': '__SYMBOL_ITERATOR__' + }); + + values = [ + {}, + { + '0': 1, + '1': 2, + '2': 3 + }, + { + '__SYMBOL_ITERATOR__': null + }, + { + '__SYMBOL_ITERATOR__': 'beep' + }, + { + '__SYMBOL_ITERATOR__': nonIterable1 + }, + { + '__SYMBOL_ITERATOR__': nonIterable2 + } + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return new BooleanArray( value ); + }; + } + + function hasSupport() { + return true; + } + + function nonIterable1() { + return null; + } + + function nonIterable2() { + return {}; + } +}); + +tape( 'the constructor throws an error if not provided a length, iterable, array-like object, or ArrayBuffer', function test( t ) { + var values; + var i; + + values = [ + '5', + 3.14, + -1, + NaN, + true, + false, + null, + void 0, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return new BooleanArray( value ); + }; + } +}); + +tape( 'the constructor throws an error if provided more than one argument and the first argument is not an ArrayBuffer', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return new BooleanArray( value, 0 ); + }; + } +}); + +tape( 'the constructor throws an error if provided a byte offset argument which is not a nonnegative integer', function test( t ) { + var values; + var i; + + values = [ + '5', + -1, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return new BooleanArray( new ArrayBuffer( 64 ), value ); + }; + } +}); + +tape( 'the constructor throws an error if provided a length argument which is not a nonnegative integer (ArrayBuffer)', function test( t ) { + var values; + var i; + + values = [ + '5', + -1, + 3.14, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return new BooleanArray( new ArrayBuffer( 64 ), 0, value ); + }; + } +}); + +tape( 'the constructor throws an error if provided insufficient memory to accommodate byte offset and length arguments', function test( t ) { + var values; + var i; + + values = [ + 8, + 16, + 24, + 32 + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), RangeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return new BooleanArray( new ArrayBuffer( 100 ), value, 1e3 ); + }; + } +}); diff --git a/bool/test/test.of.js b/bool/test/test.of.js new file mode 100644 index 00000000..b9e6dc4e --- /dev/null +++ b/bool/test/test.of.js @@ -0,0 +1,130 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var BooleanArray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof BooleanArray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'attached to the main export is an `of` method for creating a boolean array from a variable number of arguments', function test( t ) { + var arr; + + t.strictEqual( hasOwnProp( BooleanArray, 'of' ), true, 'has property' ); + t.strictEqual( isFunction( BooleanArray.of ), true, 'has method' ); + + arr = BooleanArray.of(); + t.strictEqual( arr instanceof BooleanArray, true, 'returns an instance' ); + + t.end(); +}); + +tape( 'the method throws an error if invoked with a `this` context which is not a constructor', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + [] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.of.call( value, true, true ); + }; + } +}); + +tape( 'the method throws an error if invoked with a `this` context which is not a boolean array constructor', function test( t ) { + var values; + var i; + + values = [ + {}, + null, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return BooleanArray.of.call( value, true, true ); + }; + } +}); + +tape( 'the method returns a boolean array', function test( t ) { + var arr; + var v; + + // No arguments: + arr = BooleanArray.of(); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 0, 'returns expected value' ); + + // Boolean arguments: + arr = BooleanArray.of( true, false, false, true ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 4, 'returns expected value' ); + + // Non-boolean arguments: + arr = BooleanArray.of( 1, {}, 0, null, 'beep' ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 5, 'returns expected value' ); + + // Mixed arguments: + arr = BooleanArray.of( true, 1, false, 0 ); + t.strictEqual( arr instanceof BooleanArray, true, 'returns expected value' ); + + v = arr.length; + t.strictEqual( v, 4, 'returns expected value' ); + + t.end(); +}); diff --git a/bool/test/test.set.js b/bool/test/test.set.js new file mode 100644 index 00000000..5b9f1df5 --- /dev/null +++ b/bool/test/test.set.js @@ -0,0 +1,387 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2018 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var ArrayBuffer = require( './../../buffer' ); +var Uint8Array = require( './../../uint8' ); +var BooleanArray = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof BooleanArray, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'attached to the prototype of the main export is a `set` method for setting one or more array elements', function test( t ) { + t.strictEqual( hasOwnProp( BooleanArray.prototype, 'set' ), true, 'has property' ); + t.strictEqual( isFunction( BooleanArray.prototype.set ), true, 'has method' ); + t.end(); +}); + +tape( 'the method throws an error if invoked with a `this` context which is not a boolean array instance', function test( t ) { + var values; + var arr; + var i; + + arr = new BooleanArray( 5 ); + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + {}, + [] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return arr.set.call( value, 0 ); + }; + } +}); + +tape( 'the method throws an error if provided an index argument which is not a nonnegative integer', function test( t ) { + var values; + var arr; + var i; + + arr = new BooleanArray( 10 ); + + values = [ + '5', + -5, + 3.14, + NaN, + true, + false, + null, + void 0, + {}, + [], + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return arr.set( true, value ); + }; + } +}); + +tape( 'the method throws an error if provided an index argument which is out-of-bounds (non-array)', function test( t ) { + var values; + var arr; + var i; + + arr = new BooleanArray( 10 ); + + values = [ + arr.length, + arr.length + 1, + arr.length + 2, + arr.length + 3 + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), RangeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return arr.set( true, value ); + }; + } +}); + +tape( 'the method throws an error if provided an index argument which is out-of-bounds (array-like object)', function test( t ) { + var values; + var arr1; + var arr2; + var i; + + arr1 = new BooleanArray( 10 ); + arr2 = []; + for ( i = 0; i < arr1.length; i++ ) { + arr2.push( true ); + } + + values = [ + 1, + 2, + 3, + 4, + 5 + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), RangeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return arr1.set( arr2, value ); + }; + } +}); + +tape( 'the method sets an array element (non-array)', function test( t ) { + var arr; + var v; + var i; + + arr = new BooleanArray( 10 ); + + v = arr.get( 0 ); + t.strictEqual( v, false, 'returns expected value' ); + + // No index argument: + arr.set( true ); + + v = arr.get( 0 ); + t.strictEqual( v, true, 'returns expected value' ); + + arr.set( false ); + + // Index argument: + for ( i = 0; i < arr.length; i++ ) { + v = arr.get( i ); + t.strictEqual( v, false, 'returns expected value' ); + + arr.set( true, i ); + v = arr.get( i ); + t.strictEqual( v, true, 'returns expected value' ); + } + t.end(); +}); + +tape( 'the method sets an array element (array-like object)', function test( t ) { + var arr; + var v; + var i; + + arr = new BooleanArray( 10 ); + + v = arr.get( 0 ); + t.strictEqual( v, false, 'returns expected value' ); + + // No index argument: + arr.set( [ true ] ); + + v = arr.get( 0 ); + t.strictEqual( v, true, 'returns expected value' ); + + arr.set( [ false ] ); + + // Index argument: + for ( i = 0; i < arr.length; i++ ) { + v = arr.get( i ); + t.strictEqual( v, false, 'returns expected value' ); + + arr.set( [ true ], i ); + + v = arr.get( i ); + t.strictEqual( v, true, 'returns expected value' ); + } + + // Multiple values, no index argument: + arr.set( [ true, true ] ); + + v = arr.get( 0 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 1 ); + t.strictEqual( v, true, 'returns expected value' ); + + // Multiple values, index argument: + arr.set( [ true, true ], 2 ); + + v = arr.get( 2 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 3 ); + t.strictEqual( v, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the method sets an array element (typed array; shared buffer)', function test( t ) { + var byteOffset; + var arr; + var src; + var buf; + var ab; + var v; + var i; + + byteOffset = 112; + + ab = new ArrayBuffer( 240 ); + arr = new BooleanArray( ab, byteOffset, 10 ); + + // Overlapping (requires copy), multiple values, no index argument: + buf = [ true, true ]; + src = new Uint8Array( ab, byteOffset-(1*arr.BYTES_PER_ELEMENT), 2 ); + for ( i = 0; i < buf.length; i++ ) { + src[ i ] = buf[ i ]; + } + arr.set( src ); + + v = arr.get( 0 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 1 ); + t.strictEqual( v, true, 'returns expected value' ); + + // Overlapping (requires copy), multiple values, index argument: + buf = [ true, true ]; + src = new Uint8Array( ab, byteOffset+(1*arr.BYTES_PER_ELEMENT), 2 ); + for ( i = 0; i < buf.length; i++ ) { + src[ i ] = buf[ i ]; + } + arr.set( src, 2 ); + + v = arr.get( 2 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 3 ); + t.strictEqual( v, true, 'returns expected value' ); + + // Overlapping (no copy), multiple values, no index argument: + buf = [ true, true ]; + src = new Uint8Array( ab, byteOffset+(1*arr.BYTES_PER_ELEMENT), 2 ); + for ( i = 0; i < buf.length; i++ ) { + src[ i ] = buf[ i ]; + } + arr.set( src ); + + v = arr.get( 0 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 1 ); + t.strictEqual( v, true, 'returns expected value' ); + + // Overlapping (no copy), multiple values, index argument: + buf = [ true, true ]; + src = new Uint8Array( ab, byteOffset+(3*arr.BYTES_PER_ELEMENT), 2 ); + for ( i = 0; i < buf.length; i++ ) { + src[ i ] = buf[ i ]; + } + arr.set( src, 2 ); + + v = arr.get( 2 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 3 ); + t.strictEqual( v, true, 'returns expected value' ); + + t.end(); +}); + +tape( 'the method sets an array element (boolean array; shared buffer)', function test( t ) { + var byteOffset; + var arr; + var src; + var buf; + var ab; + var v; + var i; + + byteOffset = 112; + + ab = new ArrayBuffer( 240 ); + arr = new BooleanArray( ab, byteOffset, 10 ); + + // Overlapping (requires copy), multiple values, no index argument: + buf = [ true, true ]; + src = new BooleanArray( ab, byteOffset-(1*arr.BYTES_PER_ELEMENT), 2 ); + for ( i = 0; i < buf.length; i++ ) { + src.set( buf[ i ], i ); + } + arr.set( src ); + + v = arr.get( 0 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 1 ); + t.strictEqual( v, true, 'returns expected value' ); + + // Overlapping (requires copy), multiple values, index argument: + buf = [ true, true ]; + src = new BooleanArray( ab, byteOffset+(1*arr.BYTES_PER_ELEMENT), 2 ); + for ( i = 0; i < buf.length; i++ ) { + src.set( buf[ i ], i ); + } + arr.set( src, 2 ); + + v = arr.get( 2 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 3 ); + t.strictEqual( v, true, 'returns expected value' ); + + // Overlapping (no copy), multiple values, no index argument: + buf = [ true, true ]; + src = new BooleanArray( ab, byteOffset+(1*arr.BYTES_PER_ELEMENT), 2 ); + for ( i = 0; i < buf.length; i++ ) { + src.set( buf[ i ], i ); + } + arr.set( src ); + + v = arr.get( 0 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 1 ); + t.strictEqual( v, true, 'returns expected value' ); + + // Overlapping (no copy), multiple values, index argument: + buf = [ true, true ]; + src = new BooleanArray( ab, byteOffset+(3*arr.BYTES_PER_ELEMENT), 2 ); + for ( i = 0; i < buf.length; i++ ) { + src.set( buf[ i ], i ); + } + arr.set( src, 2 ); + + v = arr.get( 2 ); + t.strictEqual( v, true, 'returns expected value' ); + + v = arr.get( 3 ); + t.strictEqual( v, true, 'returns expected value' ); + + t.end(); +}); diff --git a/complex128/docs/types/index.d.ts b/complex128/docs/types/index.d.ts index c2d280c6..27d49715 100644 --- a/complex128/docs/types/index.d.ts +++ b/complex128/docs/types/index.d.ts @@ -1744,7 +1744,7 @@ interface Complex128ArrayConstructor { /** * Creates a new 128-bit complex number array from a variable number of arguments. * - * @param element - array elements + * @param elements - array elements * @returns 128-bit complex number array * * @example diff --git a/complex128/test/test.js b/complex128/test/test.js index dc6db426..aeb3ae4d 100644 --- a/complex128/test/test.js +++ b/complex128/test/test.js @@ -512,7 +512,7 @@ tape( 'the constructor returns an instance having a `length` property for return } }); -tape( 'the constructor throws an error if provided an ArrayBuffer which is a multiple of 16', function test( t ) { +tape( 'the constructor throws an error if provided an ArrayBuffer which is not a multiple of 16', function test( t ) { var values; var i; diff --git a/complex64/docs/types/index.d.ts b/complex64/docs/types/index.d.ts index 6f11e3f5..e643f408 100644 --- a/complex64/docs/types/index.d.ts +++ b/complex64/docs/types/index.d.ts @@ -1746,7 +1746,7 @@ interface Complex64ArrayConstructor { /** * Creates a new 64-bit complex number array from a variable number of arguments. * - * @param element - array elements + * @param elements - array elements * @returns 64-bit complex number array * * @example diff --git a/complex64/test/test.js b/complex64/test/test.js index 05a57e7b..889bdfd8 100644 --- a/complex64/test/test.js +++ b/complex64/test/test.js @@ -512,7 +512,7 @@ tape( 'the constructor returns an instance having a `length` property for return } }); -tape( 'the constructor throws an error if provided an ArrayBuffer which is a multiple of 8', function test( t ) { +tape( 'the constructor throws an error if provided an ArrayBuffer which is not a multiple of 8', function test( t ) { var values; var i; diff --git a/lib/index.js b/lib/index.js index d4d4d3df..1aaf0ac9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -49,6 +49,15 @@ var ns = {}; */ setReadOnly( ns, 'base', require( './../base' ) ); +/** +* @name BooleanArray +* @memberof ns +* @readonly +* @constructor +* @see {@link module:@stdlib/array/bool} +*/ +setReadOnly( ns, 'BooleanArray', require( './../bool' ) ); + /** * @name ArrayBuffer * @memberof ns diff --git a/package.json b/package.json index 4a191f53..90502671 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "dependencies": { "@stdlib/assert": "github:stdlib-js/assert#main", "@stdlib/blas": "github:stdlib-js/blas#main", + "@stdlib/boolean": "github:stdlib-js/boolean#main", "@stdlib/buffer": "github:stdlib-js/buffer#main", "@stdlib/complex": "github:stdlib-js/complex#main", "@stdlib/constants": "github:stdlib-js/constants#main",