Add fast cast for recursive generics

This commit is contained in:
Alexander Nozik 2021-08-11 18:03:06 +03:00
parent da9d6e7639
commit 81abbe28a9
6 changed files with 36 additions and 20 deletions

View File

@ -3,6 +3,7 @@ package space.kscience.dataforge.meta
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import space.kscience.dataforge.misc.Type
import space.kscience.dataforge.misc.unsafeCast
import space.kscience.dataforge.names.*
import space.kscience.dataforge.values.*
@ -139,13 +140,6 @@ public fun Meta.getIndexed(name: Name): Map<String?, Meta> {
*/
public interface TypedMeta<out M : TypedMeta<M>> : Meta {
/**
* Access self as a recursive type instance
*/
@Suppress("UNCHECKED_CAST")
public val self: M
get() = this as M
override val items: Map<NameToken, M>
override fun getMeta(name: Name): M? {
@ -161,6 +155,11 @@ public interface TypedMeta<out M : TypedMeta<M>> : Meta {
override fun toMeta(): Meta = this
}
/**
* Access self as a recursive type instance
*/
public inline val <M : TypedMeta<M>> TypedMeta<M>.self: M get() = unsafeCast()
//public typealias Meta = TypedMeta<*>
public operator fun <M : TypedMeta<M>> TypedMeta<M>.get(token: NameToken): M? = items[token]

View File

@ -51,6 +51,20 @@ public data class MetaDescriptor(
public val defaultValue: Value? = null,
public val attributes: Meta = Meta.EMPTY,
) {
/**
* A node constructed of default values for this descriptor and its children
*/
public val defaultNode: Meta by lazy {
Meta {
defaultValue?.let { defaultValue ->
this.value = defaultValue
}
children.forEach { (key, descriptor) ->
set(key, descriptor.defaultNode)
}
}
}
public companion object {
internal const val ALLOWED_VALUES_KEY = "allowedValues"
}
@ -68,19 +82,6 @@ public operator fun MetaDescriptor.get(name: Name): MetaDescriptor? = when (name
public operator fun MetaDescriptor.get(name: String): MetaDescriptor? = get(Name.parse(name))
/**
* A node constructed of default values for this descriptor and its children
*/
public val MetaDescriptor.defaultNode: Meta
get() = Meta {
defaultValue?.let { defaultValue ->
this.value = defaultValue
}
children.forEach { (key, descriptor) ->
set(key, descriptor.defaultNode)
}
}
public fun MetaDescriptor.validate(value: Value?): Boolean = if (value == null) {
valueRequirement != ValueRequirement.REQUIRED
} else {

View File

@ -0,0 +1,3 @@
package space.kscience.dataforge.misc
public expect inline fun <T> Any?.unsafeCast(): T

View File

@ -0,0 +1,5 @@
package space.kscience.dataforge.misc
import kotlin.js.unsafeCast as unsafeCastJs
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
public actual inline fun <T> Any?.unsafeCast(): T = this.unsafeCastJs<T>()

View File

@ -0,0 +1,4 @@
package space.kscience.dataforge.misc
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
public actual inline fun <T> Any?.unsafeCast(): T = this as T

View File

@ -0,0 +1,4 @@
package space.kscience.dataforge.misc
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
public actual inline fun <T> Any?.unsafeCast(): T = this as T