00001 var composeArgs = require('./_composeArgs'), 00002 composeArgsRight = require('./_composeArgsRight'), 00003 countHolders = require('./_countHolders'), 00004 createCtor = require('./_createCtor'), 00005 createRecurry = require('./_createRecurry'), 00006 getHolder = require('./_getHolder'), 00007 reorder = require('./_reorder'), 00008 replaceHolders = require('./_replaceHolders'), 00009 root = require('./_root'); 00010 00012 var WRAP_BIND_FLAG = 1, 00013 WRAP_BIND_KEY_FLAG = 2, 00014 WRAP_CURRY_FLAG = 8, 00015 WRAP_CURRY_RIGHT_FLAG = 16, 00016 WRAP_ARY_FLAG = 128, 00017 WRAP_FLIP_FLAG = 512; 00018 00038 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { 00039 var isAry = bitmask & WRAP_ARY_FLAG, 00040 isBind = bitmask & WRAP_BIND_FLAG, 00041 isBindKey = bitmask & WRAP_BIND_KEY_FLAG, 00042 isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), 00043 isFlip = bitmask & WRAP_FLIP_FLAG, 00044 Ctor = isBindKey ? undefined : createCtor(func); 00045 00046 function wrapper() { 00047 var length = arguments.length, 00048 args = Array(length), 00049 index = length; 00050 00051 while (index--) { 00052 args[index] = arguments[index]; 00053 } 00054 if (isCurried) { 00055 var placeholder = getHolder(wrapper), 00056 holdersCount = countHolders(args, placeholder); 00057 } 00058 if (partials) { 00059 args = composeArgs(args, partials, holders, isCurried); 00060 } 00061 if (partialsRight) { 00062 args = composeArgsRight(args, partialsRight, holdersRight, isCurried); 00063 } 00064 length -= holdersCount; 00065 if (isCurried && length < arity) { 00066 var newHolders = replaceHolders(args, placeholder); 00067 return createRecurry( 00068 func, bitmask, createHybrid, wrapper.placeholder, thisArg, 00069 args, newHolders, argPos, ary, arity - length 00070 ); 00071 } 00072 var thisBinding = isBind ? thisArg : this, 00073 fn = isBindKey ? thisBinding[func] : func; 00074 00075 length = args.length; 00076 if (argPos) { 00077 args = reorder(args, argPos); 00078 } else if (isFlip && length > 1) { 00079 args.reverse(); 00080 } 00081 if (isAry && ary < length) { 00082 args.length = ary; 00083 } 00084 if (this && this !== root && this instanceof wrapper) { 00085 fn = Ctor || createCtor(fn); 00086 } 00087 return fn.apply(thisBinding, args); 00088 } 00089 return wrapper; 00090 } 00091 00092 module.exports = createHybrid;