Imported immutable version
This commit is contained in:
commit
d0327d0e90
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/.idea/
|
||||||
|
gradle/
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
*.class
|
||||||
|
*.jar
|
||||||
|
/out/
|
||||||
|
/gradlew*
|
||||||
|
.kotlin/
|
||||||
|
/kotlin-js-store
|
||||||
107
build.gradle.kts
Normal file
107
build.gradle.kts
Normal 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
1
gradle.properties
Normal file
@ -0,0 +1 @@
|
|||||||
|
kotlin.code.style=official
|
||||||
2
settings.gradle.kts
Normal file
2
settings.gradle.kts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
rootProject.name = "enumerated-collection"
|
||||||
|
|
||||||
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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))
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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) {
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user