From f84f71938516192dc66ddc6f9707091dc6a2dbed Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Thu, 7 Jan 2021 17:26:16 +0700 Subject: [PATCH] Add GSL objects disposition check, add missing newline, improve tests --- .../kscience/kmath/gsl/codegen/PsiTestUtil.kt | 2 +- .../kmath/gsl/codegen/matricesCodegen.kt | 18 +-- .../kmath/gsl/codegen/vectorsCodegen.kt | 18 ++- .../kscience/kmath/gsl/GslMemoryHolder.kt | 14 +- .../kotlin/kscience/kmath/gsl/_Matrices.kt | 128 +++++++++--------- .../kotlin/kscience/kmath/gsl/_Vectors.kt | 96 ++++++------- ...{ErrorHandler.kt => ErrorsHandlingTest.kt} | 12 +- .../nativeTest/kotlin/GslMatrixRealTest.kt | 23 ++++ ...extTest.kt => GslRealMatrixContextTest.kt} | 11 +- 9 files changed, 187 insertions(+), 135 deletions(-) rename kmath-gsl/src/nativeTest/kotlin/{ErrorHandler.kt => ErrorsHandlingTest.kt} (50%) rename kmath-gsl/src/nativeTest/kotlin/{GslRealContextTest.kt => GslRealMatrixContextTest.kt} (86%) diff --git a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/PsiTestUtil.kt b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/PsiTestUtil.kt index 2981b9502..e38d93323 100644 --- a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/PsiTestUtil.kt +++ b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/PsiTestUtil.kt @@ -70,4 +70,4 @@ internal object PsiTestUtil { if (dummyCopy is PsiFileImpl) dummyCopy.originalFile = file return dummyCopy } -} \ No newline at end of file +} diff --git a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt index 56a563f84..84391181c 100644 --- a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt +++ b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt @@ -23,33 +23,35 @@ private fun KtPsiFactory.createMatrixClass( scope: DeferScope ) : GslMatrix<$kotlinTypeName, $structName>(scope) { override val rowNum: Int - get() = nativeHandle.pointed.size1.toInt() + get() = nativeHandleChecked().pointed.size1.toInt() override val colNum: Int - get() = nativeHandle.pointed.size2.toInt() + get() = nativeHandleChecked().pointed.size2.toInt() override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): $className = - ${className}(nativeHandle, this.features + features, scope) + ${className}(nativeHandleChecked(), this.features + features, scope) override operator fun get(i: Int, j: Int): $kotlinTypeName = ${ fn("gsl_matrixRget", cTypeName) - }(nativeHandle, i.toULong(), j.toULong()) + }(nativeHandleChecked(), i.toULong(), j.toULong()) override operator fun set(i: Int, j: Int, value: ${kotlinTypeName}): Unit = - ${fn("gsl_matrixRset", cTypeName)}(nativeHandle, i.toULong(), j.toULong(), value) + ${fn("gsl_matrixRset", cTypeName)}(nativeHandleChecked(), i.toULong(), j.toULong(), value) override fun copy(): $className { val new = requireNotNull(${fn("gsl_matrixRalloc", cTypeName)}(rowNum.toULong(), colNum.toULong())) - ${fn("gsl_matrixRmemcpy", cTypeName)}(new, nativeHandle) + ${fn("gsl_matrixRmemcpy", cTypeName)}(new, nativeHandleChecked()) return $className(new, features, scope) } - override fun close(): Unit = ${fn("gsl_matrixRfree", cTypeName)}(nativeHandle) + override fun close(): Unit = ${fn("gsl_matrixRfree", cTypeName)}(nativeHandleChecked()) override fun equals(other: Any?): Boolean { - if (other is $className) return ${fn("gsl_matrixRequal", cTypeName)}(nativeHandle, other.nativeHandle) == 1 + if (other is $className) return ${ + fn("gsl_matrixRequal", cTypeName) + }(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } }""" diff --git a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt index 2f4a06475..2139489d1 100644 --- a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt +++ b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt @@ -21,25 +21,31 @@ private fun KtPsiFactory.createVectorClass( """internal class $className(override val nativeHandle: CPointer<$structName>, scope: DeferScope) : GslVector<$kotlinTypeName, $structName>(scope) { override val size: Int - get() = nativeHandle.pointed.size.toInt() + get() = nativeHandleChecked().pointed.size.toInt() - override fun get(index: Int): $kotlinTypeName = ${fn("gsl_vectorRget", cTypeName)}(nativeHandle, index.toULong()) + override fun get(index: Int): $kotlinTypeName = ${ + fn("gsl_vectorRget", + cTypeName) + }(nativeHandleChecked(), index.toULong()) override fun set(index: Int, value: $kotlinTypeName): Unit = ${ fn("gsl_vectorRset", cTypeName) - }(nativeHandle, index.toULong(), value) + }(nativeHandleChecked(), index.toULong(), value) override fun copy(): $className { val new = requireNotNull(${fn("gsl_vectorRalloc", cTypeName)}(size.toULong())) - ${fn("gsl_vectorRmemcpy", cTypeName)}(new, nativeHandle) + ${fn("gsl_vectorRmemcpy", cTypeName)}(new, nativeHandleChecked()) return ${className}(new, scope) } override fun equals(other: Any?): Boolean { - if (other is $className) return ${fn("gsl_vectorRequal", cTypeName)}(nativeHandle, other.nativeHandle) == 1 + if (other is $className) return ${ + fn("gsl_vectorRequal", + cTypeName) + }(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } - override fun close(): Unit = ${fn("gsl_vectorRfree", cTypeName)}(nativeHandle) + override fun close(): Unit = ${fn("gsl_vectorRfree", cTypeName)}(nativeHandleChecked()) }""" f += createClass(text) diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt index 15ee384b5..d68a52a62 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt @@ -8,14 +8,26 @@ import kotlinx.cinterop.DeferScope * Represents managed native GSL object. The only property this class holds is pointer to the GSL object. In order to be * freed this class's object must be added to [DeferScope]. * + * The objects of this type shouldn't be used after being disposed by the scope. + * * @param scope the scope where this object is declared. */ public abstract class GslMemoryHolder internal constructor(internal val scope: DeferScope) { internal abstract val nativeHandle: CPointer + private var isClosed: Boolean = false init { ensureHasGslErrorHandler() - scope.defer(::close) + + scope.defer { + close() + isClosed = true + } + } + + internal fun nativeHandleChecked(): CPointer { + check(!isClosed) { "The use of GSL object that is closed." } + return nativeHandle } internal abstract fun close() diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt index a38534515..e8c98a9fd 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt @@ -10,31 +10,31 @@ internal class GslRealMatrix( scope: DeferScope ) : GslMatrix(scope) { override val rowNum: Int - get() = nativeHandle.pointed.size1.toInt() + get() = nativeHandleChecked().pointed.size1.toInt() override val colNum: Int - get() = nativeHandle.pointed.size2.toInt() + get() = nativeHandleChecked().pointed.size2.toInt() override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslRealMatrix = - GslRealMatrix(nativeHandle, this.features + features, scope) + GslRealMatrix(nativeHandleChecked(), this.features + features, scope) - override operator fun get(i: Int, j: Int): Double = gsl_matrix_get(nativeHandle, i.toULong(), j.toULong()) + override operator fun get(i: Int, j: Int): Double = gsl_matrix_get(nativeHandleChecked(), i.toULong(), j.toULong()) override operator fun set(i: Int, j: Int, value: Double): Unit = - gsl_matrix_set(nativeHandle, i.toULong(), j.toULong(), value) + gsl_matrix_set(nativeHandleChecked(), i.toULong(), j.toULong(), value) override fun copy(): GslRealMatrix { val new = requireNotNull(gsl_matrix_alloc(rowNum.toULong(), colNum.toULong())) - gsl_matrix_memcpy(new, nativeHandle) + gsl_matrix_memcpy(new, nativeHandleChecked()) return GslRealMatrix(new, features, scope) } - override fun close(): Unit = gsl_matrix_free(nativeHandle) + override fun close(): Unit = gsl_matrix_free(nativeHandleChecked()) override fun equals(other: Any?): Boolean { - if (other is GslRealMatrix) return gsl_matrix_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslRealMatrix) return gsl_matrix_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } } @@ -45,31 +45,31 @@ internal class GslFloatMatrix( scope: DeferScope ) : GslMatrix(scope) { override val rowNum: Int - get() = nativeHandle.pointed.size1.toInt() + get() = nativeHandleChecked().pointed.size1.toInt() override val colNum: Int - get() = nativeHandle.pointed.size2.toInt() + get() = nativeHandleChecked().pointed.size2.toInt() override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslFloatMatrix = - GslFloatMatrix(nativeHandle, this.features + features, scope) + GslFloatMatrix(nativeHandleChecked(), this.features + features, scope) - override operator fun get(i: Int, j: Int): Float = gsl_matrix_float_get(nativeHandle, i.toULong(), j.toULong()) + override operator fun get(i: Int, j: Int): Float = gsl_matrix_float_get(nativeHandleChecked(), i.toULong(), j.toULong()) override operator fun set(i: Int, j: Int, value: Float): Unit = - gsl_matrix_float_set(nativeHandle, i.toULong(), j.toULong(), value) + gsl_matrix_float_set(nativeHandleChecked(), i.toULong(), j.toULong(), value) override fun copy(): GslFloatMatrix { val new = requireNotNull(gsl_matrix_float_alloc(rowNum.toULong(), colNum.toULong())) - gsl_matrix_float_memcpy(new, nativeHandle) + gsl_matrix_float_memcpy(new, nativeHandleChecked()) return GslFloatMatrix(new, features, scope) } - override fun close(): Unit = gsl_matrix_float_free(nativeHandle) + override fun close(): Unit = gsl_matrix_float_free(nativeHandleChecked()) override fun equals(other: Any?): Boolean { - if (other is GslFloatMatrix) return gsl_matrix_float_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslFloatMatrix) return gsl_matrix_float_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } } @@ -80,31 +80,31 @@ internal class GslShortMatrix( scope: DeferScope ) : GslMatrix(scope) { override val rowNum: Int - get() = nativeHandle.pointed.size1.toInt() + get() = nativeHandleChecked().pointed.size1.toInt() override val colNum: Int - get() = nativeHandle.pointed.size2.toInt() + get() = nativeHandleChecked().pointed.size2.toInt() override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslShortMatrix = - GslShortMatrix(nativeHandle, this.features + features, scope) + GslShortMatrix(nativeHandleChecked(), this.features + features, scope) - override operator fun get(i: Int, j: Int): Short = gsl_matrix_short_get(nativeHandle, i.toULong(), j.toULong()) + override operator fun get(i: Int, j: Int): Short = gsl_matrix_short_get(nativeHandleChecked(), i.toULong(), j.toULong()) override operator fun set(i: Int, j: Int, value: Short): Unit = - gsl_matrix_short_set(nativeHandle, i.toULong(), j.toULong(), value) + gsl_matrix_short_set(nativeHandleChecked(), i.toULong(), j.toULong(), value) override fun copy(): GslShortMatrix { val new = requireNotNull(gsl_matrix_short_alloc(rowNum.toULong(), colNum.toULong())) - gsl_matrix_short_memcpy(new, nativeHandle) + gsl_matrix_short_memcpy(new, nativeHandleChecked()) return GslShortMatrix(new, features, scope) } - override fun close(): Unit = gsl_matrix_short_free(nativeHandle) + override fun close(): Unit = gsl_matrix_short_free(nativeHandleChecked()) override fun equals(other: Any?): Boolean { - if (other is GslShortMatrix) return gsl_matrix_short_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslShortMatrix) return gsl_matrix_short_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } } @@ -115,31 +115,31 @@ internal class GslUShortMatrix( scope: DeferScope ) : GslMatrix(scope) { override val rowNum: Int - get() = nativeHandle.pointed.size1.toInt() + get() = nativeHandleChecked().pointed.size1.toInt() override val colNum: Int - get() = nativeHandle.pointed.size2.toInt() + get() = nativeHandleChecked().pointed.size2.toInt() override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslUShortMatrix = - GslUShortMatrix(nativeHandle, this.features + features, scope) + GslUShortMatrix(nativeHandleChecked(), this.features + features, scope) - override operator fun get(i: Int, j: Int): UShort = gsl_matrix_ushort_get(nativeHandle, i.toULong(), j.toULong()) + override operator fun get(i: Int, j: Int): UShort = gsl_matrix_ushort_get(nativeHandleChecked(), i.toULong(), j.toULong()) override operator fun set(i: Int, j: Int, value: UShort): Unit = - gsl_matrix_ushort_set(nativeHandle, i.toULong(), j.toULong(), value) + gsl_matrix_ushort_set(nativeHandleChecked(), i.toULong(), j.toULong(), value) override fun copy(): GslUShortMatrix { val new = requireNotNull(gsl_matrix_ushort_alloc(rowNum.toULong(), colNum.toULong())) - gsl_matrix_ushort_memcpy(new, nativeHandle) + gsl_matrix_ushort_memcpy(new, nativeHandleChecked()) return GslUShortMatrix(new, features, scope) } - override fun close(): Unit = gsl_matrix_ushort_free(nativeHandle) + override fun close(): Unit = gsl_matrix_ushort_free(nativeHandleChecked()) override fun equals(other: Any?): Boolean { - if (other is GslUShortMatrix) return gsl_matrix_ushort_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslUShortMatrix) return gsl_matrix_ushort_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } } @@ -150,31 +150,31 @@ internal class GslLongMatrix( scope: DeferScope ) : GslMatrix(scope) { override val rowNum: Int - get() = nativeHandle.pointed.size1.toInt() + get() = nativeHandleChecked().pointed.size1.toInt() override val colNum: Int - get() = nativeHandle.pointed.size2.toInt() + get() = nativeHandleChecked().pointed.size2.toInt() override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslLongMatrix = - GslLongMatrix(nativeHandle, this.features + features, scope) + GslLongMatrix(nativeHandleChecked(), this.features + features, scope) - override operator fun get(i: Int, j: Int): Long = gsl_matrix_long_get(nativeHandle, i.toULong(), j.toULong()) + override operator fun get(i: Int, j: Int): Long = gsl_matrix_long_get(nativeHandleChecked(), i.toULong(), j.toULong()) override operator fun set(i: Int, j: Int, value: Long): Unit = - gsl_matrix_long_set(nativeHandle, i.toULong(), j.toULong(), value) + gsl_matrix_long_set(nativeHandleChecked(), i.toULong(), j.toULong(), value) override fun copy(): GslLongMatrix { val new = requireNotNull(gsl_matrix_long_alloc(rowNum.toULong(), colNum.toULong())) - gsl_matrix_long_memcpy(new, nativeHandle) + gsl_matrix_long_memcpy(new, nativeHandleChecked()) return GslLongMatrix(new, features, scope) } - override fun close(): Unit = gsl_matrix_long_free(nativeHandle) + override fun close(): Unit = gsl_matrix_long_free(nativeHandleChecked()) override fun equals(other: Any?): Boolean { - if (other is GslLongMatrix) return gsl_matrix_long_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslLongMatrix) return gsl_matrix_long_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } } @@ -185,31 +185,31 @@ internal class GslULongMatrix( scope: DeferScope ) : GslMatrix(scope) { override val rowNum: Int - get() = nativeHandle.pointed.size1.toInt() + get() = nativeHandleChecked().pointed.size1.toInt() override val colNum: Int - get() = nativeHandle.pointed.size2.toInt() + get() = nativeHandleChecked().pointed.size2.toInt() override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslULongMatrix = - GslULongMatrix(nativeHandle, this.features + features, scope) + GslULongMatrix(nativeHandleChecked(), this.features + features, scope) - override operator fun get(i: Int, j: Int): ULong = gsl_matrix_ulong_get(nativeHandle, i.toULong(), j.toULong()) + override operator fun get(i: Int, j: Int): ULong = gsl_matrix_ulong_get(nativeHandleChecked(), i.toULong(), j.toULong()) override operator fun set(i: Int, j: Int, value: ULong): Unit = - gsl_matrix_ulong_set(nativeHandle, i.toULong(), j.toULong(), value) + gsl_matrix_ulong_set(nativeHandleChecked(), i.toULong(), j.toULong(), value) override fun copy(): GslULongMatrix { val new = requireNotNull(gsl_matrix_ulong_alloc(rowNum.toULong(), colNum.toULong())) - gsl_matrix_ulong_memcpy(new, nativeHandle) + gsl_matrix_ulong_memcpy(new, nativeHandleChecked()) return GslULongMatrix(new, features, scope) } - override fun close(): Unit = gsl_matrix_ulong_free(nativeHandle) + override fun close(): Unit = gsl_matrix_ulong_free(nativeHandleChecked()) override fun equals(other: Any?): Boolean { - if (other is GslULongMatrix) return gsl_matrix_ulong_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslULongMatrix) return gsl_matrix_ulong_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } } @@ -220,31 +220,31 @@ internal class GslIntMatrix( scope: DeferScope ) : GslMatrix(scope) { override val rowNum: Int - get() = nativeHandle.pointed.size1.toInt() + get() = nativeHandleChecked().pointed.size1.toInt() override val colNum: Int - get() = nativeHandle.pointed.size2.toInt() + get() = nativeHandleChecked().pointed.size2.toInt() override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslIntMatrix = - GslIntMatrix(nativeHandle, this.features + features, scope) + GslIntMatrix(nativeHandleChecked(), this.features + features, scope) - override operator fun get(i: Int, j: Int): Int = gsl_matrix_int_get(nativeHandle, i.toULong(), j.toULong()) + override operator fun get(i: Int, j: Int): Int = gsl_matrix_int_get(nativeHandleChecked(), i.toULong(), j.toULong()) override operator fun set(i: Int, j: Int, value: Int): Unit = - gsl_matrix_int_set(nativeHandle, i.toULong(), j.toULong(), value) + gsl_matrix_int_set(nativeHandleChecked(), i.toULong(), j.toULong(), value) override fun copy(): GslIntMatrix { val new = requireNotNull(gsl_matrix_int_alloc(rowNum.toULong(), colNum.toULong())) - gsl_matrix_int_memcpy(new, nativeHandle) + gsl_matrix_int_memcpy(new, nativeHandleChecked()) return GslIntMatrix(new, features, scope) } - override fun close(): Unit = gsl_matrix_int_free(nativeHandle) + override fun close(): Unit = gsl_matrix_int_free(nativeHandleChecked()) override fun equals(other: Any?): Boolean { - if (other is GslIntMatrix) return gsl_matrix_int_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslIntMatrix) return gsl_matrix_int_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } } @@ -255,31 +255,31 @@ internal class GslUIntMatrix( scope: DeferScope ) : GslMatrix(scope) { override val rowNum: Int - get() = nativeHandle.pointed.size1.toInt() + get() = nativeHandleChecked().pointed.size1.toInt() override val colNum: Int - get() = nativeHandle.pointed.size2.toInt() + get() = nativeHandleChecked().pointed.size2.toInt() override val features: Set = features override fun suggestFeature(vararg features: MatrixFeature): GslUIntMatrix = - GslUIntMatrix(nativeHandle, this.features + features, scope) + GslUIntMatrix(nativeHandleChecked(), this.features + features, scope) - override operator fun get(i: Int, j: Int): UInt = gsl_matrix_uint_get(nativeHandle, i.toULong(), j.toULong()) + override operator fun get(i: Int, j: Int): UInt = gsl_matrix_uint_get(nativeHandleChecked(), i.toULong(), j.toULong()) override operator fun set(i: Int, j: Int, value: UInt): Unit = - gsl_matrix_uint_set(nativeHandle, i.toULong(), j.toULong(), value) + gsl_matrix_uint_set(nativeHandleChecked(), i.toULong(), j.toULong(), value) override fun copy(): GslUIntMatrix { val new = requireNotNull(gsl_matrix_uint_alloc(rowNum.toULong(), colNum.toULong())) - gsl_matrix_uint_memcpy(new, nativeHandle) + gsl_matrix_uint_memcpy(new, nativeHandleChecked()) return GslUIntMatrix(new, features, scope) } - override fun close(): Unit = gsl_matrix_uint_free(nativeHandle) + override fun close(): Unit = gsl_matrix_uint_free(nativeHandleChecked()) override fun equals(other: Any?): Boolean { - if (other is GslUIntMatrix) return gsl_matrix_uint_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslUIntMatrix) return gsl_matrix_uint_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } } diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt index de2da97da..fb64773bd 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt @@ -6,176 +6,176 @@ import org.gnu.gsl.* internal class GslRealVector(override val nativeHandle: CPointer, scope: DeferScope) : GslVector(scope) { override val size: Int - get() = nativeHandle.pointed.size.toInt() + get() = nativeHandleChecked().pointed.size.toInt() - override fun get(index: Int): Double = gsl_vector_get(nativeHandle, index.toULong()) - override fun set(index: Int, value: Double): Unit = gsl_vector_set(nativeHandle, index.toULong(), value) + override fun get(index: Int): Double = gsl_vector_get(nativeHandleChecked(), index.toULong()) + override fun set(index: Int, value: Double): Unit = gsl_vector_set(nativeHandleChecked(), index.toULong(), value) override fun copy(): GslRealVector { val new = requireNotNull(gsl_vector_alloc(size.toULong())) - gsl_vector_memcpy(new, nativeHandle) + gsl_vector_memcpy(new, nativeHandleChecked()) return GslRealVector(new, scope) } override fun equals(other: Any?): Boolean { - if (other is GslRealVector) return gsl_vector_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslRealVector) return gsl_vector_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } - override fun close(): Unit = gsl_vector_free(nativeHandle) + override fun close(): Unit = gsl_vector_free(nativeHandleChecked()) } internal class GslFloatVector(override val nativeHandle: CPointer, scope: DeferScope) : GslVector(scope) { override val size: Int - get() = nativeHandle.pointed.size.toInt() + get() = nativeHandleChecked().pointed.size.toInt() - override fun get(index: Int): Float = gsl_vector_float_get(nativeHandle, index.toULong()) - override fun set(index: Int, value: Float): Unit = gsl_vector_float_set(nativeHandle, index.toULong(), value) + override fun get(index: Int): Float = gsl_vector_float_get(nativeHandleChecked(), index.toULong()) + override fun set(index: Int, value: Float): Unit = gsl_vector_float_set(nativeHandleChecked(), index.toULong(), value) override fun copy(): GslFloatVector { val new = requireNotNull(gsl_vector_float_alloc(size.toULong())) - gsl_vector_float_memcpy(new, nativeHandle) + gsl_vector_float_memcpy(new, nativeHandleChecked()) return GslFloatVector(new, scope) } override fun equals(other: Any?): Boolean { - if (other is GslFloatVector) return gsl_vector_float_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslFloatVector) return gsl_vector_float_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } - override fun close(): Unit = gsl_vector_float_free(nativeHandle) + override fun close(): Unit = gsl_vector_float_free(nativeHandleChecked()) } internal class GslShortVector(override val nativeHandle: CPointer, scope: DeferScope) : GslVector(scope) { override val size: Int - get() = nativeHandle.pointed.size.toInt() + get() = nativeHandleChecked().pointed.size.toInt() - override fun get(index: Int): Short = gsl_vector_short_get(nativeHandle, index.toULong()) - override fun set(index: Int, value: Short): Unit = gsl_vector_short_set(nativeHandle, index.toULong(), value) + override fun get(index: Int): Short = gsl_vector_short_get(nativeHandleChecked(), index.toULong()) + override fun set(index: Int, value: Short): Unit = gsl_vector_short_set(nativeHandleChecked(), index.toULong(), value) override fun copy(): GslShortVector { val new = requireNotNull(gsl_vector_short_alloc(size.toULong())) - gsl_vector_short_memcpy(new, nativeHandle) + gsl_vector_short_memcpy(new, nativeHandleChecked()) return GslShortVector(new, scope) } override fun equals(other: Any?): Boolean { - if (other is GslShortVector) return gsl_vector_short_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslShortVector) return gsl_vector_short_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } - override fun close(): Unit = gsl_vector_short_free(nativeHandle) + override fun close(): Unit = gsl_vector_short_free(nativeHandleChecked()) } internal class GslUShortVector(override val nativeHandle: CPointer, scope: DeferScope) : GslVector(scope) { override val size: Int - get() = nativeHandle.pointed.size.toInt() + get() = nativeHandleChecked().pointed.size.toInt() - override fun get(index: Int): UShort = gsl_vector_ushort_get(nativeHandle, index.toULong()) - override fun set(index: Int, value: UShort): Unit = gsl_vector_ushort_set(nativeHandle, index.toULong(), value) + override fun get(index: Int): UShort = gsl_vector_ushort_get(nativeHandleChecked(), index.toULong()) + override fun set(index: Int, value: UShort): Unit = gsl_vector_ushort_set(nativeHandleChecked(), index.toULong(), value) override fun copy(): GslUShortVector { val new = requireNotNull(gsl_vector_ushort_alloc(size.toULong())) - gsl_vector_ushort_memcpy(new, nativeHandle) + gsl_vector_ushort_memcpy(new, nativeHandleChecked()) return GslUShortVector(new, scope) } override fun equals(other: Any?): Boolean { - if (other is GslUShortVector) return gsl_vector_ushort_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslUShortVector) return gsl_vector_ushort_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } - override fun close(): Unit = gsl_vector_ushort_free(nativeHandle) + override fun close(): Unit = gsl_vector_ushort_free(nativeHandleChecked()) } internal class GslLongVector(override val nativeHandle: CPointer, scope: DeferScope) : GslVector(scope) { override val size: Int - get() = nativeHandle.pointed.size.toInt() + get() = nativeHandleChecked().pointed.size.toInt() - override fun get(index: Int): Long = gsl_vector_long_get(nativeHandle, index.toULong()) - override fun set(index: Int, value: Long): Unit = gsl_vector_long_set(nativeHandle, index.toULong(), value) + override fun get(index: Int): Long = gsl_vector_long_get(nativeHandleChecked(), index.toULong()) + override fun set(index: Int, value: Long): Unit = gsl_vector_long_set(nativeHandleChecked(), index.toULong(), value) override fun copy(): GslLongVector { val new = requireNotNull(gsl_vector_long_alloc(size.toULong())) - gsl_vector_long_memcpy(new, nativeHandle) + gsl_vector_long_memcpy(new, nativeHandleChecked()) return GslLongVector(new, scope) } override fun equals(other: Any?): Boolean { - if (other is GslLongVector) return gsl_vector_long_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslLongVector) return gsl_vector_long_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } - override fun close(): Unit = gsl_vector_long_free(nativeHandle) + override fun close(): Unit = gsl_vector_long_free(nativeHandleChecked()) } internal class GslULongVector(override val nativeHandle: CPointer, scope: DeferScope) : GslVector(scope) { override val size: Int - get() = nativeHandle.pointed.size.toInt() + get() = nativeHandleChecked().pointed.size.toInt() - override fun get(index: Int): ULong = gsl_vector_ulong_get(nativeHandle, index.toULong()) - override fun set(index: Int, value: ULong): Unit = gsl_vector_ulong_set(nativeHandle, index.toULong(), value) + override fun get(index: Int): ULong = gsl_vector_ulong_get(nativeHandleChecked(), index.toULong()) + override fun set(index: Int, value: ULong): Unit = gsl_vector_ulong_set(nativeHandleChecked(), index.toULong(), value) override fun copy(): GslULongVector { val new = requireNotNull(gsl_vector_ulong_alloc(size.toULong())) - gsl_vector_ulong_memcpy(new, nativeHandle) + gsl_vector_ulong_memcpy(new, nativeHandleChecked()) return GslULongVector(new, scope) } override fun equals(other: Any?): Boolean { - if (other is GslULongVector) return gsl_vector_ulong_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslULongVector) return gsl_vector_ulong_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } - override fun close(): Unit = gsl_vector_ulong_free(nativeHandle) + override fun close(): Unit = gsl_vector_ulong_free(nativeHandleChecked()) } internal class GslIntVector(override val nativeHandle: CPointer, scope: DeferScope) : GslVector(scope) { override val size: Int - get() = nativeHandle.pointed.size.toInt() + get() = nativeHandleChecked().pointed.size.toInt() - override fun get(index: Int): Int = gsl_vector_int_get(nativeHandle, index.toULong()) - override fun set(index: Int, value: Int): Unit = gsl_vector_int_set(nativeHandle, index.toULong(), value) + override fun get(index: Int): Int = gsl_vector_int_get(nativeHandleChecked(), index.toULong()) + override fun set(index: Int, value: Int): Unit = gsl_vector_int_set(nativeHandleChecked(), index.toULong(), value) override fun copy(): GslIntVector { val new = requireNotNull(gsl_vector_int_alloc(size.toULong())) - gsl_vector_int_memcpy(new, nativeHandle) + gsl_vector_int_memcpy(new, nativeHandleChecked()) return GslIntVector(new, scope) } override fun equals(other: Any?): Boolean { - if (other is GslIntVector) return gsl_vector_int_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslIntVector) return gsl_vector_int_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } - override fun close(): Unit = gsl_vector_int_free(nativeHandle) + override fun close(): Unit = gsl_vector_int_free(nativeHandleChecked()) } internal class GslUIntVector(override val nativeHandle: CPointer, scope: DeferScope) : GslVector(scope) { override val size: Int - get() = nativeHandle.pointed.size.toInt() + get() = nativeHandleChecked().pointed.size.toInt() - override fun get(index: Int): UInt = gsl_vector_uint_get(nativeHandle, index.toULong()) - override fun set(index: Int, value: UInt): Unit = gsl_vector_uint_set(nativeHandle, index.toULong(), value) + override fun get(index: Int): UInt = gsl_vector_uint_get(nativeHandleChecked(), index.toULong()) + override fun set(index: Int, value: UInt): Unit = gsl_vector_uint_set(nativeHandleChecked(), index.toULong(), value) override fun copy(): GslUIntVector { val new = requireNotNull(gsl_vector_uint_alloc(size.toULong())) - gsl_vector_uint_memcpy(new, nativeHandle) + gsl_vector_uint_memcpy(new, nativeHandleChecked()) return GslUIntVector(new, scope) } override fun equals(other: Any?): Boolean { - if (other is GslUIntVector) return gsl_vector_uint_equal(nativeHandle, other.nativeHandle) == 1 + if (other is GslUIntVector) return gsl_vector_uint_equal(nativeHandleChecked(), other.nativeHandleChecked()) == 1 return super.equals(other) } - override fun close(): Unit = gsl_vector_uint_free(nativeHandle) + override fun close(): Unit = gsl_vector_uint_free(nativeHandleChecked()) } diff --git a/kmath-gsl/src/nativeTest/kotlin/ErrorHandler.kt b/kmath-gsl/src/nativeTest/kotlin/ErrorsHandlingTest.kt similarity index 50% rename from kmath-gsl/src/nativeTest/kotlin/ErrorHandler.kt rename to kmath-gsl/src/nativeTest/kotlin/ErrorsHandlingTest.kt index 0d8fbfbea..7d97eca85 100644 --- a/kmath-gsl/src/nativeTest/kotlin/ErrorHandler.kt +++ b/kmath-gsl/src/nativeTest/kotlin/ErrorsHandlingTest.kt @@ -4,7 +4,7 @@ import org.gnu.gsl.gsl_block_calloc import kotlin.test.Test import kotlin.test.assertFailsWith -internal class ErrorHandler { +internal class ErrorsHandlingTest { @Test fun blockAllocation() { assertFailsWith { @@ -19,4 +19,14 @@ internal class ErrorHandler { GslRealMatrixContext { produce(Int.MAX_VALUE, Int.MAX_VALUE) { _, _ -> 0.0 } } } } + + @Test + fun useOfClosedObject() { + val mat = GslRealMatrixContext { produce(1, 1) { _, _ -> 0.0 } } + assertFailsWith { mat.colNum } + assertFailsWith { mat.rowNum } + assertFailsWith { mat[0, 0] } + assertFailsWith { mat.copy() } + assertFailsWith { println(mat == mat) } + } } diff --git a/kmath-gsl/src/nativeTest/kotlin/GslMatrixRealTest.kt b/kmath-gsl/src/nativeTest/kotlin/GslMatrixRealTest.kt index b4ea4adb2..b4b446462 100644 --- a/kmath-gsl/src/nativeTest/kotlin/GslMatrixRealTest.kt +++ b/kmath-gsl/src/nativeTest/kotlin/GslMatrixRealTest.kt @@ -1,5 +1,9 @@ package kscience.kmath.gsl +import kscience.kmath.linear.RealMatrixContext +import kscience.kmath.operations.invoke +import kscience.kmath.structures.Matrix +import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals @@ -16,4 +20,23 @@ internal class GslMatrixRealTest { val mat = produce(1, 1) { _, _ -> 42.0 } assertEquals(42.0, mat[0, 0]) } + + @Test + fun copy() = GslRealMatrixContext { + val mat = produce(1, 1) { _, _ -> 42.0 } + assertEquals(mat, mat.copy()) + } + + @Test + fun equals() = GslRealMatrixContext { + var rng = Random(0) + val mat: Matrix = produce(2, 2) { _, _ -> rng.nextDouble() } + rng = Random(0) + val mat2: Matrix = RealMatrixContext { produce(2, 2) { _, _ -> rng.nextDouble() } } + rng = Random(0) + val mat3: Matrix = produce(2, 2) { _, _ -> rng.nextDouble() } + assertEquals(mat, mat2) + assertEquals(mat, mat3) + assertEquals(mat2, mat3) + } } diff --git a/kmath-gsl/src/nativeTest/kotlin/GslRealContextTest.kt b/kmath-gsl/src/nativeTest/kotlin/GslRealMatrixContextTest.kt similarity index 86% rename from kmath-gsl/src/nativeTest/kotlin/GslRealContextTest.kt rename to kmath-gsl/src/nativeTest/kotlin/GslRealMatrixContextTest.kt index 9ee543a13..c73cb2775 100644 --- a/kmath-gsl/src/nativeTest/kotlin/GslRealContextTest.kt +++ b/kmath-gsl/src/nativeTest/kotlin/GslRealMatrixContextTest.kt @@ -3,7 +3,6 @@ package kscience.kmath.gsl import kscience.kmath.linear.RealMatrixContext import kscience.kmath.operations.invoke import kscience.kmath.structures.Matrix -import kscience.kmath.structures.NDStructure import kscience.kmath.structures.RealBuffer import kscience.kmath.structures.asSequence import kotlin.random.Random @@ -12,11 +11,11 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue import kotlin.time.measureTime -internal class GslRealContextTest { +internal class GslRealMatrixContextTest { @Test fun testScale() = GslRealMatrixContext { val ma = produce(10, 10) { _, _ -> 0.1 } - val mb = (ma * 20.0) + val mb = ma * 20.0 assertEquals(mb[0, 1], 2.0) } @@ -42,7 +41,7 @@ internal class GslRealContextTest { @Test fun testManyCalls() = GslRealMatrixContext { - val expected = RealMatrixContext { + val expected: Matrix = RealMatrixContext { val rng = Random(0) var prod = produce(20, 20) { _, _ -> rng.nextDouble() } val mult = produce(20, 20) { _, _ -> rng.nextDouble() } @@ -51,9 +50,9 @@ internal class GslRealContextTest { } val rng = Random(0) - var prod = produce(20, 20) { _, _ -> rng.nextDouble() } + var prod: Matrix = produce(20, 20) { _, _ -> rng.nextDouble() } val mult = produce(20, 20) { _, _ -> rng.nextDouble() } measureTime { repeat(100) { prod = prod dot mult } }.also(::println) - assertTrue(NDStructure.equals(expected, prod)) + assertEquals(expected, prod) } }