Skip to content

Commit d22cdc6

Browse files
committed
Auto-generated commit
1 parent e2c9645 commit d22cdc6

File tree

8 files changed

+2070
-11
lines changed

8 files changed

+2070
-11
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
### Features
1212

13+
- [`b2cefbe`](https://github.com/stdlib-js/stdlib/commit/b2cefbe2b2192cb705b85c43ffac2f57ca782c42) - add custom `valueOf` method
1314
- [`848f226`](https://github.com/stdlib-js/stdlib/commit/848f226d45aad2d627453c8306ae192c75338ac3) - add `factory` method
1415
- [`916b907`](https://github.com/stdlib-js/stdlib/commit/916b9073d6cf82262233e835f9bbbaca26d685f0) - add `ndarray/vector/ctor`
1516
- [`9b0d852`](https://github.com/stdlib-js/stdlib/commit/9b0d8520418c2788d20d446b6a39471b6393a787) - add `loopOrder` to namespace
@@ -390,6 +391,8 @@ A total of 15 issues were closed in this release:
390391

391392
<details>
392393

394+
- [`01544ae`](https://github.com/stdlib-js/stdlib/commit/01544aef20deb6e2b8c6826462cd29916ce3e45b) - **test:** add tests _(by Athan Reines)_
395+
- [`b2cefbe`](https://github.com/stdlib-js/stdlib/commit/b2cefbe2b2192cb705b85c43ffac2f57ca782c42) - **feat:** add custom `valueOf` method _(by Athan Reines)_
393396
- [`848f226`](https://github.com/stdlib-js/stdlib/commit/848f226d45aad2d627453c8306ae192c75338ac3) - **feat:** add `factory` method _(by Athan Reines)_
394397
- [`d30fed0`](https://github.com/stdlib-js/stdlib/commit/d30fed0b3516e362f957aa15d1521b3b3fe6cefd) - **docs:** update examples _(by Athan Reines)_
395398
- [`916b907`](https://github.com/stdlib-js/stdlib/commit/916b9073d6cf82262233e835f9bbbaca26d685f0) - **feat:** add `ndarray/vector/ctor` _(by Athan Reines)_

base/ctor/benchmark/benchmark.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,3 +1275,71 @@ bench( pkg+':toString', function benchmark( b ) {
12751275
b.pass( 'benchmark finished' );
12761276
b.end();
12771277
});
1278+
1279+
bench( pkg+':valueOf:ndims=0', function benchmark( b ) {
1280+
var strides;
1281+
var buffer;
1282+
var offset;
1283+
var shape;
1284+
var order;
1285+
var out;
1286+
var v;
1287+
var i;
1288+
1289+
buffer = [ 1.0 ];
1290+
shape = [];
1291+
strides = [ 0 ];
1292+
offset = 0;
1293+
order = 'row-major';
1294+
1295+
out = ndarray( 'generic', buffer, shape, strides, offset, order );
1296+
1297+
b.tic();
1298+
for ( i = 0; i < b.iterations; i++ ) {
1299+
buffer[ 0 ] = i;
1300+
v = out.valueOf();
1301+
if ( typeof v !== 'number' ) {
1302+
b.fail( 'should return a number' );
1303+
}
1304+
}
1305+
b.toc();
1306+
if ( typeof v !== 'number' ) {
1307+
b.fail( 'should return a number' );
1308+
}
1309+
b.pass( 'benchmark finished' );
1310+
b.end();
1311+
});
1312+
1313+
bench( pkg+':valueOf:ndims>=1', function benchmark( b ) {
1314+
var strides;
1315+
var buffer;
1316+
var offset;
1317+
var shape;
1318+
var order;
1319+
var out;
1320+
var v;
1321+
var i;
1322+
1323+
buffer = [ 1.0, 2.0 ];
1324+
shape = [ 2 ];
1325+
strides = [ 1 ];
1326+
offset = 0;
1327+
order = 'row-major';
1328+
1329+
out = ndarray( 'generic', buffer, shape, strides, offset, order );
1330+
1331+
b.tic();
1332+
for ( i = 0; i < b.iterations; i++ ) {
1333+
buffer[ i%buffer.length ] = i;
1334+
v = out.valueOf();
1335+
if ( typeof v !== 'object' ) {
1336+
b.fail( 'should return an object' );
1337+
}
1338+
}
1339+
b.toc();
1340+
if ( typeof v !== 'object' ) {
1341+
b.fail( 'should return an object' );
1342+
}
1343+
b.pass( 'benchmark finished' );
1344+
b.end();
1345+
});

base/ctor/lib/main.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var igetValue = require( './iget.js' );
3838
var isetValue = require( './iset.js' );
3939
var setValue = require( './set.js' );
4040
var getValue = require( './get.js' );
41+
var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redeclare
4142
var toJSON = require( './tojson.js' );
4243
var toString = require( './tostring.js' ); // eslint-disable-line stdlib/no-redeclare
4344
var meta2dataview = require( './meta2dataview.js' );
@@ -569,6 +570,42 @@ setReadOnly( ndarray.prototype, 'toString', toString );
569570
*/
570571
setReadOnly( ndarray.prototype, 'toJSON', toJSON );
571572

573+
/**
574+
* Converts an ndarray instance to a primitive value.
575+
*
576+
* ## Notes
577+
*
578+
* - Only zero-dimensional ndarrays are converted to a primitive value. For ndarray instances having one or more dimensions, the method returns the `this` value, as is the default behavior for objects.
579+
*
580+
* @name valueOf
581+
* @memberof ndarray.prototype
582+
* @type {Function}
583+
* @returns {(*|ndarray)} result
584+
*
585+
* @example
586+
* var buffer = [ 3.14 ];
587+
* var shape = [];
588+
* var strides = [ 0 ];
589+
* var offset = 0;
590+
*
591+
* var x = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' );
592+
*
593+
* var v = x.valueOf();
594+
* // returns 3.14
595+
*
596+
* @example
597+
* var buffer = [ 3.14 ];
598+
* var shape = [ 1 ];
599+
* var strides = [ 1 ];
600+
* var offset = 0;
601+
*
602+
* var x = ndarray( 'generic', buffer, shape, strides, offset, 'row-major' );
603+
*
604+
* var v = x.valueOf();
605+
* // returns <ndarray>
606+
*/
607+
setReadOnly( ndarray.prototype, 'valueOf', valueOf );
608+
572609
/**
573610
* Serializes ndarray meta data to a `DataView`.
574611
*

base/ctor/lib/valueof.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2025 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MAIN //
22+
23+
/**
24+
* Converts an ndarray instance to a primitive value.
25+
*
26+
* ## Notes
27+
*
28+
* - Only zero-dimensional ndarrays are converted to a primitive value. For ndarray instances having one or more dimensions, the method returns the `this` value, as is the default behavior for objects.
29+
*
30+
* @private
31+
* @returns {(*|ndarray)} result
32+
*/
33+
function valueOf() { // eslint-disable-line stdlib/no-redeclare
34+
/* eslint-disable no-invalid-this */
35+
if ( this._ndims === 0 ) {
36+
return this.iget();
37+
}
38+
return this;
39+
40+
/* eslint-enable no-invalid-this */
41+
}
42+
43+
44+
// EXPORTS //
45+
46+
module.exports = valueOf;

base/ctor/test/test.js

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3551,7 +3551,9 @@ tape( 'an ndarray has a custom `toString()` method (large array)', function test
35513551
var arr;
35523552

35533553
dtype = 'generic';
3554-
buffer = new Array( 1e4 );
3554+
3555+
// Intentionally create a sparse array:
3556+
buffer = new Array( 1e4 ); // eslint-disable-line stdlib/no-new-array
35553557
shape = [ buffer.length ];
35563558
order = 'row-major';
35573559
strides = [ 1 ];
@@ -3817,6 +3819,68 @@ tape( 'an ndarray has a custom `toJSON()` method (0d)', function test( t ) {
38173819
t.end();
38183820
});
38193821

3822+
tape( 'an ndarray has a custom `valueOf()` method (0d)', function test( t ) {
3823+
var expected;
3824+
var strides;
3825+
var actual;
3826+
var buffer;
3827+
var offset;
3828+
var dtype;
3829+
var order;
3830+
var shape;
3831+
var arr;
3832+
3833+
dtype = 'generic';
3834+
buffer = [ 3.14 ];
3835+
shape = [];
3836+
order = 'row-major';
3837+
strides = [ 0 ];
3838+
offset = 0;
3839+
3840+
arr = ndarray( dtype, buffer, shape, strides, offset, order );
3841+
3842+
t.strictEqual( hasOwnProp( arr, 'valueOf' ), false, 'does not have own property' );
3843+
t.strictEqual( hasProp( arr, 'valueOf' ), true, 'has property' );
3844+
t.strictEqual( isFunction( arr.valueOf ), true, 'has method' );
3845+
3846+
expected = 3.14;
3847+
actual = arr.valueOf();
3848+
t.strictEqual( actual, expected, 'returns expected value' );
3849+
3850+
t.end();
3851+
});
3852+
3853+
tape( 'an ndarray has a custom `valueOf()` method (>=1d)', function test( t ) {
3854+
var expected;
3855+
var strides;
3856+
var actual;
3857+
var buffer;
3858+
var offset;
3859+
var dtype;
3860+
var order;
3861+
var shape;
3862+
var arr;
3863+
3864+
dtype = 'generic';
3865+
buffer = [ 1.0, 2.0 ];
3866+
shape = [ 2 ];
3867+
order = 'row-major';
3868+
strides = [ 0 ];
3869+
offset = 0;
3870+
3871+
arr = ndarray( dtype, buffer, shape, strides, offset, order );
3872+
3873+
t.strictEqual( hasOwnProp( arr, 'valueOf' ), false, 'does not have own property' );
3874+
t.strictEqual( hasProp( arr, 'valueOf' ), true, 'has property' );
3875+
t.strictEqual( isFunction( arr.valueOf ), true, 'has method' );
3876+
3877+
expected = arr;
3878+
actual = arr.valueOf();
3879+
t.strictEqual( actual, expected, 'returns expected value' );
3880+
3881+
t.end();
3882+
});
3883+
38203884
tape( 'an ndarray has a protocol method for serializing meta data to a DataView', function test( t ) {
38213885
/* eslint-disable no-underscore-dangle */
38223886
var expected;

vector/ctor/lib/main.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ function arraybuffer2vector( dtype, buffer, length, stride, byteOffset, order, o
165165
N = length * stride;
166166

167167
// Adjust the byte offset to point to the element marking the beginning of the view:
168-
if ( stride < 0 ) {
168+
if ( stride < 0 ) { // TODO: the following is effectively unreachable code, as provided strides are never anything other than unity; however, we keep this around in the event that we want to extract this function to a separate package and would like to maintain generality
169169
N *= -1;
170170
o -= N * bytesPerElement( dtype );
171171
}
@@ -483,6 +483,9 @@ function vector() {
483483
if ( nargs === 2 ) {
484484
// Case: vector( dtype, options )
485485
if ( isDataType( arg0 ) ) {
486+
if ( arg1 === null ) {
487+
throw new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', arg1 ) );
488+
}
486489
return vectorWithDType( 0, arg0, arg1 );
487490
}
488491
// Case: vector( arg0, dtype )
@@ -501,6 +504,9 @@ function vector() {
501504
return arraybuffer2vector( DEFAULT_DTYPE, arg0, (arg0.byteLength-arg1)/bytesPerElement( DEFAULT_DTYPE ), 1, arg1, DEFAULT_ORDER );
502505
}
503506
// Case: vector( arg0, options )
507+
if ( arg1 === null ) {
508+
throw new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', arg1 ) );
509+
}
504510
out = vectorWithDType( arg0, DEFAULT_DTYPE, arg1 );
505511
if ( out === null ) {
506512
throw new TypeError( format( 'invalid argument. First argument must be a length, ArrayBuffer, typed array, array-like object, or iterable. Value: `%s`.', arg0 ) );
@@ -523,6 +529,9 @@ function vector() {
523529
}
524530
// Case: vector( arg0, dtype, options )
525531
if ( isDataType( arg1 ) ) {
532+
if ( arg2 === null ) {
533+
throw new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', arg2 ) );
534+
}
526535
out = vectorWithDType( arg0, arg1, arg2 );
527536
if ( out === null ) {
528537
throw new TypeError( format( 'invalid argument. First argument must be a length, ArrayBuffer, typed array, array-like object, or iterable. Value: `%s`.', arg0 ) );
@@ -536,15 +545,15 @@ function vector() {
536545
if ( !isNonNegativeInteger( arg1 ) ) {
537546
throw new TypeError( format( 'invalid argument. Byte offset must be a nonnegative integer. Value: `%s`.', arg1 ) );
538547
}
539-
// Case: vector( ArrayBuffer, byteOffset, options )
540-
if ( isPlainObject( arg2 ) ) {
541-
return arraybuffer2vector( DEFAULT_DTYPE, arg0, (arg0.byteLength-arg1)/bytesPerElement( DEFAULT_DTYPE ), 1, arg1, resolveOrder( arg2 ), arg2 );
542-
}
543548
// Case: vector( ArrayBuffer, byteOffset, length )
544-
if ( !isNonNegativeInteger( arg2 ) ) {
545-
throw new TypeError( format( 'invalid argument. Length must be a nonnegative integer. Value: `%s`.', arg2 ) );
549+
if ( isNonNegativeInteger( arg2 ) ) {
550+
return arraybuffer2vector( DEFAULT_DTYPE, arg0, arg2, 1, arg1, DEFAULT_ORDER );
551+
}
552+
// Case: vector( ArrayBuffer, byteOffset, options )
553+
if ( arg2 === null ) {
554+
throw new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', arg2 ) );
546555
}
547-
return arraybuffer2vector( DEFAULT_DTYPE, arg0, arg2, 1, arg1, DEFAULT_ORDER );
556+
return arraybuffer2vector( DEFAULT_DTYPE, arg0, (arg0.byteLength-arg1)/bytesPerElement( DEFAULT_DTYPE ), 1, arg1, resolveOrder( arg2 ), arg2 );
548557
}
549558
arg3 = arguments[ 3 ];
550559

vector/ctor/test/test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,3 @@ tape( 'attached to the main export is a `factory` method', function test( t ) {
3737
t.strictEqual( isMethod( vector, 'factory' ), true, 'returns expected value' );
3838
t.end();
3939
});
40-
41-
// FIXME: add tests (see array/typed and ndarray/zeros)

0 commit comments

Comments
 (0)