// Licensed Materials - Property of IBM
//
// IBM Watson Analytics
//
// (C) Copyright IBM Corp. 2015
//
// US Government Users Restricted Rights - Use, duplication or
// disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
module.exports = ( function( ObjectPolyfill, EntryStore )
{
"use strict";
// Putting this in a var allows uglify to minify the code much more
var SET_SIZE = !( ( __ES__ >= 5 ) || ObjectPolyfill.propertyGetSetSupport );
/**
* @classdesc Iterator for the Map polyfill.
* @class module:barejs/polyfill.Map~MapIterator
* @extends module:barejs/polyfill.EntryStore.Iterator
*/
function MapIterator( _kind, _store )
{
EntryStore.Iterator.call( this, _kind, _store );
}
MapIterator.prototype = Object.create( EntryStore.Iterator.prototype,
/** @lends module:barejs/polyfill.Map~MapIterator */
{
constructor: { writable: true, value: MapIterator }
} );
/**
* @classdesc Mimics the implementation of a native {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map Map}.
* Has an O(n) lookup time for non String or Number keys, so cannot compete with a native Map (Which is supposed to have an O(1) lookup time).
* @class module:barejs/polyfill.Map
*/
function Map()
{
ObjectPolyfill.defineProperty( this, "_store", { value: new EntryStore( arguments[0], true ) } );
/*istanbul ignore if: NodeJS has property support*/
if ( SET_SIZE )
this.size = this._store.size;
}
ObjectPolyfill.defineProperties( Map.prototype,
/** @lends module:barejs/polyfill.Map# */
{
_store: { value: null },
/**
* The size of the Map, which represents the number of entries currently in the Map.
* @member {number}
* @readonly
*/
size: ( SET_SIZE ?
/*istanbul ignore next*/ { writable: true, value: null } :
{ "get": function size(){ return this._store && this._store.size; } } ),
/**
* Set a value for the specified key in the Map.
* @function
* @param _key The object to use as key.
* @param _value The value to add.
* @returns {module:barejs/polyfill.Map} The Map (for chaining)
*/
"set": { value: function set( _key, _value )
{
this._store.set( _key, _value );
/*istanbul ignore if: NodeJS has property support*/
if ( SET_SIZE )
this.size = this._store.size;
return this;
} },
/**
* Get the value for the specified key
* @function
* @param {object} _key The object to use as key.
* @returns The value, or undefined if the key is not known.
*/
"get": { value: function get( _key )
{
var entry = this._store.entries[this._store.indexOf( _key )];
return entry && entry[1];
} },
/**
* Check if the Map has an entry for the specified key
* @function
* @param {object} _key The object to use as key.
* @returns {boolean} True if there is an entry for the key, false otherwise
*/
has: { value: function has( _key )
{
return this._store.indexOf( _key ) >= 0;
} },
/**
* Remove the value for the specified key
* @function
* @param {object} _key The object to use as key.
* @returns {boolean} True if the entry was deleted, false otherwise
*/
"delete": { value: function _delete( _key )
{
var removed = this._store.remove( _key );
/*istanbul ignore if: NodeJS has property support*/
if ( SET_SIZE )
this.size = this._store.size;
return removed;
} },
clear: { value: function clear()
{
this._store.clear();
/*istanbul ignore if: NodeJS has property support*/
if ( SET_SIZE )
this.size = this._store.size;
} },
/**
* Iterate the Map
* @function
* @param {function} _callback The callback function.
* @param [_thisArg] Optional: context to call the callback in.
*/
forEach: { value: function forEach( _callback/*, _thisArg*/ )
{
this._store.forEach( this, _callback, arguments[1] );
} },
/**
* Get a key iterator
* @function
* @returns {module:barejs/polyfill.Map~MapIterator} A key iterator
*/
keys: { value: function keys()
{
return new MapIterator( "key", this._store );
} },
/**
* Get a value iterator
* @function
* @returns {module:barejs/polyfill.Map~MapIterator} A value iterator
*/
values: { value: function values()
{
return new MapIterator( "value", this._store );
} },
/**
* Get an entry iterator
* @function
* @returns {module:barejs/polyfill.Map~MapIterator} A entry iterator
*/
entries: { value: function entries()
{
return new MapIterator( "entry", this._store );
} }
} );
ObjectPolyfill.setIterator( Map.prototype, Map.prototype.entries );
return Map;
}( require( "./Object" ), require( "./EntryStore" ) ) );