Created
January 20, 2020 11:22
-
-
Save janheinrichmerker/2a3a981b743c90f57f497f9db544bb45 to your computer and use it in GitHub Desktop.
Add-only Kotlin collections.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.webis.webisstud.thesis.reimer | |
/** | |
* A generic collection of elements that supports adding elements. | |
* | |
* @param E the type of elements contained in the collection. | |
* The mutable collection is invariant on its element type. | |
*/ | |
interface AddOnlyCollection<E> : Collection<E> { | |
/** | |
* Adds the specified element to the collection. | |
* | |
* @return `true` if the element has been added, | |
* `false` if the collection does not support duplicates | |
* and the element is already contained in the collection. | |
*/ | |
fun add(element: E): Boolean | |
/** | |
* Adds all of the elements of the specified collection to this collection. | |
* | |
* @return `true` if any of the specified elements was added to the collection, | |
* `false` if the collection was not modified. | |
*/ | |
fun addAll(elements: Collection<E>): Boolean | |
} | |
/** | |
* A generic ordered collection of elements that supports adding elements. | |
* @param E the type of elements contained in the list. The mutable list is invariant on its element type. | |
*/ | |
interface AddOnlyList<E> : AddOnlyCollection<E>, List<E> { | |
/** | |
* Adds the specified element to the end of this list. | |
* | |
* @return `true` because the list is always modified as the result of this operation. | |
*/ | |
override fun add(element: E): Boolean | |
/** | |
* Adds all of the elements of the specified collection to the end of this list. | |
* | |
* The elements are appended in the order they appear in the [elements] collection. | |
* | |
* @return `true` if the list was changed as the result of the operation. | |
*/ | |
override fun addAll(elements: Collection<E>): Boolean | |
/** | |
* Inserts all of the elements of the specified collection [elements] into this list at the specified [index]. | |
* | |
* @return `true` if the list was changed as the result of the operation. | |
*/ | |
fun addAll(index: Int, elements: Collection<E>): Boolean | |
/** | |
* Inserts an element into the list at the specified [index]. | |
*/ | |
fun add(index: Int, element: E): Unit | |
override fun listIterator(): AddOnlyListIterator<E> | |
override fun listIterator(index: Int): AddOnlyListIterator<E> | |
override fun subList(fromIndex: Int, toIndex: Int): AddOnlyList<E> | |
} | |
/** | |
* An iterator over a mutable collection that supports indexed access. Provides the ability | |
* to add, modify elements while iterating. | |
*/ | |
interface AddOnlyListIterator<T> : ListIterator<T>, Iterator<T> { | |
override fun next(): T | |
override fun hasNext(): Boolean | |
/** | |
* Adds the specified element [element] into the underlying collection immediately before the element that would be | |
* returned by [next], if any, and after the element that would be returned by [previous], if any. | |
* (If the collection contains no elements, the new element becomes the sole element in the collection.) | |
* The new element is inserted before the implicit cursor: a subsequent call to [next] would be unaffected, | |
* and a subsequent call to [previous] would return the new element. (This call increases by one the value \ | |
* that would be returned by a call to [nextIndex] or [previousIndex].) | |
*/ | |
fun add(element: T) | |
} | |
/** | |
* A generic unordered collection of elements that does not support duplicate elements, and supports | |
* adding elements. | |
* @param E the type of elements contained in the set. The mutable set is invariant on its element type. | |
*/ | |
interface AddOnlySet<E> : Set<E>, AddOnlyCollection<E> { | |
/** | |
* Adds the specified element to the set. | |
* | |
* @return `true` if the element has been added, `false` if the element is already contained in the set. | |
*/ | |
override fun add(element: E): Boolean | |
override fun addAll(elements: Collection<E>): Boolean | |
} | |
/** | |
* A modifiable collection that holds pairs of objects (keys and values) and supports efficiently retrieving | |
* the value corresponding to each key. Map keys are unique; the map holds only one value for each key. | |
* @param K the type of map keys. The map is invariant on its key type. | |
* @param V the type of map values. The mutable map is invariant on its value type. | |
*/ | |
interface AddOnlyMap<K, V> : Map<K, V> { | |
/** | |
* Associates the specified [value] with the specified [key] in the map. | |
* | |
* @return the previous value associated with the key, or `null` if the key was not present in the map. | |
*/ | |
fun put(key: K, value: V): V? | |
/** | |
* Updates this map with key/value pairs from the specified map [from]. | |
*/ | |
fun putAll(from: Map<out K, V>): Unit | |
/** | |
* Returns an [AddOnlySet] of all keys in this map. | |
*/ | |
override val keys: AddOnlySet<K> | |
/** | |
* Returns an [AddOnlyCollection] of all values in this map. Note that this collection may contain duplicate values. | |
*/ | |
override val values: AddOnlyCollection<V> | |
/** | |
* Returns an [AddOnlySet] of all key/value pairs in this map. | |
*/ | |
override val entries: AddOnlySet<MutableMap.MutableEntry<K, V>> | |
} | |
fun <E> MutableCollection<E>.restrictAddOnly(): AddOnlyCollection<E> { | |
return object : AddOnlySet<E>, Collection<E> by this { | |
override fun add(element: E) = this@restrictAddOnly.add(element) | |
override fun addAll(elements: Collection<E>) = this@restrictAddOnly.addAll(elements) | |
} | |
} | |
fun <E> MutableList<E>.restrictAddOnly(): AddOnlyList<E> { | |
return object : AddOnlyList<E>, List<E> by this { | |
override fun add(element: E) = this@restrictAddOnly.add(element) | |
override fun addAll(elements: Collection<E>) = this@restrictAddOnly.addAll(elements) | |
override fun add(index: Int, element: E) = this@restrictAddOnly.add(index, element) | |
override fun addAll(index: Int, elements: Collection<E>) = this@restrictAddOnly.addAll(index, elements) | |
override fun listIterator() = this@restrictAddOnly.listIterator().restrictAddOnly() | |
override fun listIterator(index: Int) = this@restrictAddOnly.listIterator(index).restrictAddOnly() | |
override fun subList(fromIndex: Int, toIndex: Int) = this@restrictAddOnly.subList(fromIndex, toIndex).restrictAddOnly() | |
} | |
} | |
fun <E> MutableListIterator<E>.restrictAddOnly(): AddOnlyListIterator<E> { | |
return object : AddOnlyListIterator<E>, ListIterator<E> by this { | |
override fun add(element: E) = this@restrictAddOnly.add(element) | |
} | |
} | |
fun <E> MutableSet<E>.restrictAddOnly(): AddOnlySet<E> { | |
return object : AddOnlySet<E>, Set<E> by this { | |
override fun add(element: E) = this@restrictAddOnly.add(element) | |
override fun addAll(elements: Collection<E>) = this@restrictAddOnly.addAll(elements) | |
} | |
} | |
fun <K, V> MutableMap<K, V>.restrictAddOnly(): AddOnlyMap<K, V> { | |
return object : AddOnlyMap<K, V>, Map<K, V> by this { | |
override fun put(key: K, value: V) = this@restrictAddOnly.put(key, value) | |
override fun putAll(from: Map<out K, V>) = this@restrictAddOnly.putAll(from) | |
override val keys get() = this@restrictAddOnly.keys.restrictAddOnly() | |
override val values get() = this@restrictAddOnly.values.restrictAddOnly() | |
override val entries get() = this@restrictAddOnly.entries.restrictAddOnly() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment