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