Bottom type check for tables
This commit is contained in:
parent
061c570407
commit
126e59f81a
@ -5,7 +5,7 @@ import kotlin.reflect.KClass
|
|||||||
/**
|
/**
|
||||||
* @param C bottom type for all columns in the table
|
* @param C bottom type for all columns in the table
|
||||||
*/
|
*/
|
||||||
class ColumnTable<C: Any>(override val columns: Collection<Column<C>>) : Table {
|
class ColumnTable<C : Any>(override val columns: Collection<Column<C>>) : Table<C> {
|
||||||
private val rowsNum = columns.first().size
|
private val rowsNum = columns.first().size
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -21,7 +21,7 @@ class ColumnTable<C: Any>(override val columns: Collection<Column<C>>) : Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class VirtualRow(val table: Table, val index: Int) : Row {
|
internal class VirtualRow<C : Any>(val table: Table<C>, val index: Int) : Row {
|
||||||
override fun <T : Any> getValue(column: String, type: KClass<out T>): T? = table.getValue(index, column, type)
|
override fun <T : Any> getValue(column: String, type: KClass<out T>): T? = table.getValue(index, column, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,10 @@ package hep.dataforge.tables
|
|||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
class ColumnTableBuilder(val size: Int) : Table {
|
class ColumnTableBuilder<C: Any>(val size: Int) : Table<C> {
|
||||||
private val _columns = ArrayList<Column<*>>()
|
private val _columns = ArrayList<Column<C>>()
|
||||||
|
|
||||||
override val columns: List<Column<*>> get() = _columns
|
override val columns: List<Column<C>> get() = _columns
|
||||||
override val rows: List<Row> get() = (0 until size).map {
|
override val rows: List<Row> get() = (0 until size).map {
|
||||||
VirtualRow(this, it)
|
VirtualRow(this, it)
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@ class ColumnTableBuilder(val size: Int) : Table {
|
|||||||
/**
|
/**
|
||||||
* Add a fixed column to the end of the table
|
* Add a fixed column to the end of the table
|
||||||
*/
|
*/
|
||||||
fun add(column: Column<*>) {
|
fun add(column: Column<C>) {
|
||||||
require(column.size == this.size) { "Required column size $size, but found ${column.size}" }
|
require(column.size == this.size) { "Required column size $size, but found ${column.size}" }
|
||||||
_columns.add(column)
|
_columns.add(column)
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ class ColumnTableBuilder(val size: Int) : Table {
|
|||||||
/**
|
/**
|
||||||
* Insert a column at [index]
|
* Insert a column at [index]
|
||||||
*/
|
*/
|
||||||
fun insert(index: Int, column: Column<*>) {
|
fun insert(index: Int, column: Column<C>) {
|
||||||
require(column.size == this.size) { "Required column size $size, but found ${column.size}" }
|
require(column.size == this.size) { "Required column size $size, but found ${column.size}" }
|
||||||
_columns.add(index, column)
|
_columns.add(index, column)
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@ import hep.dataforge.meta.Meta
|
|||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
class RowTable<R : Row>(override val rows: List<R>, override val header: TableHeader) : Table {
|
class RowTable<C: Any, R : Row>(override val rows: List<R>, override val header: List<ColumnHeader<C>>) : Table<C> {
|
||||||
override fun <T : Any> getValue(row: Int, column: String, type: KClass<out T>): T? =
|
override fun <T : Any> getValue(row: Int, column: String, type: KClass<out T>): T? =
|
||||||
rows[row].getValue(column, type)
|
rows[row].getValue(column, type)
|
||||||
|
|
||||||
override val columns: List<Column<*>> get() = header.map { RotTableColumn(it) }
|
override val columns: List<Column<C>> get() = header.map { RotTableColumn(it) }
|
||||||
|
|
||||||
private inner class RotTableColumn<T : Any>(val header: ColumnHeader<T>) : Column<T> {
|
private inner class RotTableColumn<T : C>(val header: ColumnHeader<T>) : Column<T> {
|
||||||
override val name: String get() = header.name
|
override val name: String get() = header.name
|
||||||
override val type: KClass<out T> get() = header.type
|
override val type: KClass<out T> get() = header.type
|
||||||
override val meta: Meta get() = header.meta
|
override val meta: Meta get() = header.meta
|
||||||
|
@ -16,9 +16,9 @@ internal fun <T : Any> KClass<T>.cast(value: Any?): T? {
|
|||||||
typealias TableHeader = List<ColumnHeader<*>>
|
typealias TableHeader = List<ColumnHeader<*>>
|
||||||
|
|
||||||
|
|
||||||
interface Table {
|
interface Table<out C: Any> {
|
||||||
fun <T : Any> getValue(row: Int, column: String, type: KClass<out T>): T?
|
fun <T : Any> getValue(row: Int, column: String, type: KClass<out T>): T?
|
||||||
val columns: Collection<Column<*>>
|
val columns: Collection<Column<C>>
|
||||||
val header: TableHeader get() = columns.toList()
|
val header: TableHeader get() = columns.toList()
|
||||||
val rows: List<Row>
|
val rows: List<Row>
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ interface Table {
|
|||||||
|
|
||||||
operator fun Collection<Column<*>>.get(name: String): Column<*>? = find { it.name == name }
|
operator fun Collection<Column<*>>.get(name: String): Column<*>? = find { it.name == name }
|
||||||
|
|
||||||
inline operator fun <reified T : Any> Table.get(row: Int, column: String): T? = getValue(row, column, T::class)
|
inline operator fun <C: Any, reified T : C> Table<C>.get(row: Int, column: String): T? = getValue(row, column, T::class)
|
||||||
|
|
||||||
interface ColumnHeader<out T : Any> {
|
interface ColumnHeader<out T : Any> {
|
||||||
val name: String
|
val name: String
|
||||||
@ -38,7 +38,7 @@ interface ColumnHeader<out T : Any> {
|
|||||||
val meta: Meta
|
val meta: Meta
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun <T : Any> Table.get(row: Int, column: Column<T>): T? = getValue(row, column.name, column.type)
|
operator fun <C: Any, T : C> Table<C>.get(row: Int, column: Column<T>): T? = getValue(row, column.name, column.type)
|
||||||
|
|
||||||
interface Column<out T : Any> : ColumnHeader<T> {
|
interface Column<out T : Any> : ColumnHeader<T> {
|
||||||
val size: Int
|
val size: Int
|
||||||
|
@ -25,7 +25,7 @@ class CastColumn<T : Any>(val origin: Column<*>, override val type: KClass<T>) :
|
|||||||
override fun get(index: Int): T? = type.cast(origin[index])
|
override fun get(index: Int): T? = type.cast(origin[index])
|
||||||
}
|
}
|
||||||
|
|
||||||
class ColumnProperty<T : Any>(val table: Table, val type: KClass<T>) : ReadOnlyProperty<Any?, Column<T>> {
|
class ColumnProperty<C: Any, T : C>(val table: Table<C>, val type: KClass<T>) : ReadOnlyProperty<Any?, Column<T>> {
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Column<T> {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Column<T> {
|
||||||
val name = property.name
|
val name = property.name
|
||||||
return (table.columns[name] ?: error("Column with name $name not found in the table")).cast(type)
|
return (table.columns[name] ?: error("Column with name $name not found in the table")).cast(type)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user