• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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