1 // =================================
  2 // Copyright (c) 2024 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Concepts;
  8 using System.IO;
  9 
 10 namespace System.Collections
 11 {
 12     public class HashMap<KTH = Hasher<K>C = EqualTo<K>>
 13         where K is Semiregular and T is Semiregular and HashFunction<HK> and C is Relation and C.Domain is K
 14     {
 15         public typedef K KeyType;
 16         public typedef T MappedType;
 17         public typedef Pair<KeyTypeMappedType> ValueType;
 18         public typedef H HashFun;
 19         public typedef C Compare;
 20         public typedef TableType.ConstIterator ConstIterator;
 21         public typedef TableType.Iterator Iterator;
 22         private typedef HashMap<KeyTypeMappedTypeHashFunCompare> Self;
 23         private typedef Hashtable<KeyTypeValueTypeSelectFirst<KeyTypeMappedType>HashFunCompare> TableType;
 24 
 25         public inline Iterator Begin()
 26         {
 27             return table.Begin();
 28         }
 29         public inline ConstIterator Begin() const
 30         {
 31             return table.CBegin();
 32         }
 33         public inline ConstIterator CBegin() const
 34         {
 35             return table.CBegin();
 36         }
 37         public inline Iterator End()
 38         {
 39             return table.End();
 40         }
 41         public inline ConstIterator End() const
 42         {
 43             return table.CEnd();
 44         }
 45         public inline ConstIterator CEnd() const
 46         {
 47             return table.CEnd();
 48         }
 49         public inline long Count() const
 50         {
 51             return table.Count();
 52         }
 53         public inline bool IsEmpty() const
 54         {
 55             return table.IsEmpty();
 56         }
 57         public inline void Clear()
 58         {
 59             table.Clear();
 60         }
 61         public inline Iterator Find(const KeyType& key)
 62         {
 63             return table.Find(key);
 64         }
 65         public inline ConstIterator Find(const KeyType& key) const
 66         {
 67             return table.CFind(key);
 68         }
 69         public inline ConstIterator CFind(const KeyType& key) const
 70         {
 71             return table.CFind(key);
 72         }
 73         public inline MappedType& operator[](const KeyType& key)
 74         {
 75             KeyType keyType(key);
 76             Pair<Iteratorbool> ib = Insert(ValueType(Rvalue(keyType)Rvalue(MappedType())));
 77             Iterator i = ib.first;
 78             return i->second;
 79         }
 80         public inline Pair<Iteratorbool> Insert(const ValueType& value)
 81         {
 82             return table.Insert(value);
 83         }
 84         public inline Pair<Iteratorbool> Insert(ValueType&& value)
 85         {
 86             return table.Insert(Rvalue(value));
 87         }
 88         public inline void Remove(const KeyType& key)
 89         {
 90             table.Remove(key);
 91         }
 92         public inline void Remove(Iterator pos)
 93         {
 94             table.Remove(pos);
 95         }
 96         private TableType table;
 97     }
 98 
 99     public bool operator==<KTHC>(const HashMap<KTHC>& leftconst HashMap<KTHC>& right)
100         where K is Semiregular and T is Semiregular and HashFunction<HK> and C is Relation and C.Domain is K
101     {
102         if (left.Count() != right.Count()) return false;
103         for (const Pair<KT>& p : left)
104         {
105             auto i = right.CFind(p.first);
106             if (i == right.CEnd()) return false;
107             if (i->second != p.second) return false;
108         }
109         return true;
110     }
111 
112     [system_default]
113     public TextWriter& operator<<<KTHC>(TextWriter& writerconst HashMap<KTHC>& hashMap)
114     {
115         if (writer.Error()) return writer;
116         writer << "{";
117         bool first = true;
118         for (const Pair<KT>& element : hashMap)
119         {
120             if (first)
121             {
122                 first = false;
123             }
124             else
125             {
126                 writer << ", ";
127             }
128             writer << element;
129         }
130         writer << "}";
131         return writer;
132     }