Compare commits

..

12 Commits

Author SHA1 Message Date
renovate-bot 9446c5de66 Update kotest to v6.2.0 2026-06-16 06:21:38 +00:00
renovate-bot fc1e5aa3a9 Update kotlin monorepo to v2.4.0 2026-06-04 02:00:53 +00:00
renovate-bot 6699d13159 Update dependency io.mockk:mockk to v1.14.11 2026-06-02 08:10:18 +00:00
renovate-bot 56b66e4804 Update junit-framework monorepo to v6.1.0 2026-05-20 06:03:14 +00:00
yura 2124b8b229 Adding LICENSE and a dummy README 2026-05-18 09:40:19 +02:00
yura f85ac3f76e Bumping gradle version 2026-05-18 09:40:19 +02:00
yura 84e7b25468 Just a little improvement, no code change 2026-05-18 09:40:19 +02:00
yura 5cbf9f4a14 Adding MatrixStorageTest 2026-05-18 09:40:19 +02:00
yura 5c42826e66 Adding some extensions 2026-05-18 09:40:19 +02:00
yura db51aecca1 Adding companion create method 2026-05-18 09:40:19 +02:00
yura b442d9d574 Basic Matrix and Matrix Storage implementation 2026-05-18 09:40:19 +02:00
yura 075bd4f54b Adding renovate.json 2026-05-18 09:40:07 +02:00
19 changed files with 140 additions and 18 deletions
View File
+3
View File
@@ -0,0 +1,3 @@
# Matrix
TODO
+5 -5
View File
@@ -2,9 +2,9 @@
# 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.4.0" # https://kotlinlang.org/docs/releases.html#release-details
ktlint-library = "1.8.0" # https://github.com/pinterest/ktlint ktlint-library = "1.8.0" # https://github.com/pinterest/ktlint
ktlint-plugin = "14.2.0" # https://github.com/JLLeitschuh/ktlint-gradle ktlint-plugin = "14.2.0" # https://github.com/JLLeitschuh/ktlint-gradle
@@ -13,9 +13,9 @@ memoize = "0.1" # https://gitea.davygora.duckdns.org/yura/-/packages/maven/org.d
# Test # Test
kotest = "6.1.11" # https://mvnrepository.com/artifact/io.kotest/kotest-runner-junit5 kotest = "6.2.0" # https://mvnrepository.com/artifact/io.kotest/kotest-runner-junit5
junit = "6.0.3" # https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter junit = "6.1.0" # https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter
mockk = "1.14.9" # https://mvnrepository.com/artifact/io.mockk/mockk mockk = "1.14.11" # https://mvnrepository.com/artifact/io.mockk/mockk
[libraries] [libraries]
+1 -1
View File
@@ -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
Vendored
+1 -1
View File
@@ -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/.
+10
View File
@@ -0,0 +1,10 @@
{
"extends": ["config:recommended"],
"labels": ["dependencies"],
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
}
]
}
@@ -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>()
@@ -2,7 +2,7 @@ package org.duckdns.davygora.matrix.storage
@JvmInline @JvmInline
value class BooleanStorage( value class BooleanStorage(
val data: BooleanArray, override val data: BooleanArray,
) : MatrixStorage<Boolean> { ) : MatrixStorage<Boolean> {
override val size get() = data.size override val size get() = data.size
@@ -2,7 +2,7 @@ package org.duckdns.davygora.matrix.storage
@JvmInline @JvmInline
value class ByteStorage( value class ByteStorage(
val data: ByteArray, override val data: ByteArray,
) : MatrixStorage<Byte> { ) : MatrixStorage<Byte> {
override val size get() = data.size override val size get() = data.size
@@ -2,7 +2,7 @@ package org.duckdns.davygora.matrix.storage
@JvmInline @JvmInline
value class CharStorage( value class CharStorage(
val data: CharArray, override val data: CharArray,
) : MatrixStorage<Char> { ) : MatrixStorage<Char> {
override val size get() = data.size override val size get() = data.size
@@ -2,7 +2,7 @@ package org.duckdns.davygora.matrix.storage
@JvmInline @JvmInline
value class DoubleStorage( value class DoubleStorage(
val data: DoubleArray, override val data: DoubleArray,
) : MatrixStorage<Double> { ) : MatrixStorage<Double> {
override val size get() = data.size override val size get() = data.size
@@ -2,7 +2,7 @@ package org.duckdns.davygora.matrix.storage
@JvmInline @JvmInline
value class FloatStorage( value class FloatStorage(
val data: FloatArray, override val data: FloatArray,
) : MatrixStorage<Float> { ) : MatrixStorage<Float> {
override val size get() = data.size override val size get() = data.size
@@ -2,7 +2,7 @@ package org.duckdns.davygora.matrix.storage
@JvmInline @JvmInline
value class IntStorage( value class IntStorage(
val data: IntArray, override val data: IntArray,
) : MatrixStorage<Int> { ) : MatrixStorage<Int> {
override val size get() = data.size override val size get() = data.size
@@ -2,7 +2,7 @@ package org.duckdns.davygora.matrix.storage
@JvmInline @JvmInline
value class LongStorage( value class LongStorage(
val data: LongArray, override val data: LongArray,
) : MatrixStorage<Long> { ) : MatrixStorage<Long> {
override val size get() = data.size override val size get() = data.size
@@ -1,6 +1,8 @@
package org.duckdns.davygora.matrix.storage package org.duckdns.davygora.matrix.storage
sealed interface MatrixStorage<T> { sealed interface MatrixStorage<T> {
val data: Any
val size: Int val size: Int
operator fun get(index: Int): T operator fun get(index: Int): T
@@ -12,8 +14,18 @@ sealed interface MatrixStorage<T> {
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
inline fun <reified T> List<T>.toMatrixStorage() = inline fun <reified T> List<T>.toMatrixStorage(): MatrixStorage<T> {
when (T::class) { 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() Boolean::class -> (this as List<Boolean>).toBooleanArray().toMatrixStorage()
Byte::class -> (this as List<Byte>).toByteArray().toMatrixStorage() Byte::class -> (this as List<Byte>).toByteArray().toMatrixStorage()
Char::class -> (this as List<Char>).toCharArray().toMatrixStorage() Char::class -> (this as List<Char>).toCharArray().toMatrixStorage()
@@ -24,3 +36,4 @@ inline fun <reified T> List<T>.toMatrixStorage() =
Short::class -> (this as List<Short>).toShortArray().toMatrixStorage() Short::class -> (this as List<Short>).toShortArray().toMatrixStorage()
else -> this.toTypedArray().toMatrixStorage() else -> this.toTypedArray().toMatrixStorage()
} as MatrixStorage<T> } as MatrixStorage<T>
}
@@ -2,7 +2,7 @@ package org.duckdns.davygora.matrix.storage
@JvmInline @JvmInline
value class ObjectStorage<T>( value class ObjectStorage<T>(
val data: Array<T>, override val data: Array<T>,
) : MatrixStorage<T> { ) : MatrixStorage<T> {
override val size get() = data.size override val size get() = data.size
@@ -2,7 +2,7 @@ package org.duckdns.davygora.matrix.storage
@JvmInline @JvmInline
value class ShortStorage( value class ShortStorage(
val data: ShortArray, override val data: ShortArray,
) : MatrixStorage<Short> { ) : MatrixStorage<Short> {
override val size get() = data.size override val size get() = data.size
@@ -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 }
}
}
})