time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

_createHybrid.js (3252B)


      1 var composeArgs = require('./_composeArgs'),
      2     composeArgsRight = require('./_composeArgsRight'),
      3     countHolders = require('./_countHolders'),
      4     createCtor = require('./_createCtor'),
      5     createRecurry = require('./_createRecurry'),
      6     getHolder = require('./_getHolder'),
      7     reorder = require('./_reorder'),
      8     replaceHolders = require('./_replaceHolders'),
      9     root = require('./_root');
     10 
     11 /** Used to compose bitmasks for function metadata. */
     12 var WRAP_BIND_FLAG = 1,
     13     WRAP_BIND_KEY_FLAG = 2,
     14     WRAP_CURRY_FLAG = 8,
     15     WRAP_CURRY_RIGHT_FLAG = 16,
     16     WRAP_ARY_FLAG = 128,
     17     WRAP_FLIP_FLAG = 512;
     18 
     19 /**
     20  * Creates a function that wraps `func` to invoke it with optional `this`
     21  * binding of `thisArg`, partial application, and currying.
     22  *
     23  * @private
     24  * @param {Function|string} func The function or method name to wrap.
     25  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
     26  * @param {*} [thisArg] The `this` binding of `func`.
     27  * @param {Array} [partials] The arguments to prepend to those provided to
     28  *  the new function.
     29  * @param {Array} [holders] The `partials` placeholder indexes.
     30  * @param {Array} [partialsRight] The arguments to append to those provided
     31  *  to the new function.
     32  * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
     33  * @param {Array} [argPos] The argument positions of the new function.
     34  * @param {number} [ary] The arity cap of `func`.
     35  * @param {number} [arity] The arity of `func`.
     36  * @returns {Function} Returns the new wrapped function.
     37  */
     38 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
     39   var isAry = bitmask & WRAP_ARY_FLAG,
     40       isBind = bitmask & WRAP_BIND_FLAG,
     41       isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
     42       isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
     43       isFlip = bitmask & WRAP_FLIP_FLAG,
     44       Ctor = isBindKey ? undefined : createCtor(func);
     45 
     46   function wrapper() {
     47     var length = arguments.length,
     48         args = Array(length),
     49         index = length;
     50 
     51     while (index--) {
     52       args[index] = arguments[index];
     53     }
     54     if (isCurried) {
     55       var placeholder = getHolder(wrapper),
     56           holdersCount = countHolders(args, placeholder);
     57     }
     58     if (partials) {
     59       args = composeArgs(args, partials, holders, isCurried);
     60     }
     61     if (partialsRight) {
     62       args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
     63     }
     64     length -= holdersCount;
     65     if (isCurried && length < arity) {
     66       var newHolders = replaceHolders(args, placeholder);
     67       return createRecurry(
     68         func, bitmask, createHybrid, wrapper.placeholder, thisArg,
     69         args, newHolders, argPos, ary, arity - length
     70       );
     71     }
     72     var thisBinding = isBind ? thisArg : this,
     73         fn = isBindKey ? thisBinding[func] : func;
     74 
     75     length = args.length;
     76     if (argPos) {
     77       args = reorder(args, argPos);
     78     } else if (isFlip && length > 1) {
     79       args.reverse();
     80     }
     81     if (isAry && ary < length) {
     82       args.length = ary;
     83     }
     84     if (this && this !== root && this instanceof wrapper) {
     85       fn = Ctor || createCtor(fn);
     86     }
     87     return fn.apply(thisBinding, args);
     88   }
     89   return wrapper;
     90 }
     91 
     92 module.exports = createHybrid;