import { Collection , MutationContext , PreferredContext , asSubordinateContext , commit , hashIterator , immutable , isDefined , isMutable , isObject , isUndefined , selectContext , unwrap } from '@collectable/core' ; import { HashMap , clone , empty , isEqual , keys , set as _set , size , updateMap } from '@collectable/map' ; import { iterate } from './iterate' ; export class HashSetStructure < T > implements Collection < T , T [ ] > { internal constructor ( mctx , public _map ) { this [ '@@mctx' ] = mctx ; } internal get '@@size' ( ) { return this . _map [ '@@size' ] ; } internal readonly '@@mctx' : MutationContext ; internal get '@@is-collection' ( ) : true { return true ; } internal '@@clone' ( mctx ) { return new HashSetStructure < T > ( mctx , clone ( this . _map , asSubordinateContext ( mctx ) ) ) ; } internal '@@equals' ( other ) { return isEqual ( this . _map , other . _map ) ; } internal '@@hash' ( ) { return hashIterator ( iterate ( this ) ) ; } internal '@@unwrap' ( ) { return unwrap ( this ) ; } internal '@@unwrapInto' ( target ) { var it = keys ( this . _map ) ; var current ; var i = 0 ; while ( ! ( current = it . next ( ) ) . done ) { target [ i ++ ] = unwrap < T > ( current . value ) ; } return target ; } internal '@@createUnwrapTarget' ( ) { return new Array < T > ( size ( this . _map ) ) ; } [ Symbol . iterator ] ( ) { return iterate < T > ( this ) ; } } export function isHashSet < T > ( arg ) { return isObject ( arg ) && arg instanceof HashSetStructure ; } export function cloneHashSet < T > ( set , mutability ? ) { if ( isUndefined ( mutability ) ) mutability = isMutable ( set ) ; const mctx = selectContext ( mutability ) ; const sctx = asSubordinateContext ( mctx ) ; return new HashSetStructure ( mctx , clone ( set . _map , sctx ) ) ; } export function createSet < T > ( values ? ) { var map = empty < T , null > ( true ) ; if ( isDefined ( values ) ) { map = updateMap ( function ( map ) { if ( Array . isArray ( values ) ) { for ( var i = 0 ; i < values . length ; i ++ ) { _set ( values [ i ] , null , map ) ; } } else { var it = values [ Symbol . iterator ] ( ) ; var current ; while ( ! ( current = it . next ( ) ) . done ) { _set ( current . value , null , map ) ; } } } , map ) ; } return new HashSetStructure < T > ( immutable ( ) , commit ( map ) ) ; } export function extractMap < T > ( set ) { return set . _map ; } export function emptySet < T > ( mutability ? ) { if ( mutability ) { var mctx = selectContext ( mutability ) ; return new HashSetStructure < T > ( mctx , empty < T , null > ( asSubordinateContext ( mctx ) ) ) ; } return isDefined ( _empty ) ? _empty : ( _empty = createSet < any > ( ) ) ; } var _empty ;