Compare commits
7 Commits
2124b8b229
...
09990150cb
| Author | SHA1 | Date | |
|---|---|---|---|
| 09990150cb | |||
| edbb3f682f | |||
| 1f76f364b4 | |||
| ca6b4df548 | |||
| 512ba38209 | |||
| 49b6dffdba | |||
| 9f20223e92 |
+1
-1
@@ -35,7 +35,7 @@ kotlin {
|
|||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvmToolchain {
|
jvmToolchain {
|
||||||
languageVersion = JavaLanguageVersion.of(25)
|
languageVersion = JavaLanguageVersion.of(21)
|
||||||
vendor = JvmVendorSpec.ADOPTIUM
|
vendor = JvmVendorSpec.ADOPTIUM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Main
|
# Main
|
||||||
|
|
||||||
gradle = "9.5.0" # https://gradle.org/releases/
|
gradle = "9.5.1" # https://gradle.org/releases/
|
||||||
|
|
||||||
kotlin = "2.3.21" # https://kotlinlang.org/docs/releases.html#release-details
|
kotlin = "2.3.21" # https://kotlinlang.org/docs/releases.html#release-details
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ mockk = "1.14.9" # https://mvnrepository.com/artifact/io.mockk/mockk
|
|||||||
|
|
||||||
kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" }
|
kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" }
|
||||||
|
|
||||||
memoize = {group = "org.duckdns.davygora", name = "memoize", version.ref="memoize"}
|
memoize = { group = "org.duckdns.davygora", name = "memoize", version.ref = "memoize" }
|
||||||
|
|
||||||
# Test
|
# Test
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
retries=0
|
retries=0
|
||||||
retryBackOffMs=500
|
retryBackOffMs=500
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/<unknown>/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package org.duckdns.davygora.matrix
|
||||||
|
|
||||||
|
import org.duckdns.davygora.matrix.storage.MatrixStorage
|
||||||
|
|
||||||
|
abstract class AbstractMatrix<T>(
|
||||||
|
override val xSize: Int,
|
||||||
|
override val ySize: Int,
|
||||||
|
protected val matrix: MatrixStorage<T>,
|
||||||
|
) : Matrix<T> {
|
||||||
|
override fun toString(): String =
|
||||||
|
(0..<ySize)
|
||||||
|
.map { y ->
|
||||||
|
"[\t${(0..<xSize).joinToString("\t") { x -> this[x, y].toString() }}\t]"
|
||||||
|
}.joinToString { "\n" }
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as AbstractMatrix<T>
|
||||||
|
|
||||||
|
if (xSize != other.xSize) return false
|
||||||
|
if (ySize != other.ySize) return false
|
||||||
|
if (matrix != other.matrix) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = xSize
|
||||||
|
result = 31 * result + ySize
|
||||||
|
result = 31 * result + matrix.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.duckdns.davygora.matrix
|
||||||
|
|
||||||
|
import org.duckdns.davygora.matrix.storage.MatrixStorage
|
||||||
|
|
||||||
|
abstract class AbstractMutableMatrix<T>(
|
||||||
|
xSize: Int,
|
||||||
|
ySize: Int,
|
||||||
|
matrix: MatrixStorage<T>,
|
||||||
|
) : AbstractMatrix<T>(xSize, ySize, matrix),
|
||||||
|
MutableMatrix<T>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.duckdns.davygora.matrix
|
||||||
|
|
||||||
|
interface Matrix<T> {
|
||||||
|
val xSize: Int
|
||||||
|
val ySize: Int
|
||||||
|
|
||||||
|
operator fun get(
|
||||||
|
x: Int,
|
||||||
|
y: Int,
|
||||||
|
): T
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package org.duckdns.davygora.matrix
|
||||||
|
|
||||||
|
interface MutableMatrix<T> : Matrix<T> {
|
||||||
|
operator fun set(
|
||||||
|
x: Int,
|
||||||
|
y: Int,
|
||||||
|
value: T,
|
||||||
|
)
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package org.duckdns.davygora.matrix.exception
|
||||||
|
|
||||||
|
class MatrixCoordinateOutOfRangeException(
|
||||||
|
coordName: Char,
|
||||||
|
coord: Int,
|
||||||
|
maxCoord: Int,
|
||||||
|
) : MatrixException("${coordName.uppercaseChar()} coordinate $coord is out of range, allowed is 0..$maxCoord")
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package org.duckdns.davygora.matrix.exception
|
||||||
|
|
||||||
|
sealed class MatrixException(
|
||||||
|
message: String,
|
||||||
|
cause: Throwable? = null,
|
||||||
|
) : RuntimeException(message, cause)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package org.duckdns.davygora.matrix.exception
|
||||||
|
|
||||||
|
class MatrixInvalidSizeException(
|
||||||
|
coordinate: Char,
|
||||||
|
size: Int,
|
||||||
|
) : MatrixException("${coordinate.uppercaseChar()} size is invalid: $size (should be > 0)")
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package org.duckdns.davygora.matrix.exception
|
||||||
|
|
||||||
|
class MatrixNotRectangularException(
|
||||||
|
xSizes: Collection<Int>,
|
||||||
|
) : MatrixException("Submitted matrix is not rectangular, different row sizes are $xSizes")
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package org.duckdns.davygora.matrix.exception
|
||||||
|
|
||||||
|
class MatrixSizeMismatchException(
|
||||||
|
expectedSize: Int,
|
||||||
|
actualSize: Int,
|
||||||
|
) : MatrixException("Matrix size mismatch: expected $expectedSize, actual $actualSize")
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package org.duckdns.davygora.matrix.impl
|
||||||
|
|
||||||
|
import org.duckdns.davygora.matrix.AbstractMutableMatrix
|
||||||
|
import org.duckdns.davygora.matrix.exception.MatrixCoordinateOutOfRangeException
|
||||||
|
import org.duckdns.davygora.matrix.exception.MatrixInvalidSizeException
|
||||||
|
import org.duckdns.davygora.matrix.exception.MatrixNotRectangularException
|
||||||
|
import org.duckdns.davygora.matrix.exception.MatrixSizeMismatchException
|
||||||
|
import org.duckdns.davygora.matrix.storage.MatrixStorage
|
||||||
|
import org.duckdns.davygora.matrix.storage.toMatrixStorage
|
||||||
|
import org.duckdns.davygora.memoize.memoize
|
||||||
|
|
||||||
|
class ArrayMatrix<T>(
|
||||||
|
xSize: Int,
|
||||||
|
ySize: Int,
|
||||||
|
matrix: MatrixStorage<T>,
|
||||||
|
) : AbstractMutableMatrix<T>(xSize, ySize, matrix) {
|
||||||
|
private val size = xSize * ySize
|
||||||
|
|
||||||
|
private val maxX = xSize - 1
|
||||||
|
private val maxY = ySize - 1
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (ySize < 1) throw MatrixInvalidSizeException('y', ySize)
|
||||||
|
if (xSize < 1) throw MatrixInvalidSizeException('x', xSize)
|
||||||
|
if (size != matrix.size) throw MatrixSizeMismatchException(size, matrix.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
override operator fun get(
|
||||||
|
x: Int,
|
||||||
|
y: Int,
|
||||||
|
): T = matrix[index(x, y)]
|
||||||
|
|
||||||
|
override operator fun set(
|
||||||
|
x: Int,
|
||||||
|
y: Int,
|
||||||
|
value: T,
|
||||||
|
) {
|
||||||
|
matrix[index(x, y)] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
private val index = { x: Int, y: Int -> validateY(y) * xSize + validateX(x) }.memoize()
|
||||||
|
|
||||||
|
private val validateX = { x: Int -> validateCoord('x', x, maxX) }.memoize()
|
||||||
|
private val validateY = { y: Int -> validateCoord('y', y, maxY) }.memoize()
|
||||||
|
|
||||||
|
private fun validateCoord(
|
||||||
|
coordName: Char,
|
||||||
|
coord: Int,
|
||||||
|
maxCoord: Int,
|
||||||
|
) = if (coord in
|
||||||
|
0..maxCoord
|
||||||
|
) {
|
||||||
|
coord
|
||||||
|
} else {
|
||||||
|
throw MatrixCoordinateOutOfRangeException(coordName, coord, maxCoord)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
inline fun <reified T> create(values: List<List<T>>): ArrayMatrix<T> {
|
||||||
|
val ySize = values.size
|
||||||
|
val xSize =
|
||||||
|
when {
|
||||||
|
ySize > 0 -> {
|
||||||
|
values.map { row -> row.size }.toSet().let { xSizes ->
|
||||||
|
if (xSizes.size == 1) xSizes.first() else throw MatrixNotRectangularException(xSizes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ArrayMatrix(xSize, ySize, values.flatten().toMatrixStorage())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.duckdns.davygora.matrix.impl
|
||||||
|
|
||||||
|
import org.duckdns.davygora.matrix.Matrix
|
||||||
|
import org.duckdns.davygora.matrix.MutableMatrix
|
||||||
|
import org.duckdns.davygora.matrix.storage.toMatrixStorage
|
||||||
|
import org.duckdns.davygora.matrix.util.toListChecked
|
||||||
|
|
||||||
|
inline fun <reified T> mutableMatrixOf(
|
||||||
|
xSize: Int,
|
||||||
|
ySize: Int,
|
||||||
|
vararg matrix: T,
|
||||||
|
) = ArrayMatrix(xSize, ySize, matrix.asList().toMatrixStorage()) as MutableMatrix<T>
|
||||||
|
|
||||||
|
inline fun <reified T> matrixOf(
|
||||||
|
xSize: Int,
|
||||||
|
ySize: Int,
|
||||||
|
vararg matrix: T,
|
||||||
|
) = mutableMatrixOf(xSize, ySize, *matrix) as Matrix<T>
|
||||||
|
|
||||||
|
inline fun <reified T> Iterable<Any>.toMatrix() = ArrayMatrix.create(this.map { it.toListChecked<T>() })
|
||||||
|
|
||||||
|
inline fun <reified T> Array<Any>.toMatrix() = this.asList().toMatrix<T>()
|
||||||
|
|
||||||
|
inline fun <reified T> Sequence<Any>.toMatrix() = this.toList().toMatrix<T>()
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class BooleanStorage(
|
||||||
|
override val data: BooleanArray,
|
||||||
|
) : MatrixStorage<Boolean> {
|
||||||
|
override val size get() = data.size
|
||||||
|
|
||||||
|
override operator fun get(index: Int) = data[index]
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
index: Int,
|
||||||
|
value: Boolean,
|
||||||
|
) {
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = data.contentToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun BooleanArray.toMatrixStorage() = BooleanStorage(this)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class ByteStorage(
|
||||||
|
override val data: ByteArray,
|
||||||
|
) : MatrixStorage<Byte> {
|
||||||
|
override val size get() = data.size
|
||||||
|
|
||||||
|
override operator fun get(index: Int) = data[index]
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
index: Int,
|
||||||
|
value: Byte,
|
||||||
|
) {
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = data.contentToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ByteArray.toMatrixStorage() = ByteStorage(this)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class CharStorage(
|
||||||
|
override val data: CharArray,
|
||||||
|
) : MatrixStorage<Char> {
|
||||||
|
override val size get() = data.size
|
||||||
|
|
||||||
|
override operator fun get(index: Int) = data[index]
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
index: Int,
|
||||||
|
value: Char,
|
||||||
|
) {
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = data.contentToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CharArray.toMatrixStorage() = CharStorage(this)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class DoubleStorage(
|
||||||
|
override val data: DoubleArray,
|
||||||
|
) : MatrixStorage<Double> {
|
||||||
|
override val size get() = data.size
|
||||||
|
|
||||||
|
override operator fun get(index: Int) = data[index]
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
index: Int,
|
||||||
|
value: Double,
|
||||||
|
) {
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = data.contentToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DoubleArray.toMatrixStorage() = DoubleStorage(this)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class FloatStorage(
|
||||||
|
override val data: FloatArray,
|
||||||
|
) : MatrixStorage<Float> {
|
||||||
|
override val size get() = data.size
|
||||||
|
|
||||||
|
override operator fun get(index: Int) = data[index]
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
index: Int,
|
||||||
|
value: Float,
|
||||||
|
) {
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = data.contentToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FloatArray.toMatrixStorage() = FloatStorage(this)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class IntStorage(
|
||||||
|
override val data: IntArray,
|
||||||
|
) : MatrixStorage<Int> {
|
||||||
|
override val size get() = data.size
|
||||||
|
|
||||||
|
override operator fun get(index: Int) = data[index]
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
index: Int,
|
||||||
|
value: Int,
|
||||||
|
) {
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = data.contentToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IntArray.toMatrixStorage() = IntStorage(this)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class LongStorage(
|
||||||
|
override val data: LongArray,
|
||||||
|
) : MatrixStorage<Long> {
|
||||||
|
override val size get() = data.size
|
||||||
|
|
||||||
|
override operator fun get(index: Int) = data[index]
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
index: Int,
|
||||||
|
value: Long,
|
||||||
|
) {
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = data.contentToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun LongArray.toMatrixStorage() = LongStorage(this)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
sealed interface MatrixStorage<T> {
|
||||||
|
val data: Any
|
||||||
|
|
||||||
|
val size: Int
|
||||||
|
|
||||||
|
operator fun get(index: Int): T
|
||||||
|
|
||||||
|
operator fun set(
|
||||||
|
index: Int,
|
||||||
|
value: T,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <reified T> List<T>.toMatrixStorage(): MatrixStorage<T> {
|
||||||
|
firstNotNullOfOrNull { it }
|
||||||
|
|
||||||
|
val elementClass =
|
||||||
|
firstOrNull()
|
||||||
|
?.let { first -> first::class }
|
||||||
|
?.takeIf { clazz ->
|
||||||
|
all { it == null || it::class == clazz }
|
||||||
|
}
|
||||||
|
?: T::class
|
||||||
|
|
||||||
|
return when (elementClass) {
|
||||||
|
Boolean::class -> (this as List<Boolean>).toBooleanArray().toMatrixStorage()
|
||||||
|
Byte::class -> (this as List<Byte>).toByteArray().toMatrixStorage()
|
||||||
|
Char::class -> (this as List<Char>).toCharArray().toMatrixStorage()
|
||||||
|
Double::class -> (this as List<Double>).toDoubleArray().toMatrixStorage()
|
||||||
|
Float::class -> (this as List<Float>).toFloatArray().toMatrixStorage()
|
||||||
|
Int::class -> (this as List<Int>).toIntArray().toMatrixStorage()
|
||||||
|
Long::class -> (this as List<Long>).toLongArray().toMatrixStorage()
|
||||||
|
Short::class -> (this as List<Short>).toShortArray().toMatrixStorage()
|
||||||
|
else -> this.toTypedArray().toMatrixStorage()
|
||||||
|
} as MatrixStorage<T>
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class ObjectStorage<T>(
|
||||||
|
override val data: Array<T>,
|
||||||
|
) : MatrixStorage<T> {
|
||||||
|
override val size get() = data.size
|
||||||
|
|
||||||
|
override operator fun get(index: Int) = data[index]
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
index: Int,
|
||||||
|
value: T,
|
||||||
|
) {
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = data.contentToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Array<T>.toMatrixStorage() = ObjectStorage(this)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class ShortStorage(
|
||||||
|
override val data: ShortArray,
|
||||||
|
) : MatrixStorage<Short> {
|
||||||
|
override val size get() = data.size
|
||||||
|
|
||||||
|
override operator fun get(index: Int) = data[index]
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
index: Int,
|
||||||
|
value: Short,
|
||||||
|
) {
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = data.contentToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ShortArray.toMatrixStorage() = ShortStorage(this)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.duckdns.davygora.matrix.util
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <reified T> Any.toListChecked(): List<T> =
|
||||||
|
when (this) {
|
||||||
|
is List<*> -> this
|
||||||
|
is Collection<*> -> toList()
|
||||||
|
is Iterable<*> -> toList()
|
||||||
|
is Sequence<*> -> toList()
|
||||||
|
is Array<*> -> asList()
|
||||||
|
is BooleanArray -> asList()
|
||||||
|
is ByteArray -> asList()
|
||||||
|
is CharArray -> asList()
|
||||||
|
is DoubleArray -> asList()
|
||||||
|
is FloatArray -> asList()
|
||||||
|
is IntArray -> asList()
|
||||||
|
is LongArray -> asList()
|
||||||
|
is ShortArray -> asList()
|
||||||
|
else -> error("Unsupported type: ${this::class}")
|
||||||
|
}.also { list ->
|
||||||
|
require(list.all { it is T })
|
||||||
|
} as List<T>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package org.duckdns.davygora.matrix.storage
|
||||||
|
|
||||||
|
import io.kotest.core.spec.style.FunSpec
|
||||||
|
import io.kotest.datatest.withData
|
||||||
|
import io.kotest.matchers.shouldBe
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
class MatrixStorageTest :
|
||||||
|
FunSpec({
|
||||||
|
val testCases: Map<String, Triple<List<*>, KClass<*>, KClass<*>>> =
|
||||||
|
mapOf(
|
||||||
|
"boolean" to Triple(listOf(true, false), BooleanStorage::class, BooleanArray::class),
|
||||||
|
"byte" to Triple((0..100).map { it.toByte() }, ByteStorage::class, ByteArray::class),
|
||||||
|
"char" to Triple(('a'..'z') + ('A'..'Z') + ('0'..'9'), CharStorage::class, CharArray::class),
|
||||||
|
"double" to Triple((0..100).map { it.toDouble() }, DoubleStorage::class, DoubleArray::class),
|
||||||
|
"float" to Triple((0..100).map { it.toFloat() }, FloatStorage::class, FloatArray::class),
|
||||||
|
"int" to Triple((0..100).map { it }, IntStorage::class, IntArray::class),
|
||||||
|
"long" to Triple((0..100).map { it.toLong() }, LongStorage::class, LongArray::class),
|
||||||
|
"short" to Triple((0..100).map { it.toShort() }, ShortStorage::class, ShortArray::class),
|
||||||
|
"object" to Triple((0..100).map { first -> Pair(first, (0..100).random()) }, ObjectStorage::class, Array<Any>::class),
|
||||||
|
)
|
||||||
|
|
||||||
|
context("list of elements of a given type should produce corresponding storage, size, get and set should work") {
|
||||||
|
withData(
|
||||||
|
testCases,
|
||||||
|
) { (allowedValues, storageClass, dataClass) ->
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
|
||||||
|
val size = (10..1000).random()
|
||||||
|
val list = List(size) { allowedValues.random() }
|
||||||
|
val newList = List(size) { allowedValues.random() }
|
||||||
|
|
||||||
|
// Act
|
||||||
|
|
||||||
|
val storage = list.toMatrixStorage()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
|
||||||
|
storage::class shouldBe storageClass
|
||||||
|
storage.data::class shouldBe dataClass
|
||||||
|
|
||||||
|
storage.size shouldBe size
|
||||||
|
list.forEachIndexed { index, value -> storage[index] shouldBe value }
|
||||||
|
|
||||||
|
newList.forEachIndexed { index, value -> storage[index] = value }
|
||||||
|
newList.forEachIndexed { index, value -> storage[index] shouldBe value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user