1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.kairos.internal.store 18 19 /** 20 * Higher-kinded encoding for [Map]. 21 * 22 * Let's say you want to write a class that is generic over both a map, and the type of data within 23 * the map: 24 * ``` 25 * class Foo<TMap, TKey, TValue> { 26 * val container: TMap<TKey, TElement> // disallowed! 27 * } 28 * ``` 29 * 30 * You can use `MapK` to represent the "higher-kinded" type variable `TMap`: 31 * ``` 32 * class Foo<TMap, TKey, TValue> { 33 * val container: MapK<TMap, TKey, TValue> // OK! 34 * } 35 * ``` 36 * 37 * Note that Kotlin will not let you use the generic type without parameters as `TMap`: 38 * ``` 39 * val fooHk: MapK<HashMap, Int, String> // not allowed: HashMap requires two type parameters 40 * ``` 41 * 42 * To work around this, you need to declare a special type-witness object. This object is only used 43 * at compile time and can be stripped out by a minifier because it's never used at runtime. 44 * 45 * ``` 46 * class Foo<A, B> : MapK<FooWitness, A, B> { ... } 47 * object FooWitness 48 * 49 * // safe, as long as Foo is the only implementor of MapK<FooWitness, *, *> 50 * fun <A, B> MapK<FooWitness, A, B>.asFoo(): Foo<A, B> = this as Foo<A, B> 51 * 52 * val fooStore: MapK<FooWitness, Int, String> = Foo() 53 * val foo: Foo<Int, String> = fooStore.asFoo() 54 * ``` 55 */ 56 internal interface MapK<W, K, V> : Map<K, V> 57 58 internal interface MutableMapK<W, K, V> : MutableMap<K, V> { 59 readOnlyCopynull60 fun readOnlyCopy(): MapK<W, K, V> 61 62 fun asReadOnly(): MapK<W, K, V> 63 64 interface Factory<W, K> { 65 fun <V> create(capacity: Int?): MutableMapK<W, K, V> 66 67 fun <V> create(input: MapK<W, K, V>): MutableMapK<W, K, V> 68 } 69 } 70 71 internal object NoValue 72 73 internal data class StoreEntry<K, V>(override var key: K, override var value: V) : 74 MutableMap.MutableEntry<K, V> { <lambda>null75 override fun setValue(newValue: V): V = value.also { value = newValue } 76 } 77