Meta subtyping and get by empty name.
This commit is contained in:
parent
effac131de
commit
f9ae9348e2
@ -66,8 +66,14 @@ interface Meta : MetaRepr {
|
||||
|
||||
/* Get operations*/
|
||||
|
||||
/**
|
||||
* Perform recursive item search using given [name]. Each [NameToken] is treated as a name in [Meta.items] of a parent node.
|
||||
*
|
||||
* If [name] is empty reture current [Meta] as a [NodeItem]
|
||||
*/
|
||||
operator fun Meta?.get(name: Name): MetaItem<*>? {
|
||||
if (this == null) return null
|
||||
if (name.isEmpty()) return NodeItem(this)
|
||||
return name.first()?.let { token ->
|
||||
val tail = name.cutFirst()
|
||||
when (tail.length) {
|
||||
@ -78,6 +84,9 @@ operator fun Meta?.get(name: Name): MetaItem<*>? {
|
||||
}
|
||||
|
||||
operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token)
|
||||
/**
|
||||
* Parse [Name] from [key] using full name notation and pass it to [Meta.get]
|
||||
*/
|
||||
operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName())
|
||||
|
||||
/**
|
||||
@ -113,12 +122,16 @@ operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem<*>>> = sequence().ite
|
||||
/**
|
||||
* A meta node that ensures that all of its descendants has at least the same type
|
||||
*/
|
||||
interface MetaNode<M : MetaNode<M>> : Meta {
|
||||
interface MetaNode<out M : MetaNode<M>> : Meta {
|
||||
override val items: Map<NameToken, MetaItem<M>>
|
||||
}
|
||||
|
||||
operator fun <M : MetaNode<M>> MetaNode<M>?.get(name: Name): MetaItem<M>? {
|
||||
/**
|
||||
* The same as [Meta.get], but with specific node type
|
||||
*/
|
||||
operator fun <M : MetaNode<M>> M?.get(name: Name): MetaItem<M>? {
|
||||
if (this == null) return null
|
||||
if (name.isEmpty()) return NodeItem(this)
|
||||
return name.first()?.let { token ->
|
||||
val tail = name.cutFirst()
|
||||
when (tail.length) {
|
||||
@ -128,17 +141,9 @@ operator fun <M : MetaNode<M>> MetaNode<M>?.get(name: Name): MetaItem<M>? {
|
||||
}
|
||||
}
|
||||
|
||||
operator fun <M : MetaNode<M>> MetaNode<M>?.get(key: String): MetaItem<M>? = if (this == null) {
|
||||
null
|
||||
} else {
|
||||
this[key.toName()]
|
||||
}
|
||||
operator fun <M : MetaNode<M>> M?.get(key: String): MetaItem<M>? = this[key.toName()]
|
||||
|
||||
operator fun <M : MetaNode<M>> MetaNode<M>?.get(key: NameToken): MetaItem<M>? = if (this == null) {
|
||||
null
|
||||
} else {
|
||||
this[key.asName()]
|
||||
}
|
||||
operator fun <M : MetaNode<M>> M?.get(key: NameToken): MetaItem<M>? = this[key.asName()]
|
||||
|
||||
/**
|
||||
* Equals, hashcode and to string for any meta
|
||||
|
@ -3,7 +3,7 @@ package hep.dataforge.meta
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.values.Value
|
||||
|
||||
interface MutableMeta<M : MutableMeta<M>> : MetaNode<M> {
|
||||
interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M> {
|
||||
override val items: Map<NameToken, MetaItem<M>>
|
||||
operator fun set(name: Name, item: MetaItem<*>?)
|
||||
// fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit)
|
||||
@ -54,7 +54,8 @@ abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(),
|
||||
0 -> error("Can't setValue meta item for empty name")
|
||||
1 -> {
|
||||
val token = name.first()!!
|
||||
replaceItem(token, get(name), wrapItem(item))
|
||||
@Suppress("UNCHECKED_CAST") val oldItem: MetaItem<M>? = get(name) as? MetaItem<M>
|
||||
replaceItem(token, oldItem, wrapItem(item))
|
||||
}
|
||||
else -> {
|
||||
val token = name.first()!!
|
||||
@ -71,6 +72,7 @@ abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(),
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun MutableMeta<*>.remove(name: Name) = set(name, null)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun MutableMeta<*>.remove(name: String) = remove(name.toName())
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user