Imported immutable version

This commit is contained in:
Andrew Golovashevich 2025-08-16 23:53:40 +03:00
commit d0327d0e90
9 changed files with 348 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
/.idea/
gradle/
.gradle/
build/
*.class
*.jar
/out/
/gradlew*
.kotlin/
/kotlin-js-store

107
build.gradle.kts Normal file
View File

@ -0,0 +1,107 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import ru.landgrafhomyak.kotlin.kmp_gradle_build_helper.*
import ru.landgrafhomyak.kotlin.kmp_gradle_build_helper.plugin.xomrk
buildscript {
repositories {
mavenCentral()
maven("https://maven.landgrafhomyak.ru/")
}
dependencies {
classpath("ru.landgrafhomyak.kotlin:kotlin-mpp-gradle-build:v0.3k2.1.10")
}
}
group = "ru.landgrafhomyak.utility"
version = "0.1"
repositories {
mavenCentral()
}
xomrk {
kotlin {
setCompatibilityWithKotlin(KotlinVersion.KOTLIN_2_0)
optInContracts()
explicitApi()
noWarnExpectActual()
warningsAsErrors()
defineAllMultiplatformTargets()
jvmToolchain(11)
jvm {
withJava()
compilations.configureEach {
compileJavaTaskProvider?.configure {
targetCompatibility = "1.8"
}
compileTaskProvider.configure {
compilerOptions {
jvmTarget = JvmTarget.JVM_1_8
freeCompilerArgs.addAll(
"-Xno-call-assertions",
"-Xno-param-assertions",
"-Xno-receiver-assertions"
)
}
}
}
tasks.named { t -> t == "${this@jvm.name}Test" }.configureEach {
this as Test
useTestNG()
}
}
sourceSets {
// if use kotlin("stdlib") gitea ui brokes at paragraph with dependency versions
val kotlinStdlibDependency = "org.jetbrains.kotlin:kotlin-stdlib:${this@kotlin.coreLibrariesVersion}"
val commonMain by getting {
dependencies {
compileOnly(kotlinStdlibDependency)
}
}
val jvmMain by getting {
dependsOn(commonMain)
dependencies {
compileOnly(kotlinStdlibDependency)
}
}
val nonJvmMain by creating {
dependsOn(commonMain)
dependencies {
implementation(kotlinStdlibDependency)
}
}
jvmTest {
dependencies {
implementation("org.testng:testng:7.5.1")
}
}
configureEach {
when {
// commonMain !in dependsOn -> return@configureEach
!name.endsWith("Main") -> return@configureEach
this@configureEach === commonMain -> return@configureEach
this@configureEach === jvmMain -> return@configureEach
this@configureEach === nonJvmMain -> return@configureEach
}
dependsOn(nonJvmMain)
}
}
}
publishing {
repositories {
defineXomrkGiteaMavenRepo()
}
}
}

1
gradle.properties Normal file
View File

@ -0,0 +1 @@
kotlin.code.style=official

2
settings.gradle.kts Normal file
View File

@ -0,0 +1,2 @@
rootProject.name = "enumerated-collection"

View File

@ -0,0 +1,166 @@
package ru.landgrafhomyak.utility.enumerated_collection
import kotlin.jvm.JvmStatic
internal abstract class EnumeratedCollection<E : Any>(
private val _data: Array<out E>,
) : List<E> {
protected abstract fun _getElementOrdinal(e: E): Int
abstract override fun toString(): String
override val size: Int
get() = this._data.size
override operator fun contains(element: E): Boolean {
_Platform.jvm_assertNotNull(element, "param: element")
val ordinal = this._getElementOrdinal(element)
if (ordinal >= this.size)
return false
if (ordinal < 0)
throw IllegalArgumentException("Negative ordinal")
return element === this._data[ordinal]
}
override fun containsAll(elements: Collection<E>): Boolean {
_Platform.jvm_assertNotNull(elements, "param: elements")
if (elements === this) return true
return elements.all(this::contains)
}
override fun isEmpty(): Boolean = this._data.isEmpty()
fun isNotEmpty(): Boolean = this._data.isNotEmpty()
override operator fun iterator(): Iterator<E> = this._data.iterator()
override operator fun get(ordinal: Int): E {
if (ordinal >= this.size)
throw IllegalArgumentException("Ordinal out of bounds, are you sure that ordinal owner from this enum?")
if (ordinal < 0)
throw IllegalArgumentException("Negative ordinal")
return this._data[ordinal]
}
override fun indexOf(element: E): Int {
_Platform.jvm_assertNotNull(element, "param: element")
@Suppress("LiftReturnOrAssignment")
if (element in this)
return this._getElementOrdinal(element)
else
return -1
}
override fun lastIndexOf(element: E): Int =
this.indexOf(element)
override fun listIterator(): ListIterator<E> = this.ListIteratorImpl(0)
override fun listIterator(index: Int): ListIterator<E> = this.ListIteratorImpl(index)
override fun subList(fromIndex: Int, toIndex: Int): List<E> =
this.SublistView(fromIndex, toIndex)
private object Empty : EnumeratedCollection<Any>(emptyArray<Any>()) {
override fun toString(): String = "<empty dynamic enum>"
override fun _getElementOrdinal(e: Any): Int = throw IllegalArgumentException("This method unexpected to be invoked")
}
companion object {
@Suppress("UNCHECKED_CAST")
@JvmStatic
fun <T : Any> empty(): EnumeratedCollection<T> = Empty as EnumeratedCollection<T>
}
private inner class ListIteratorImpl(private var nextPos: Int) : ListIterator<E> {
override fun next(): E {
if (!this.hasNext()) throw IllegalStateException("Iteration ended")
return this@EnumeratedCollection._data[this.nextPos++]
}
override fun hasNext(): Boolean =
this.nextPos < this@EnumeratedCollection._data.size
override fun hasPrevious(): Boolean = this.nextPos > 0
override fun previous(): E {
if (!this.hasNext()) throw IllegalStateException("Collection start reached")
return this@EnumeratedCollection._data[--this.nextPos]
}
override fun nextIndex(): Int = this.nextPos
override fun previousIndex(): Int = this.nextPos - 1
}
private inner class SublistView(
private val _start: Int,
private val _end: Int,
) : List<E> {
init {
require(this._start <= this._end) { "fromIndex should be greater than toIndex: ${this._start} > ${this._end}" }
}
override val size: Int = this._end - this._start
@Suppress("ReplaceSizeCheckWithIsNotEmpty")
override fun isEmpty(): Boolean = this.size != 0
override fun contains(element: E): Boolean {
_Platform.jvm_assertNotNull(element, "param: element")
if (element !in this@EnumeratedCollection) return false
return this@EnumeratedCollection._getElementOrdinal(element) in (this._start..<this._end)
}
override fun iterator(): Iterator<E> = this.listIterator()
override fun containsAll(elements: Collection<E>): Boolean {
_Platform.jvm_assertNotNull(elements, "param: elements")
if (elements === this) return true
return elements.all(this::contains)
}
override fun get(index: Int): E = this@EnumeratedCollection[this._start + index]
override fun indexOf(element: E): Int {
_Platform.jvm_assertNotNull(element, "param: element")
if (element !in this) return -1
return this@EnumeratedCollection._getElementOrdinal(element) - this._start
}
override fun lastIndexOf(element: E): Int =
this.indexOf(element)
override fun listIterator(): ListIterator<E> = SublistIteratorImpl(this._start)
override fun listIterator(index: Int): ListIterator<E> = SublistIteratorImpl(this._start + index)
override fun subList(fromIndex: Int, toIndex: Int): List<E> =
this@EnumeratedCollection.SublistView(this._start + fromIndex, this._start + toIndex)
private inner class SublistIteratorImpl(private var nextPos: Int) : ListIterator<E> {
override fun next(): E {
if (!this.hasNext()) throw IllegalStateException("Iteration ended")
return this@EnumeratedCollection._data[this.nextPos++]
}
override fun hasNext(): Boolean =
this.nextPos < this@SublistView._end
override fun hasPrevious(): Boolean = this.nextPos > this@SublistView._start
override fun previous(): E {
if (!this.hasNext()) throw IllegalStateException("Collection start reached")
return this@EnumeratedCollection._data[--this.nextPos]
}
override fun nextIndex(): Int = this.nextPos - this@SublistView._start
override fun previousIndex(): Int = this.nextPos - 1 - this@SublistView._start
}
}
}

View File

@ -0,0 +1,7 @@
package ru.landgrafhomyak.utility.enumerated_collection
@PublishedApi
internal expect object _Platform {
@PublishedApi
internal inline fun jvm_assertNotNull(x: Any?, name: String)
}

View File

@ -0,0 +1,17 @@
package ru.landgrafhomyak.utility.enumerated_collection
import java.util.Objects
import kotlin.contracts.contract
@PublishedApi
internal actual object _Platform {
@Suppress("NOTHING_TO_INLINE")
@JvmStatic
@PublishedApi
internal actual inline fun jvm_assertNotNull(x: Any?, name: String) {
contract {
returns().implies(x != null)
}
Objects.requireNonNull(x, name)
}
}

View File

@ -0,0 +1,28 @@
package ru.landgrafhomyak.utility.enumerated_collection.tests
import org.testng.annotations.Test
import ru.landgrafhomyak.utility.enumerated_collection.EnumeratedCollection
@Test
class KotlinStdlibDependencyTest {
@Test
fun testNoKotlinStdlib() {
try {
if (KotlinVersion.CURRENT.major != -1)
throw AssertionError("Kotlin stdlib still in runtime classpath")
} catch (_: LinkageError) {
}
}
private class IntCollection(_data: Array<out Int>) : EnumeratedCollection<Int>(_data) {
override fun _getElementOrdinal(e: Int): Int = e
override fun toString(): String = "<test collection>"
}
@Test(dependsOnMethods = ["testNoKotlinStdlib"])
fun testCreationEmpty() {
IntCollection(arrayOf(1, 2, 3, 4))
}
}

View File

@ -0,0 +1,10 @@
package ru.landgrafhomyak.utility.enumerated_collection
@PublishedApi
internal actual object _Platform {
@Suppress("NOTHING_TO_INLINE")
@PublishedApi
internal actual inline fun jvm_assertNotNull(x: Any?, name: String) {
}
}