private static bool TryInsert <K, V>(UnsafeSortedDictionary *map, K key, V value, MapInsertionBehaviour behaviour)
            where K : unmanaged, IComparable <K>
            where V : unmanaged
        {
            UDebug.Assert(map != null);
            UDebug.Assert(typeof(K).TypeHandle.Value == map->_typeHandleKey);
            UDebug.Assert(typeof(V).TypeHandle.Value == map->_typeHandleValue);

            var entry = UnsafeOrderedCollection.Find <K>(&map->_collection, key);

            // Entry is already present
            if (entry != null)
            {
                if (behaviour == MapInsertionBehaviour.Overwrite)
                {
                    *GetValue <V>(map->_valueOffset, entry) = value;
                    return(true);
                }

                if (behaviour == MapInsertionBehaviour.ThrowIfExists)
                {
                    throw new ArgumentException(string.Format(ThrowHelper.Arg_AddingDuplicateWithKey, key));
                }

                return(false);
            }
            // Create new entry
            else
            {
                entry = UnsafeOrderedCollection.Insert <K>(&map->_collection, key);
                *GetValue <V>(map->_valueOffset, entry) = value;
                return(true);
            }
        }
        public static void CopyTo <K, V>(UnsafeSortedDictionary *map, KeyValuePair <K, V>[] destination, int destinationIndex)
            where K : unmanaged, IComparable <K>
            where V : unmanaged
        {
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            if (GetCount(map) + (uint)destinationIndex > destination.Length)
            {
                throw new ArgumentOutOfRangeException(ThrowHelper.Arg_ArrayPlusOffTooSmall);
            }

            UDebug.Assert(map != null);
            UDebug.Assert(typeof(K).TypeHandle.Value == map->_typeHandleKey);
            UDebug.Assert(typeof(V).TypeHandle.Value == map->_typeHandleValue);
            UDebug.Assert(destination != null);
            UDebug.Assert(destination.Length >= GetCount(map) + destinationIndex);

            var enumerator = GetEnumerator <K, V>(map);

            int i = 0;

            while (enumerator.MoveNext())
            {
                destination[destinationIndex + i] = enumerator.Current;
                i++;
            }
        }
        public static bool ContainsKey <K>(UnsafeSortedDictionary *map, K key)
            where K : unmanaged, IComparable <K>
        {
            UDebug.Assert(map != null);
            UDebug.Assert(typeof(K).TypeHandle.Value == map->_typeHandleKey);

            return(UnsafeOrderedCollection.Find <K>(&map->_collection, key) != null);
        }
        public static KeyEnumerator <K> GetKeyEnumerator <K>(UnsafeSortedDictionary *map)
            where K : unmanaged, IComparable <K>
        {
            UDebug.Assert(map != null);
            UDebug.Assert(typeof(K).TypeHandle.Value == map->_typeHandleKey);

            return(new KeyEnumerator <K>(map));
        }
        public static ValueEnumerator <V> GetValueEnumerator <V>(UnsafeSortedDictionary *map)
            where V : unmanaged
        {
            UDebug.Assert(map != null);
            UDebug.Assert(typeof(V).TypeHandle.Value == map->_typeHandleValue);

            return(new ValueEnumerator <V>(map));
        }
        public static V Get <K, V>(UnsafeSortedDictionary *map, K key)
            where K : unmanaged, IComparable <K>
            where V : unmanaged
        {
            var entry = UnsafeOrderedCollection.Find(&map->_collection, key);

            if (entry == null)
            {
                throw new ArgumentException(string.Format(ThrowHelper.Arg_KeyNotFoundWithKey, key));
            }

            return(*GetValue <V>(map->_valueOffset, entry));
        }
        public static bool ContainsValue <V>(UnsafeSortedDictionary *map, V value)
            where V : unmanaged, IEquatable <V>
        {
            var iterator = new ValueEnumerator <V>(map);

            while (iterator.MoveNext())
            {
                if (value.Equals(iterator.Current))
                {
                    return(true);
                }
            }

            return(false);
        }
        public static bool TryGetValue <K, V>(UnsafeSortedDictionary *map, K key, out V val)
            where K : unmanaged, IComparable <K>
            where V : unmanaged
        {
            var entry = UnsafeOrderedCollection.Find <K>(&map->_collection, key);

            if (entry != null)
            {
                val = *GetValue <V>(map->_valueOffset, entry);
                return(true);
            }

            val = default;
            return(false);
        }
        public static void Free(UnsafeSortedDictionary *map)
        {
            if (map == null)
            {
                return;
            }

            if (map->_collection.Entries.Dynamic == 1)
            {
                UnsafeBuffer.Free(&map->_collection.Entries);
            }

            // clear memory
            *map = default;

            // free it
            Memory.Free(map);
        }
 public ValueEnumerator(UnsafeSortedDictionary *dictionary)
 {
     _valueOffset = dictionary->_valueOffset;
     _iterator    = new UnsafeOrderedCollection.Enumerator(&dictionary->_collection);
 }
        public static int GetCount(UnsafeSortedDictionary *map)
        {
            UDebug.Assert(map != null);

            return(UnsafeOrderedCollection.GetCount(&map->_collection));
        }
        public static bool IsFixedSize(UnsafeSortedDictionary *map)
        {
            UDebug.Assert(map != null);

            return(map->_collection.Entries.Dynamic == 0);
        }
 public KeyEnumerator(UnsafeSortedDictionary *dictionary)
 {
     _keyOffset = dictionary->_collection.KeyOffset;
     _iterator  = new UnsafeOrderedCollection.Enumerator(&dictionary->_collection);
 }
 public static void Add <K, V>(UnsafeSortedDictionary *map, K key, V value)
     where K : unmanaged, IComparable <K>
     where V : unmanaged
 {
     TryInsert(map, key, value, MapInsertionBehaviour.ThrowIfExists);
 }
 public static bool TryAdd <K, V>(UnsafeSortedDictionary *map, K key, V value)
     where K : unmanaged, IComparable <K>
     where V : unmanaged
 {
     return(TryInsert(map, key, value, MapInsertionBehaviour.None));
 }
        public static void Clear(UnsafeSortedDictionary *map)
        {
            UDebug.Assert(map != null);

            UnsafeOrderedCollection.Clear(&map->_collection);
        }
 public static void Set <K, V>(UnsafeSortedDictionary *map, K key, V value)
     where K : unmanaged, IComparable <K>
     where V : unmanaged
 {
     TryInsert(map, key, value, MapInsertionBehaviour.Overwrite);
 }
        public static int GetCapacity(UnsafeSortedDictionary *map)
        {
            UDebug.Assert(map != null);

            return(map->_collection.Entries.Length);
        }