https://kotlinlang.org logo
#stdlib
Title
# stdlib
e

elect

02/02/2023, 9:10 AM
would it be feasible to have a
Range
on enums?
s

Sam

02/02/2023, 9:14 AM
Yes, enums are comparable so you can make a range using the usual operators/functions. The sort order is based on the order the enum entries appear in the source code, so caution is needed, especially around API compatibility.
e

elect

02/02/2023, 9:15 AM
I'm asking about a ready to have in stdlib
s

Sam

02/02/2023, 9:16 AM
Can you give an example of the kind of thing you want?
e

elect

02/02/2023, 9:18 AM
https://gist.github.com/elect86/d659ab70e47c7ca9c372c15fb1ce05b2
isGamepad
can become
this in Gamepad_BEGIN until Gamepad_END
I have the same case over and over again
c

CLOVIS

02/02/2023, 9:21 AM
Copy code
enum class Test {
    A,
    B,
    C,
    ;
}

println(Test.A.ordinal in Test.B.ordinal until Test.C.ordinal)
?
e

elect

02/02/2023, 9:21 AM
that's exactly what I'm using, I'd love to skip
.ordinal
s

Sam

02/02/2023, 9:22 AM
It’s possible, but only with
..
, not with
until
.
At the moment,
until
only works for integral types, because
a until b
is basically implemented as
a..(b - 1)
. It doesn’t work for enum types because they don’t have addition and subtraction 😄.
1
e

elect

02/02/2023, 9:24 AM
well, that could be another nice feature to have, enumA + 1, to get the next one
s

Sam

02/02/2023, 9:25 AM
But open ranges for other types are coming!
c

CLOVIS

02/02/2023, 9:25 AM
Copy code
enum class Test {
    A,
    B,
    C,
    ;
}

infix fun Test.until(end: Test) = this..(enumValues<Test>()[end.ordinal-1])

println(Test.B in Test.A..Test.B)
println(Test.B in Test.A until Test.B)
You'll have to add a check for if
end
is the first element of the enum, but you get the idea
s

Sam

02/02/2023, 9:26 AM
For now, I would just recommend that you change your code to
Copy code
val Gamepad_BEGIN = GamepadStart
val Gamepad_END = GamepadRStickDown

val isGamepad: Boolean
   get() = this in Gamepad_BEGIN..Gamepad_END
(so that the
Gamepad_END
boundary is inclusive rather than exclusive)
e

elect

02/02/2023, 9:27 AM
I thought about that, but since it's a port from native, maintenance comes first
s

Sam

02/02/2023, 9:28 AM
The feature you want is coming, it’s just experimental

https://www.youtube.com/watch?v=v0AHdAIBnbs

👀 1
a

Adam S

02/02/2023, 9:31 AM
you could also try using multiple sealed-interfaces
Copy code
sealed interface Key {
  enum class Keyboard : Key { A, B, C, ... } 
  enum class Gamepad: Key { Start, Back, Left, ... }
}
Then you can check using
is
Copy code
fun checkKey(key: Key) {
  when (key) {
    is Gamepad -> {}
    is Key -> {}
  }
}
Or, if you want to keep the keys ‘flat’ and not nested, and if you want the keys to have multiple ‘types’, use objects instead of enums.
Copy code
sealed interface Key {
  sealed interface Keyboard: Key
  sealed interface Gamepad: Key

  sealed interface DirectionKey: Key

  object A: Keyboard, DirectionKey
  object B: Keyboard
  object C: Keyboard
  //...
  object W: Keyboard, DirectionKey
  object S: Keyboard, DirectionKey
  object D: Keyboard, DirectionKey

  object GamepadLeft: Gamepad, DirectionKey
  object GamepadRight: Gamepad, DirectionKey
}
Just throwing out ideas - it might be overkill and too complicated!
e

elect

02/02/2023, 9:31 AM
overkill, but nice idea
4 Views