@@ -26,6 +26,7 @@ var indicesComplement = require( '@stdlib/array/base/indices-complement' );
2626var takeIndexed2 = require ( '@stdlib/array/base/take-indexed2' ) ;
2727var iterationOrder = require ( '@stdlib/ndarray/base/iteration-order' ) ;
2828var strides2order = require ( '@stdlib/ndarray/base/strides2order' ) ;
29+ var anyIsEntryIn = require ( '@stdlib/array/base/any-is-entry-in' ) ;
2930var numel = require ( '@stdlib/ndarray/base/numel' ) ;
3031var join = require ( '@stdlib/array/base/join' ) ;
3132var format = require ( '@stdlib/string/format' ) ;
@@ -128,6 +129,22 @@ var BLOCKED_ACCESSOR_BINARY = [
128129var MAX_DIMS = BINARY . length - 1 ;
129130
130131
132+ // FUNCTIONS //
133+
134+ /**
135+ * Returns a boolean indicating if at least one ndarray data buffer implements the accessor protocol.
136+ *
137+ * @private
138+ * @param {ndarrayLike } x - first ndarray
139+ * @param {ndarrayLike } y - second ndarray
140+ * @param {ndarrayLike } z - third ndarray
141+ * @returns {boolean } boolean indicating whether an ndarray data buffer implements the accessor protocol
142+ */
143+ function hasAccessors ( x , y , z ) {
144+ return anyIsEntryIn ( [ x , y , z ] , 'accessorProtocol' , true ) ;
145+ }
146+
147+
131148// MAIN //
132149
133150/**
@@ -485,17 +502,17 @@ function binaryReduceStrided1d( fcn, arrays, dims, options ) { // eslint-disable
485502
486503 // Determine whether we can avoid iteration altogether...
487504 if ( K === 0 ) {
488- if ( z . accessorProtocol ) {
505+ if ( hasAccessors ( x , y , z ) ) {
489506 return ACCESSOR_BINARY [ K ] ( fcn , arr , strategy1 , strategy2 , opts ) ;
490507 }
491508 return BINARY [ K ] ( fcn , arr , strategy1 , strategy2 , opts ) ;
492509 }
493510 // Determine whether we only have one loop dimension and can thus readily perform one-dimensional iteration...
494511 if ( K === 1 ) {
495- if ( z . accessorProtocol ) {
496- return ACCESSOR_BINARY [ K ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ;
512+ if ( hasAccessors ( x , y , z ) ) {
513+ return ACCESSOR_BINARY [ K ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ; // eslint-disable-line max-len
497514 }
498- return BINARY [ K ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ;
515+ return BINARY [ K ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ; // eslint-disable-line max-len
499516 }
500517 sz = z . strides ;
501518
@@ -513,10 +530,10 @@ function binaryReduceStrided1d( fcn, arrays, dims, options ) { // eslint-disable
513530 }
514531 slx = [ slx [ i ] ] ;
515532 sly = [ sly [ i ] ] ;
516- if ( z . accessorProtocol ) {
517- return ACCESSOR_BINARY [ 1 ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ;
533+ if ( hasAccessors ( x , y , z ) ) {
534+ return ACCESSOR_BINARY [ 1 ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ; // eslint-disable-line max-len
518535 }
519- return BINARY [ 1 ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ;
536+ return BINARY [ 1 ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ; // eslint-disable-line max-len
520537 }
521538 iox = iterationOrder ( slx ) ; // +/-1
522539 ioy = iterationOrder ( sly ) ; // +/-1
@@ -527,22 +544,22 @@ function binaryReduceStrided1d( fcn, arrays, dims, options ) { // eslint-disable
527544 ordy = strides2order ( sly ) ;
528545 if ( iox !== 0 && ioy !== 0 && ioz !== 0 && ordx === strides2order ( sz ) && ordy === strides2order ( sz ) && K <= MAX_DIMS ) { // eslint-disable-line max-len
529546 // So long as iteration for each respective array always moves in the same direction (i.e., no mixed sign strides) and the memory layouts are the same, we can leverage cache-optimal (i.e., normal) nested loops without resorting to blocked iteration...
530- if ( z . accessorProtocol ) {
547+ if ( hasAccessors ( x , y , z ) ) {
531548 return ACCESSOR_BINARY [ K ] ( fcn , arr , views , slx , sly , ordx === 1 , strategy1 , strategy2 , opts ) ; // eslint-disable-line max-len
532549 }
533- return BINARY [ K ] ( fcn , arr , views , slx , sly , ordx === 1 , strategy1 , strategy2 , opts ) ;
550+ return BINARY [ K ] ( fcn , arr , views , slx , sly , ordx === 1 , strategy1 , strategy2 , opts ) ; // eslint-disable-line max-len
534551 }
535552 // At this point, we're either dealing with non-contiguous n-dimensional arrays, high dimensional n-dimensional arrays, and/or arrays having differing memory layouts, so our only hope is that we can still perform blocked iteration...
536553
537554 // Determine whether we can perform blocked iteration...
538555 if ( K <= MAX_DIMS ) {
539- if ( z . accessorProtocol ) {
556+ if ( hasAccessors ( x , y , z ) ) {
540557 return BLOCKED_ACCESSOR_BINARY [ K - 2 ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ; // eslint-disable-line max-len
541558 }
542- return BLOCKED_BINARY [ K - 2 ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ;
559+ return BLOCKED_BINARY [ K - 2 ] ( fcn , arr , views , slx , sly , strategy1 , strategy2 , opts ) ; // eslint-disable-line max-len
543560 }
544561 // Fall-through to linear view iteration without regard for how data is stored in memory (i.e., take the slow path)...
545- if ( z . accessorProtocol ) {
562+ if ( hasAccessors ( x , y , z ) ) {
546563 return accessorbinarynd ( fcn , arr , views , strategy1 , strategy2 , opts ) ;
547564 }
548565 binarynd ( fcn , arr , views , strategy1 , strategy2 , opts ) ;
0 commit comments