// Copyright (c) 2026 The elk-go Authors.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0.
//
// SPDX-License-Identifier: EPL-2.0

package javacompat

// IdentityMap provides IdentityHashMap equality semantics for identity-bearing
// comparable keys. K should be a pointer or an arena handle, never a value
// object whose == operation represents structural equality. Iteration is made
// deterministic in first-insertion order; ELK does not rely on the unspecified
// table order of java.util.IdentityHashMap.
//
// The zero value is ready to use.
type IdentityMap[ comparable,  any] struct {
	values OrderedMap[, ]
}

func [ comparable,  any]() *IdentityMap[, ] {
	return &IdentityMap[, ]{}
}

func ( *IdentityMap[, ]) () int                     { return .values.Len() }
func ( *IdentityMap[, ]) () bool                { return .values.IsEmpty() }
func ( *IdentityMap[, ]) ( ) (, bool)          { return .values.Get() }
func ( *IdentityMap[, ]) ( ) bool       { return .values.ContainsKey() }
func ( *IdentityMap[, ]) ( ,  ) (, bool) { return .values.Put(, ) }
func ( *IdentityMap[, ]) ( ) (, bool)       { return .values.Remove() }
func ( *IdentityMap[, ]) ()                       { .values.Clear() }
func ( *IdentityMap[, ]) () []                    { return .values.Keys() }
func ( *IdentityMap[, ]) () []                  { return .values.Values() }
func ( *IdentityMap[, ]) ( func(, ) bool)  { .values.Range() }

// IdentitySet is IdentityMap's set counterpart. K should be a pointer or an
// arena handle so Go equality is object identity.
type IdentitySet[ comparable] struct {
	values OrderedSet[]
}

func [ comparable]() *IdentitySet[] { return &IdentitySet[]{} }

func ( *IdentitySet[]) () int                 { return .values.Len() }
func ( *IdentitySet[]) () bool            { return .values.IsEmpty() }
func ( *IdentitySet[]) ( ) bool         { return .values.Add() }
func ( *IdentitySet[]) ( ) bool    { return .values.Contains() }
func ( *IdentitySet[]) ( ) bool      { return .values.Remove() }
func ( *IdentitySet[]) ()                   { .values.Clear() }
func ( *IdentitySet[]) () []              { return .values.Values() }
func ( *IdentitySet[]) ( func() bool) { .values.Range() }