// 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 Set polyfill.
* @class module:barejs/polyfill.Set~SetIterator
* @extends module:barejs/polyfill.EntryStore.Iterator
*/
function SetIterator( _kind, _store )
{
EntryStore.Iterator.call( this, _kind, _store );
}
SetIterator.prototype = Object.create( EntryStore.Iterator.prototype,
/** @lends module:barejs/polyfill.Set~SetIterator# */
{
constructor: { writable : true, value : SetIterator }
} );
/**
* @classdesc Mimics the implementation of a native {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set Set}.
* 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.Set
*/
function Set()
{
ObjectPolyfill.defineProperty( this, "_store", { value: new EntryStore( arguments[0], false ) } );
/*istanbul ignore if: NodeJS has property support*/
if ( SET_SIZE )
this.size = this._store.size;
}
ObjectPolyfill.defineProperties( Set.prototype,
/** @lends module:barejs/polyfill.Set# */
{
_store: { value: null },
/**
* The size of the Set, 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; } } ),
/**
* Adds a value to a Set object.
* @function
* @param _value The value to add.
* @returns {module:barejs/polyfill.Set} The Set (for chaining)
*/
add: { value: function add( _value )
{
this._store.set( _value, _value );
/*istanbul ignore if: NodeJS has property support*/
if ( SET_SIZE )
this.size = this._store.size;
return this;
} },
/**
* Check if the Set has a specified value.
* @function
* @param {object} _value The value to check for.
* @returns {boolean} True if there is an entry for the value, false otherwise
*/
has: { value: function has( _value )
{
return this._store.indexOf( _value ) >= 0;
} },
/**
* Remove a value from the Set
* @function
* @param {object} _value The value to remove.
* @returns {boolean} True if the value was deleted, false otherwise.
*/
"delete": { value: function _delete( _value )
{
var removed = this._store.remove( _value );
/*istanbul ignore if: NodeJS has property support*/
if ( SET_SIZE )
this.size = this._store.size;
return removed;
} },
/**
* Clear the Set.
* @function
*/
clear: { value: function clear()
{
this._store.clear();
/*istanbul ignore if: NodeJS has property support*/
if ( SET_SIZE )
this.size = this._store.size;
} },
/**
* Iterate the Set
* @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.Set~SetIterator} A key iterator
*/
keys: { value: function keys()
{
return new SetIterator( "key", this._store );
} },
/**
* Get a value iterator
* @function
* @returns {module:barejs/polyfill.Set~SetIterator} A value iterator
*/
values: { value: function values()
{
return new SetIterator( "value", this._store );
} },
/**
* Get an entry iterator
* @function
* @returns {module:barejs/polyfill.Set~SetIterator} A entry iterator
*/
entries: { value: function entries()
{
return new SetIterator( "entry", this._store );
} }
} );
ObjectPolyfill.setIterator( Set.prototype, Set.prototype.values );
return Set;
}( require( "./Object" ), require( "./EntryStore" ) ) );