Version 1
[yaffs-website] / node_modules / core-js / modules / _collection-strong.js
1 'use strict';
2 var dP          = require('./_object-dp').f
3   , create      = require('./_object-create')
4   , redefineAll = require('./_redefine-all')
5   , ctx         = require('./_ctx')
6   , anInstance  = require('./_an-instance')
7   , defined     = require('./_defined')
8   , forOf       = require('./_for-of')
9   , $iterDefine = require('./_iter-define')
10   , step        = require('./_iter-step')
11   , setSpecies  = require('./_set-species')
12   , DESCRIPTORS = require('./_descriptors')
13   , fastKey     = require('./_meta').fastKey
14   , SIZE        = DESCRIPTORS ? '_s' : 'size';
15
16 var getEntry = function(that, key){
17   // fast case
18   var index = fastKey(key), entry;
19   if(index !== 'F')return that._i[index];
20   // frozen object case
21   for(entry = that._f; entry; entry = entry.n){
22     if(entry.k == key)return entry;
23   }
24 };
25
26 module.exports = {
27   getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
28     var C = wrapper(function(that, iterable){
29       anInstance(that, C, NAME, '_i');
30       that._i = create(null); // index
31       that._f = undefined;    // first entry
32       that._l = undefined;    // last entry
33       that[SIZE] = 0;         // size
34       if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
35     });
36     redefineAll(C.prototype, {
37       // 23.1.3.1 Map.prototype.clear()
38       // 23.2.3.2 Set.prototype.clear()
39       clear: function clear(){
40         for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){
41           entry.r = true;
42           if(entry.p)entry.p = entry.p.n = undefined;
43           delete data[entry.i];
44         }
45         that._f = that._l = undefined;
46         that[SIZE] = 0;
47       },
48       // 23.1.3.3 Map.prototype.delete(key)
49       // 23.2.3.4 Set.prototype.delete(value)
50       'delete': function(key){
51         var that  = this
52           , entry = getEntry(that, key);
53         if(entry){
54           var next = entry.n
55             , prev = entry.p;
56           delete that._i[entry.i];
57           entry.r = true;
58           if(prev)prev.n = next;
59           if(next)next.p = prev;
60           if(that._f == entry)that._f = next;
61           if(that._l == entry)that._l = prev;
62           that[SIZE]--;
63         } return !!entry;
64       },
65       // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
66       // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
67       forEach: function forEach(callbackfn /*, that = undefined */){
68         anInstance(this, C, 'forEach');
69         var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3)
70           , entry;
71         while(entry = entry ? entry.n : this._f){
72           f(entry.v, entry.k, this);
73           // revert to the last existing entry
74           while(entry && entry.r)entry = entry.p;
75         }
76       },
77       // 23.1.3.7 Map.prototype.has(key)
78       // 23.2.3.7 Set.prototype.has(value)
79       has: function has(key){
80         return !!getEntry(this, key);
81       }
82     });
83     if(DESCRIPTORS)dP(C.prototype, 'size', {
84       get: function(){
85         return defined(this[SIZE]);
86       }
87     });
88     return C;
89   },
90   def: function(that, key, value){
91     var entry = getEntry(that, key)
92       , prev, index;
93     // change existing entry
94     if(entry){
95       entry.v = value;
96     // create new entry
97     } else {
98       that._l = entry = {
99         i: index = fastKey(key, true), // <- index
100         k: key,                        // <- key
101         v: value,                      // <- value
102         p: prev = that._l,             // <- previous entry
103         n: undefined,                  // <- next entry
104         r: false                       // <- removed
105       };
106       if(!that._f)that._f = entry;
107       if(prev)prev.n = entry;
108       that[SIZE]++;
109       // add to index
110       if(index !== 'F')that._i[index] = entry;
111     } return that;
112   },
113   getEntry: getEntry,
114   setStrong: function(C, NAME, IS_MAP){
115     // add .keys, .values, .entries, [@@iterator]
116     // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
117     $iterDefine(C, NAME, function(iterated, kind){
118       this._t = iterated;  // target
119       this._k = kind;      // kind
120       this._l = undefined; // previous
121     }, function(){
122       var that  = this
123         , kind  = that._k
124         , entry = that._l;
125       // revert to the last existing entry
126       while(entry && entry.r)entry = entry.p;
127       // get next entry
128       if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){
129         // or finish the iteration
130         that._t = undefined;
131         return step(1);
132       }
133       // return step by kind
134       if(kind == 'keys'  )return step(0, entry.k);
135       if(kind == 'values')return step(0, entry.v);
136       return step(0, [entry.k, entry.v]);
137     }, IS_MAP ? 'entries' : 'values' , !IS_MAP, true);
138
139     // add [@@species], 23.1.2.2, 23.2.2.2
140     setSpecies(NAME);
141   }
142 };