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
|
||||
*/
|
||||
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
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,10 @@ package hep.dataforge.tables
|
||||
import hep.dataforge.meta.Meta
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class ColumnTableBuilder(val size: Int) : Table {
|
||||
private val _columns = ArrayList<Column<*>>()
|
||||
class ColumnTableBuilder<C: Any>(val size: Int) : Table<C> {
|
||||
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 {
|
||||
VirtualRow(this, it)
|
||||
}
|
||||
@ -19,7 +19,7 @@ class ColumnTableBuilder(val size: Int) : 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}" }
|
||||
_columns.add(column)
|
||||
}
|
||||
@ -27,7 +27,7 @@ class ColumnTableBuilder(val size: Int) : Table {
|
||||
/**
|
||||
* 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}" }
|
||||
_columns.add(index, column)
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ import hep.dataforge.meta.Meta
|
||||
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? =
|
||||
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 type: KClass<out T> get() = header.type
|
||||
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<*>>
|
||||
|
||||
|
||||
interface Table {
|
||||
interface Table<out C: Any> {
|
||||
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 rows: List<Row>
|
||||
|
||||
@ -30,7 +30,7 @@ interface Table {
|
||||
|
||||
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> {
|
||||
val name: String
|
||||
@ -38,7 +38,7 @@ interface ColumnHeader<out T : Any> {
|
||||
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> {
|
||||
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])
|
||||
}
|
||||
|
||||
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> {
|
||||
val name = property.name
|
||||
return (table.columns[name] ?: error("Column with name $name not found in the table")).cast(type)
|
||||
|
Loading…
Reference in New Issue
Block a user