@@ -27,6 +27,7 @@ var isComplexArray = require( '@stdlib/array/base/assert/is-complex-typed-array'
2727var isBooleanArray = require ( '@stdlib/array/base/assert/is-booleanarray' ) ;
2828var iterationOrder = require ( '@stdlib/ndarray/base/iteration-order' ) ;
2929var strides2order = require ( '@stdlib/ndarray/base/strides2order' ) ;
30+ var anyIsEntryIn = require ( '@stdlib/array/base/any-is-entry-in' ) ;
3031var castReturn = require ( '@stdlib/complex/base/cast-return' ) ;
3132var complexCtors = require ( '@stdlib/complex/ctors' ) ;
3233var minmaxViewBufferIndex = require ( '@stdlib/ndarray/base/minmax-view-buffer-index' ) ;
@@ -128,7 +129,7 @@ var BLOCKED_ACCESSOR_WHERE = [
128129 blockedaccessorwhere9d ,
129130 blockedaccessorwhere10d // 8
130131] ;
131- var MAX_DIMS = where . length - 1 ;
132+ var MAX_DIMS = WHERE . length - 1 ;
132133
133134// TODO: consider adding a package utility for mapping a complex dtype to its complementary real-valued counterpart
134135var COMPLEX_TO_REAL = { // WARNING: this table needs to be manually updated if we add support for additional complex number dtypes
@@ -140,6 +141,19 @@ var COMPLEX_TO_REAL = { // WARNING: this table needs to be manually updated if w
140141
141142// FUNCTIONS //
142143
144+ /**
145+ * Returns a boolean indicating if at least one ndarray data buffer implements the accessor protocol.
146+ *
147+ * @private
148+ * @param {ndarrayLike } x - first ndarray
149+ * @param {ndarrayLike } y - second ndarray
150+ * @param {ndarrayLike } z - third ndarray
151+ * @returns {boolean } boolean indicating whether an ndarray data buffer implements the accessor protocol
152+ */
153+ function hasAccessors ( x , y , z ) {
154+ return anyIsEntryIn ( [ x , y , z ] , 'accessorProtocol' , true ) ;
155+ }
156+
143157/**
144158* Converts a boolean ndarray to an 8-bit unsigned integer ndarray.
145159*
@@ -206,7 +220,7 @@ function complex2real( x ) {
206220* - **offset**: index offset.
207221* - **order**: specifies whether an ndarray is row-major (C-style) or column major (Fortran-style).
208222*
209- * @param {ArrayLikeObject<Object> } arrays - array-like object containing once condition array, two input arrays, and one output array
223+ * @param {ArrayLikeObject<Object> } arrays - array-like object containing one condition array, two input arrays, and one output array
210224* @throws {Error } arrays must have the same number of dimensions
211225* @throws {Error } arrays must have the same shape
212226* @returns {void }
@@ -315,8 +329,8 @@ function where( arrays ) {
315329 o = ndarray2object ( arrays [ 3 ] ) ;
316330
317331 // Always reinterpret condition array to uint8
318- if ( isBooleanArray ( c . data ) ) {
319- c = boolean2uint8 ( c ) ;
332+ if ( isBooleanArray ( c . data ) ) {
333+ c = boolean2uint8 ( c ) ;
320334 }
321335
322336 // Check for known array types which can be reinterpreted for better iteration performance...
@@ -349,7 +363,7 @@ function where( arrays ) {
349363 }
350364 // Determine whether we can avoid iteration altogether...
351365 if ( ndims === 0 ) {
352- if ( c . accessorProtocol || x . accessorProtocol || y . accessorProtocol || o . accessorProtocol ) {
366+ if ( hasAccessors ( x , y , o ) ) {
353367 return ACCESSOR_WHERE [ ndims ] ( c , x , y , o ) ;
354368 }
355369 return WHERE [ ndims ] ( c , x , y , o ) ;
@@ -376,7 +390,7 @@ function where( arrays ) {
376390 }
377391 // Determine whether the ndarrays are one-dimensional and thus readily translate to one-dimensional strided arrays...
378392 if ( ndims === 1 ) {
379- if ( c . accessorProtocol || x . accessorProtocol || y . accessorProtocol || o . accessorProtocol ) {
393+ if ( hasAccessors ( x , y , o ) ) {
380394 return ACCESSOR_WHERE [ ndims ] ( c , x , y , o ) ;
381395 }
382396 return WHERE [ ndims ] ( c , x , y , o ) ;
@@ -402,7 +416,7 @@ function where( arrays ) {
402416 x . strides = [ sx [ i ] ] ;
403417 y . strides = [ sy [ i ] ] ;
404418 o . strides = [ so [ i ] ] ;
405- if ( x . accessorProtocol || y . accessorProtocol || o . accessorProtocol ) {
419+ if ( hasAccessors ( x , y , o ) ) {
406420 return ACCESSOR_WHERE [ 1 ] ( c , x , y , o ) ;
407421 }
408422 return WHERE [ 1 ] ( c , x , y , o ) ;
@@ -456,7 +470,7 @@ function where( arrays ) {
456470 x . offset = ox ;
457471 y . offset = oy ;
458472 o . offset = oo ;
459- if ( c . accessorProtocol || x . accessorProtocol || y . accessorProtocol || o . accessorProtocol ) {
473+ if ( hasAccessors ( x , y , o ) ) {
460474 return ACCESSOR_WHERE [ 1 ] ( c , x , y , o ) ;
461475 }
462476 return WHERE [ 1 ] ( c , x , y , o ) ;
@@ -466,7 +480,7 @@ function where( arrays ) {
466480 // Determine whether we can use simple nested loops...
467481 if ( ndims <= MAX_DIMS ) {
468482 // So long as iteration for each respective array always moves in the same direction (i.e., no mixed sign strides), we can leverage cache-optimal (i.e., normal) nested loops without resorting to blocked iteration...
469- if ( c . accessorProtocol || x . accessorProtocol || y . accessorProtocol || o . accessorProtocol ) {
483+ if ( hasAccessors ( x , y , o ) ) {
470484 return ACCESSOR_WHERE [ ndims ] ( c , x , y , o , ord === 1 ) ;
471485 }
472486 return WHERE [ ndims ] ( c , x , y , o , ord === 1 ) ;
@@ -477,13 +491,13 @@ function where( arrays ) {
477491
478492 // Determine whether we can perform blocked iteration...
479493 if ( ndims <= MAX_DIMS ) {
480- if ( c . accessorProtocol || x . accessorProtocol || y . accessorProtocol || o . accessorProtocol ) {
494+ if ( hasAccessors ( x , y , o ) ) {
481495 return BLOCKED_ACCESSOR_WHERE [ ndims - 2 ] ( c , x , y , o ) ;
482496 }
483497 return BLOCKED_WHERE [ ndims - 2 ] ( c , x , y , o ) ;
484498 }
485499 // Fall-through to linear view iteration without regard for how data is stored in memory (i.e., take the slow path)...
486- if ( c . accessorProtocol || x . accessorProtocol || y . accessorProtocol || o . accessorProtocol ) {
500+ if ( hasAccessors ( x , y , o ) ) {
487501 return accessorwherend ( c , x , y , o ) ;
488502 }
489503 wherend ( c , x , y , o ) ;
0 commit comments