Initial commit
[yaffs-website] / node_modules / pseudomap / pseudomap.js
1 var hasOwnProperty = Object.prototype.hasOwnProperty
2
3 module.exports = PseudoMap
4
5 function PseudoMap (set) {
6   if (!(this instanceof PseudoMap)) // whyyyyyyy
7     throw new TypeError("Constructor PseudoMap requires 'new'")
8
9   this.clear()
10
11   if (set) {
12     if ((set instanceof PseudoMap) ||
13         (typeof Map === 'function' && set instanceof Map))
14       set.forEach(function (value, key) {
15         this.set(key, value)
16       }, this)
17     else if (Array.isArray(set))
18       set.forEach(function (kv) {
19         this.set(kv[0], kv[1])
20       }, this)
21     else
22       throw new TypeError('invalid argument')
23   }
24 }
25
26 PseudoMap.prototype.forEach = function (fn, thisp) {
27   thisp = thisp || this
28   Object.keys(this._data).forEach(function (k) {
29     if (k !== 'size')
30       fn.call(thisp, this._data[k].value, this._data[k].key)
31   }, this)
32 }
33
34 PseudoMap.prototype.has = function (k) {
35   return !!find(this._data, k)
36 }
37
38 PseudoMap.prototype.get = function (k) {
39   var res = find(this._data, k)
40   return res && res.value
41 }
42
43 PseudoMap.prototype.set = function (k, v) {
44   set(this._data, k, v)
45 }
46
47 PseudoMap.prototype.delete = function (k) {
48   var res = find(this._data, k)
49   if (res) {
50     delete this._data[res._index]
51     this._data.size--
52   }
53 }
54
55 PseudoMap.prototype.clear = function () {
56   var data = Object.create(null)
57   data.size = 0
58
59   Object.defineProperty(this, '_data', {
60     value: data,
61     enumerable: false,
62     configurable: true,
63     writable: false
64   })
65 }
66
67 Object.defineProperty(PseudoMap.prototype, 'size', {
68   get: function () {
69     return this._data.size
70   },
71   set: function (n) {},
72   enumerable: true,
73   configurable: true
74 })
75
76 PseudoMap.prototype.values =
77 PseudoMap.prototype.keys =
78 PseudoMap.prototype.entries = function () {
79   throw new Error('iterators are not implemented in this version')
80 }
81
82 // Either identical, or both NaN
83 function same (a, b) {
84   return a === b || a !== a && b !== b
85 }
86
87 function Entry (k, v, i) {
88   this.key = k
89   this.value = v
90   this._index = i
91 }
92
93 function find (data, k) {
94   for (var i = 0, s = '_' + k, key = s;
95        hasOwnProperty.call(data, key);
96        key = s + i++) {
97     if (same(data[key].key, k))
98       return data[key]
99   }
100 }
101
102 function set (data, k, v) {
103   for (var i = 0, s = '_' + k, key = s;
104        hasOwnProperty.call(data, key);
105        key = s + i++) {
106     if (same(data[key].key, k)) {
107       data[key].value = v
108       return
109     }
110   }
111   data.size++
112   data[key] = new Entry(k, v, key)
113 }