1 // =================================
  2 // Copyright (c) 2021 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 nothrow Iterator Begin()
 26         {
 27             return table.Begin();
 28         }
 29         public inline nothrow ConstIterator Begin() const
 30         {
 31             return table.CBegin();
 32         }
 33         public inline nothrow ConstIterator CBegin() const
 34         {
 35             return table.CBegin();
 36         }
 37         public inline nothrow Iterator End()
 38         {
 39             return table.End();
 40         }
 41         public inline nothrow ConstIterator End() const
 42         {
 43             return table.CEnd();
 44         }
 45         public inline nothrow ConstIterator CEnd() const
 46         {
 47             return table.CEnd();
 48         }
 49         public inline nothrow long Count() const
 50         {
 51             return table.Count();
 52         }
 53         public inline nothrow bool IsEmpty() const
 54         {
 55             return table.IsEmpty();
 56         }
 57         public inline nothrow void Clear()
 58         {
 59             table.Clear();
 60         }
 61         public inline nothrow Iterator Find(const KeyType& key)
 62         {
 63             return table.Find(key);
 64         }
 65         public inline nothrow ConstIterator Find(const KeyType& key) const
 66         {
 67             return table.CFind(key);
 68         }
 69         public inline nothrow ConstIterator CFind(const KeyType& key) const
 70         {
 71             return table.CFind(key);
 72         }
 73         public inline MappedType& operator[](const KeyType& key)
 74         {
 75             Pair<Iteratorbool> ib = Insert(ValueType(keyMappedType()));
 76             Iterator i = ib.first;
 77             return i->second;
 78         }
 79         public inline Pair<Iteratorbool> Insert(const ValueType& value)
 80         {
 81             return table.Insert(value);
 82         }
 83         public inline nothrow void Remove(const KeyType& key)
 84         {
 85             table.Remove(key);
 86         }
 87         public inline nothrow void Remove(Iterator pos)
 88         {
 89             table.Remove(pos);
 90         }
 91         private TableType table;
 92     }
 93 
 94     public nothrow bool operator==<KTHC>(const HashMap<KTHC>& leftconst HashMap<KTHC>& right)
 95         where K is Semiregular and T is Semiregular and HashFunction<HK> and C is Relation and C.Domain is K
 96     {
 97         if (left.Count() != right.Count()) return false;
 98         for (const Pair<KT>& p : left)
 99         {
100             HashMap<KTHC>.ConstIterator i = right.CFind(p.first);
101             if (i == right.CEnd()) return false;
102             if (i->second != p.second) return false;
103         }
104         return true;
105     }
106 
107     [system_default="true"]
108     public TextWriter& operator<<<KTHC>(TextWriter& writerconst HashMap<KTHC>& hashMap)
109     {
110         writer << "{";
111         bool first = true;
112         for (const Pair<KT>& element : hashMap)
113         {
114             if (first)
115             {
116                 first = false;
117             }
118             else
119             {
120                 writer << ", ";
121             }
122             writer << element;
123         }
124         writer << "}";
125         return writer;
126     }        
127 }