Skip to content

Commit 3e7a02e

Browse files
committed
Add shift infex operators
Closes #66
1 parent 92c1413 commit 3e7a02e

File tree

4 files changed

+33
-12
lines changed

4 files changed

+33
-12
lines changed

README.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ val interval: IntInterval = interval( 0, 10, isEndIncluded = false )
1414
val areIncluded = 0 in interval && 5 in interval // true
1515
val areExcluded = 10 !in interval && 15 !in interval // true
1616
val size: UInt = interval.size // 10
17+
val shifted = interval shr 10u // Shifted right by 10: [10, 20)
1718
```
1819

1920
This protects against overflows (e.g. if `size > Int.MAX_VALUE`) but also offers better semantics.
@@ -24,6 +25,7 @@ val now = Clock.System.now()
2425
val interval: InstantInterval = interval( now, now + 100.seconds )
2526
val areIncluded = now + 50.seconds in interval // true
2627
val size: Duration = interval.size // 100 seconds
28+
val shifted = interval shr 24.hours // 100 seconds 24 hours from now
2729
```
2830

2931
## Interval Unions
@@ -36,6 +38,7 @@ Since operations are generally defined on the base interface, you can easily cha
3638
val start = interval( 0, 100 ) // Interval: [0, 100]
3739
val areIncluded = 50 in start && 100 in start // true
3840
val splitInTwo = start - interval( 25, 85 ) // Union: [[0, 25), (85, 100]]
41+
val shiftBackAndForth = splitInTwo shr 100u shl 100u // == splitInTwo
3942
val areExcluded = 50 !in splitInTwo && 85 !in splitInTwo // true
4043
val unite = splitInTwo + interval( 10, 90 ) // Interval: [0, 100]
4144
val backToStart = start == unite // true
@@ -63,18 +66,18 @@ Instead, new instances are returned if the operation results in a different set
6366

6467
The following operations are available for any `IntervalUnion<T, TSize>`:
6568

66-
| Operation | Description |
67-
|:-------------------:|:--------------------------------------------------------------------------------------------:|
68-
| `isEmpty()` | Determines whether this is an empty set. |
69-
| `getBounds()` | Gets the upper and lower bound of the set. |
70-
| `contains()` (`in`) | Determines whether a value lies in the set. |
71-
| `minus()` (`-`) | Subtract an interval from the set. |
72-
| `plus()` (`+`) | Add an interval to the set. |
73-
| `shift()` | Move the interval by a specified offset. |
74-
| `intersects()` | Determines whether another interval intersects with this set. |
75-
| `setEquals()` | Determines whether a set represents the same values. |
76-
| `iterator()` | Iterate over all intervals in the union, in order. |
77-
| `toString()` | Output as a string using common interval notation, e.g., `[0, 10]` or `[[0, 10), (10, 20]]`. |
69+
| Operation | Description |
70+
|:-----------------------:|:--------------------------------------------------------------------------------------------:|
71+
| `isEmpty()` | Determines whether this is an empty set. |
72+
| `getBounds()` | Gets the upper and lower bound of the set. |
73+
| `contains()` (`in`) | Determines whether a value lies in the set. |
74+
| `minus()` (`-`) | Subtract an interval from the set. |
75+
| `plus()` (`+`) | Add an interval to the set. |
76+
| `shift()` (`shl`/`shr`) | Move the interval by a specified offset. |
77+
| `intersects()` | Determines whether another interval intersects with this set. |
78+
| `setEquals()` | Determines whether a set represents the same values. |
79+
| `iterator()` | Iterate over all intervals in the union, in order. |
80+
| `toString()` | Output as a string using common interval notation, e.g., `[0, 10]` or `[[0, 10), (10, 20]]`. |
7881

7982
The following operations are specific to `Interval<T, TSize>`:
8083

kotlinx.interval.datetime/src/commonTest/kotlin/Readme.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package io.github.whathecode.kotlinx.interval.datetime
55
import kotlinx.datetime.Clock
66
import kotlin.test.*
77
import kotlin.time.Duration
8+
import kotlin.time.Duration.Companion.hours
89
import kotlin.time.Duration.Companion.seconds
910

1011

@@ -17,5 +18,6 @@ class Readme
1718
val interval: InstantInterval = interval( now, now + 100.seconds )
1819
val areIncluded = now + 50.seconds in interval // true
1920
val size: Duration = interval.size // 100 seconds
21+
val shifted = interval shr 24.hours // 100 seconds 24 hours from now
2022
}
2123
}

kotlinx.interval/src/commonMain/kotlin/IntervalUnion.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ sealed interface IntervalUnion<T : Comparable<T>, TSize : Comparable<TSize>> : I
4949
*/
5050
fun shift( amount: TSize, invertDirection: Boolean = false ): ShiftResult<IntervalUnion<T, TSize>, TSize>
5151

52+
/**
53+
* Returns an [IntervalUnion] offset to the right from this interval union by the specified [amount],
54+
* or as much as possible before the minimum or maximum value that can be represented by [T] is reached.
55+
* Use [shift] in case you want to verify whether the interval could be offset the full [amount].
56+
*/
57+
infix fun shr( amount: TSize ): IntervalUnion<T, TSize> = shift( amount ).shiftedInterval
58+
59+
/**
60+
* Returns an [IntervalUnion] offset to the left from this interval union by the specified [amount],
61+
* or as much as possible before the minimum or maximum value that can be represented by [T] is reached.
62+
* Use [shift] in case you want to verify whether the interval could be offset the full [amount].
63+
*/
64+
infix fun shl( amount: TSize ): IntervalUnion<T, TSize> = shift( amount, invertDirection = true ).shiftedInterval
65+
5266
/**
5367
* Determines whether [interval] has at least one value in common with this set.
5468
*/

kotlinx.interval/src/commonTest/kotlin/Readme.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class Readme
1414
val areIncluded = 0 in interval && 5 in interval // true
1515
val areExcluded = 10 !in interval && 15 !in interval // true
1616
val size: UInt = interval.size // 10
17+
val shifted = interval shr 10u // Shifted right by 10: [10, 20)
1718
}
1819

1920
@Test
@@ -22,6 +23,7 @@ class Readme
2223
val start = interval( 0, 100 ) // Interval: [0, 100]
2324
val areIncluded = 50 in start && 100 in start // true
2425
val splitInTwo = start - interval( 25, 85 ) // Union: [[0, 25), (85, 100]]
26+
val shiftBackAndForth = splitInTwo shr 100u shl 100u // == splitInTwo
2527
val areExcluded = 50 !in splitInTwo && 85 !in splitInTwo // true
2628
val unite = splitInTwo + interval( 10, 90 ) // Interval: [0, 100]
2729
val backToStart = start == unite // true

0 commit comments

Comments
 (0)