Skip to content
This repository has been archived by the owner on Jul 8, 2022. It is now read-only.

Commit

Permalink
Fix issue #168: Change inline classes to value classes (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
arsvechkarev authored May 25, 2021
1 parent 1cc2e50 commit 0cf0081
Show file tree
Hide file tree
Showing 20 changed files with 51 additions and 25 deletions.
6 changes: 4 additions & 2 deletions klock/src/commonMain/kotlin/com/soywiz/klock/Date.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package com.soywiz.klock

import com.soywiz.klock.internal.Serializable
import kotlin.jvm.JvmInline
import kotlin.math.abs

/**
* Represents a triple of [year], [month] and [day].
*
* It is packed in an inline class wrapping an Int to prevent allocations.
* It is packed in a value class wrapping an Int to prevent allocations.
*/
inline class Date(val encoded: Int) : Comparable<Date>, Serializable {
@JvmInline
value class Date(val encoded: Int) : Comparable<Date>, Serializable {
companion object {
@Suppress("MayBeConstant", "unused")
private const val serialVersionUID = 1L
Expand Down
4 changes: 3 additions & 1 deletion klock/src/commonMain/kotlin/com/soywiz/klock/DateTime.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.soywiz.klock

import com.soywiz.klock.internal.*
import kotlin.jvm.JvmInline
import kotlin.math.*

/**
Expand All @@ -11,7 +12,8 @@ import kotlin.math.*
* - Thu Aug 10 -140744 07:15:45 GMT-0014 (Central European Summer Time)
* - Wed May 23 144683 18:29:30 GMT+0200 (Central European Summer Time)
*/
inline class DateTime(
@JvmInline
value class DateTime(
/** Number of milliseconds since UNIX [EPOCH] */
val unixMillis: Double
) : Comparable<DateTime>, Serializable {
Expand Down
4 changes: 3 additions & 1 deletion klock/src/commonMain/kotlin/com/soywiz/klock/Frequency.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.soywiz.klock

import com.soywiz.klock.hr.hr
import kotlin.jvm.JvmInline

val TimeSpan.hz get() = timesPerSecond
val Int.hz get() = timesPerSecond
Expand All @@ -12,7 +13,8 @@ val TimeSpan.timesPerSecond get() = Frequency(1.0 / this.seconds)
val Int.timesPerSecond get() = Frequency(this.toDouble())
val Double.timesPerSecond get() = Frequency(this)

inline class Frequency(val hertz: Double) {
@JvmInline
value class Frequency(val hertz: Double) {
companion object {
fun from(timeSpan: TimeSpan) = timeSpan.toFrequency()
}
Expand Down
4 changes: 3 additions & 1 deletion klock/src/commonMain/kotlin/com/soywiz/klock/MonthSpan.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.soywiz.klock

import com.soywiz.klock.internal.Serializable
import kotlin.jvm.JvmInline

/**
* Creates a [MonthSpan] representing these years.
Expand All @@ -15,7 +16,8 @@ inline val Int.months get() = MonthSpan(this)
/**
* Represents a number of years and months temporal distance.
*/
inline class MonthSpan(
@JvmInline
value class MonthSpan(
/** Total months of this [MonthSpan] as integer */
val totalMonths: Int
) : Comparable<MonthSpan>, Serializable {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.soywiz.klock

import kotlin.jvm.JvmInline

val infiniteTimes get() = NumberOfTimes.INFINITE
inline val Int.times get() = NumberOfTimes(this)

inline class NumberOfTimes(val count: Int) {
@JvmInline
value class NumberOfTimes(val count: Int) {
companion object {
val ZERO = NumberOfTimes(0)
val ONE = NumberOfTimes(1)
Expand Down
4 changes: 3 additions & 1 deletion klock/src/commonMain/kotlin/com/soywiz/klock/Time.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.soywiz.klock

import com.soywiz.klock.internal.Serializable
import kotlin.jvm.JvmInline
import kotlin.math.abs

/**
* Represents a union of [millisecond], [second], [minute] and [hour].
*/
inline class Time(val encoded: TimeSpan) : Comparable<Time>, Serializable {
@JvmInline
value class Time(val encoded: TimeSpan) : Comparable<Time>, Serializable {
companion object {
@Suppress("MayBeConstant", "unused")
private const val serialVersionUID = 1L
Expand Down
6 changes: 4 additions & 2 deletions klock/src/commonMain/kotlin/com/soywiz/klock/TimeSpan.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.soywiz.klock

import com.soywiz.klock.internal.*
import kotlin.jvm.JvmInline
import kotlin.math.*

/** [TimeSpan] representing this number as [nanoseconds] or 1 / 1_000_000_000 [seconds]. */
Expand Down Expand Up @@ -75,9 +76,10 @@ inline val Double.weeks get() = TimeSpan.fromWeeks(this)
/**
* Represents a span of time, with [milliseconds] precision.
*
* It is an inline class wrapping [Double] instead of [Long] to work on JavaScript without allocations.
* It is a value class wrapping [Double] instead of [Long] to work on JavaScript without allocations.
*/
inline class TimeSpan(
@JvmInline
value class TimeSpan(
/** Returns the total number of [milliseconds] for this [TimeSpan] (1 / 1_000 [seconds]) */
val milliseconds: Double
) : Comparable<TimeSpan>, Serializable {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.soywiz.klock

import com.soywiz.klock.internal.*
import kotlin.jvm.JvmInline
import kotlin.math.*

/**
Expand All @@ -9,7 +10,8 @@ import kotlin.math.*
*
* This class is inlined so no boxing should be required.
*/
inline class TimezoneOffset(
@JvmInline
value class TimezoneOffset(
/** [TimezoneOffset] in [totalMilliseconds] */
val totalMilliseconds: Double
) : Comparable<TimezoneOffset>, Serializable {
Expand Down
4 changes: 3 additions & 1 deletion klock/src/commonMain/kotlin/com/soywiz/klock/Year.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.soywiz.klock

import com.soywiz.klock.internal.Serializable
import kotlin.jvm.JvmInline
import kotlin.math.*

/**
Expand All @@ -11,7 +12,8 @@ import kotlin.math.*
*
* The integrated model is capable of determine if a year is leap for years 1 until 9999 inclusive.
*/
inline class Year(val year: Int) : Comparable<Year>, Serializable {
@JvmInline
value class Year(val year: Int) : Comparable<Year>, Serializable {
companion object {
@Suppress("MayBeConstant", "unused")
private const val serialVersionUID = 1L
Expand Down
6 changes: 4 additions & 2 deletions klock/src/commonMain/kotlin/com/soywiz/klock/YearMonth.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.soywiz.klock

import com.soywiz.klock.internal.Serializable
import kotlin.jvm.JvmInline

/**
* Represents a couple of [year] and [month].
*
* It is packed in an inline class wrapping an Int to prevent allocations.
* It is packed in a value class wrapping an Int to prevent allocations.
*/
inline class YearMonth(internal val internalPackedInfo: Int) : Serializable {
@JvmInline
value class YearMonth(internal val internalPackedInfo: Int) : Serializable {
companion object {
@Suppress("MayBeConstant", "unused")
private const val serialVersionUID = 1L
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.soywiz.klock.hr

import com.soywiz.klock.*
import kotlin.jvm.JvmInline
import kotlin.math.round

/** Converts a [TimeSpan] into a high-resolution [HRTimeSpan] */
Expand All @@ -11,7 +12,8 @@ val HRTimeSpan.timeSpan get() = nanosecondsRaw.nanoseconds

// @TODO: Ensure nanosecondsRaw has no decimals
/** A High-Resolution TimeSpan that stores its values as nanoseconds. Just uses 52-bits and won't store decimals */
inline class HRTimeSpan constructor(val nanosecondsRaw: Double) : Comparable<HRTimeSpan> {
@JvmInline
value class HRTimeSpan constructor(val nanosecondsRaw: Double) : Comparable<HRTimeSpan> {
companion object {
val ZERO = HRTimeSpan(0.0)
val NIL = HRTimeSpan(Double.NaN)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.soywiz.klock.internal

import kotlin.jvm.JvmInline

// Original implementation grabbed from Kds to prevent additional dependencies:
// - https://github.com/korlibs/kds/blob/965f6017d7ad82e4bad714acf26cd7189186bdb3/kds/src/commonMain/kotlin/com/soywiz/kds/_Extensions.kt#L48
internal inline fun genericBinarySearch(
Expand All @@ -24,7 +26,8 @@ internal inline fun genericBinarySearch(
return invalid(fromIndex, toIndex, low, high)
}

internal inline class BSearchResult(val raw: Int) {
@JvmInline
internal value class BSearchResult(val raw: Int) {
val found: Boolean get() = raw >= 0
val index: Int get() = if (found) raw else -1
val nearIndex: Int get() = if (found) raw else -raw - 1
Expand Down
4 changes: 2 additions & 2 deletions klock/src/commonMain/kotlin/com/soywiz/klock/wrapped/WDate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import com.soywiz.klock.internal.Serializable
val Date.wrapped get() = WDate(this)

/**
* Wrapped Version, that is not inline. You can use [value] to get the wrapped inline class.
* Wrapped Version, that is not inline. You can use [value] to get the wrapped value class.
*
* Represents a triple of [year], [month] and [day].
*
* It is packed in an inline class wrapping an Int to prevent allocations.
* It is packed in a value class wrapping an Int to prevent allocations.
*/
@KlockExperimental
data class WDate(val value: Date) : Comparable<WDate>, Serializable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.soywiz.klock.internal.*
val DateTime.wrapped get() = WDateTime(this)

/**
* Wrapped Version, that is not inline. You can use [value] to get the wrapped inline class.
* Wrapped Version, that is not inline. You can use [value] to get the wrapped value class.
*
* Represents a Date in UTC (GMT+00) with millisecond precision.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.soywiz.klock.internal.Serializable
val MonthSpan.wrapped get() = WMonthSpan(this)

/**
* Wrapped Version, that is not inline. You can use [value] to get the wrapped inline class.
* Wrapped Version, that is not inline. You can use [value] to get the wrapped value class.
*
* Represents a number of years and months temporal distance.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.soywiz.klock.internal.Serializable
val Time.wrapped get() = WTime(this)

/**
* Wrapped Version, that is not inline. You can use [value] to get the wrapped inline class.
* Wrapped Version, that is not inline. You can use [value] to get the wrapped value class.
*
* Represents a union of [millisecond], [second], [minute] and [hour].
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import com.soywiz.klock.internal.*
val TimeSpan.wrapped get() = WTimeSpan(this)

/**
* Wrapped Version, that is not inline. You can use [value] to get the wrapped inline class.
* Wrapped Version, that is not inline. You can use [value] to get the wrapped value class.
*
* Represents a span of time, with [milliseconds] precision.
*
* It is an inline class wrapping [Double] instead of [Long] to work on JavaScript without allocations.
* It is a value class wrapping [Double] instead of [Long] to work on JavaScript without allocations.
*/
@KlockExperimental
data class WTimeSpan(val value: TimeSpan) : Comparable<WTimeSpan>, Serializable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.soywiz.klock.internal.Serializable
val TimezoneOffset.wrapped get() = WTimezoneOffset(this)

/**
* Wrapped Version, that is not inline. You can use [value] to get the wrapped inline class.
* Wrapped Version, that is not inline. You can use [value] to get the wrapped value class.
*
* Represents a time zone offset with millisecond precision. Usually minute is enough.
* Can be used along [WDateTimeTz] to construct non universal, local times.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.soywiz.klock.internal.Serializable
val Year.wrapped get() = WYear(this)

/**
* Wrapped Version, that is not inline. You can use [value] to get the wrapped inline class.
* Wrapped Version, that is not inline. You can use [value] to get the wrapped value class.
*
* Represents a Year in a typed way.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.soywiz.klock.internal.Serializable
val YearMonth.wrapped get() = WYearMonth(this)

/**
* Wrapped Version, that is not inline. You can use [value] to get the wrapped inline class.
* Wrapped Version, that is not inline. You can use [value] to get the wrapped value class.
*
* Represents a couple of [year] and [month].
*/
Expand Down

0 comments on commit 0cf0081

Please sign in to comment.