Bottom type check for tables

This commit is contained in:
Alexander Nozik 2020-02-08 22:01:56 +03:00
parent 061c570407
commit 126e59f81a
5 changed files with 15 additions and 15 deletions

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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

View File

@ -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)