2 var global = require('./_global')
3 , $export = require('./_export')
4 , meta = require('./_meta')
5 , fails = require('./_fails')
6 , hide = require('./_hide')
7 , redefineAll = require('./_redefine-all')
8 , forOf = require('./_for-of')
9 , anInstance = require('./_an-instance')
10 , isObject = require('./_is-object')
11 , setToStringTag = require('./_set-to-string-tag')
12 , dP = require('./_object-dp').f
13 , each = require('./_array-methods')(0)
14 , DESCRIPTORS = require('./_descriptors');
16 module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){
17 var Base = global[NAME]
19 , ADDER = IS_MAP ? 'set' : 'add'
20 , proto = C && C.prototype
22 if(!DESCRIPTORS || typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){
23 new C().entries().next();
25 // create collection constructor
26 C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
27 redefineAll(C.prototype, methods);
30 C = wrapper(function(target, iterable){
31 anInstance(target, C, NAME, '_c');
33 if(iterable != undefined)forOf(iterable, IS_MAP, target[ADDER], target);
35 each('add,clear,delete,forEach,get,has,set,keys,values,entries,toJSON'.split(','),function(KEY){
36 var IS_ADDER = KEY == 'add' || KEY == 'set';
37 if(KEY in proto && !(IS_WEAK && KEY == 'clear'))hide(C.prototype, KEY, function(a, b){
38 anInstance(this, C, KEY);
39 if(!IS_ADDER && IS_WEAK && !isObject(a))return KEY == 'get' ? undefined : false;
40 var result = this._c[KEY](a === 0 ? 0 : a, b);
41 return IS_ADDER ? this : result;
44 if('size' in proto)dP(C.prototype, 'size', {
51 setToStringTag(C, NAME);
54 $export($export.G + $export.W + $export.F, O);
56 if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP);