1 // =================================
  2 // Copyright (c) 2022 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.IO;
  8 using System.Concepts;
  9 
 10 namespace System.Collections
 11 {
 12     public class Map<KeyValueKeyCompare = Less<Key>>
 13         where Key is Semiregular and Value is Semiregular and KeyCompare is Relation and KeyCompare.Domain is Key
 14     {
 15         public typedef Key KeyType;
 16         public typedef Value MappedType;
 17         public typedef KeyCompare Compare;
 18         public typedef Pair<KeyTypeMappedType> ValueType;
 19         public typedef TreeType.ConstIterator ConstIterator;
 20         public typedef TreeType.Iterator Iterator;
 21         private typedef Map<KeyTypeMappedTypeKeyCompare> Self;
 22         private typedef RedBlackTree<KeyTypeValueTypeSelectFirst<KeyTypeMappedType>KeyCompare> TreeType;
 23 
 24         public inline nothrow Iterator Begin()
 25         {
 26             return tree.Begin();
 27         }
 28         public inline nothrow ConstIterator Begin() const
 29         {
 30             return tree.CBegin();
 31         }
 32         public inline nothrow ConstIterator CBegin() const
 33         {
 34             return tree.CBegin();
 35         }
 36         public inline nothrow Iterator End()
 37         {
 38             return tree.End();
 39         }
 40         public inline nothrow ConstIterator End() const
 41         {
 42             return tree.CEnd();
 43         }
 44         public inline nothrow ConstIterator CEnd() const
 45         {
 46             return tree.CEnd();
 47         }
 48         public inline nothrow long Count() const
 49         {
 50             return tree.Count();
 51         }
 52         public inline nothrow bool IsEmpty() const
 53         {
 54             return tree.IsEmpty();
 55         }
 56         public inline nothrow void Clear()
 57         {
 58             tree.Clear();
 59         }
 60         public inline nothrow Iterator Find(const KeyType& key)
 61         {
 62             return tree.Find(key);
 63         }
 64         public inline nothrow ConstIterator Find(const KeyType& key) const
 65         {
 66             return tree.CFind(key);
 67         }
 68         public inline nothrow ConstIterator CFind(const KeyType& key) const
 69         {
 70             return tree.CFind(key);
 71         }
 72         public inline MappedType& operator[](const KeyType& key)
 73         {
 74             ValueType valueType(keyMappedType());
 75             Pair<Iteratorbool> ib = Insert(valueType);
 76             Iterator i = ib.first;
 77             return i->second;
 78         }
 79         public inline Pair<Iteratorbool> Insert(const ValueType& value)
 80             where ValueType is Copyable
 81         {
 82             return tree.Insert(value);
 83         }
 84         public inline nothrow bool Remove(const KeyType& key)
 85         {
 86             return tree.Remove(key);
 87         }
 88         public inline nothrow void Remove(Iterator pos)
 89         {
 90             tree.Remove(pos);
 91         }
 92         private TreeType tree;
 93     }
 94 
 95     public inline nothrow bool operator==<KeyValueKeyCompare>(const Map<KeyValueKeyCompare>& leftconst Map<KeyValueKeyCompare>& right)
 96         where Key is Regular and Value is Regular and KeyCompare is Relation and KeyCompare.Domain is Key
 97     {
 98         return left.Count() == right.Count() && Equal(left.CBegin()left.CEnd()right.CBegin()right.CEnd()EqualTo<Pair<KeyValue>>());
 99     }
100 
101     public inline nothrow bool operator<<KeyValueKeyCompare>(const Map<KeyValueKeyCompare>& leftconst Map<KeyValueKeyCompare>& right)
102         where Key is TotallyOrdered and Value is TotallyOrdered and KeyCompare is Relation and KeyCompare.Domain is Key
103     {
104         return LexicographicalCompare(left.CBegin()left.CEnd()right.CBegin()right.CEnd()Less<Pair<KeyValue>>());
105     }
106 
107     [system_default="true"]
108     public TextWriter& operator<<<KeyValueKeyCompare>(TextWriter& writerconst Map<KeyValueKeyCompare>& map)
109     {
110         writer << "{";
111         bool first = true;
112         for (const Pair<KeyValue>& element : map)
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 }