Created
July 7, 2022 05:00
-
-
Save phlippieb/54e1ab490dd52ca76c164f4acb4e560b to your computer and use it in GitHub Desktop.
Leveraging Swift's type system to represent the concept of an index type with a fixed size
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Leveraging Swift's type system to represent the concept of an index type with a fixed size, | |
so that iterating over all indices doesn't require a default case. | |
*/ | |
/// The abstract properties of a fixed-size index type | |
protocol ExactNumberOfIndices: CaseIterable, RawRepresentable where RawValue == Int {} | |
/// A concrete fixed-size index type with 1 element (namely 0) | |
enum _1: Int, ExactNumberOfIndices { | |
case _0 = 0 | |
} | |
/// A concrete fixed-size index type with 2 elements (namely 0 and 1) | |
enum _2: Int, ExactNumberOfIndices { | |
case _0 = 0, _1 | |
} | |
enum _3: Int, ExactNumberOfIndices { | |
case _0 = 0, _1, _2 | |
} | |
// etc | |
/** | |
This allows us to pass an "expected number of items" around as a type. | |
If we need to iterate over indices, this cleans up the handler. | |
*/ | |
/// Example function that receives a fixed-size index type as a parameter | |
func verifyItems<ItemType, IndexType: ExactNumberOfIndices>( | |
_ items: [ItemType], | |
hasCount: IndexType.Type, | |
_ verify: (IndexType, ItemType) -> Void | |
) { | |
// Verify that the item count is correct | |
assert(items.count == IndexType.allCases.count) | |
// Iterate over each item and verify | |
zip(IndexType.allCases, items).forEach(verify) | |
} | |
/// Example usage | |
verifyItems([1, 2], hasCount: _2.self) { index, item in | |
switch index { | |
case ._0: assert(item == 1) | |
case ._1: assert(item == 2) | |
// NOTE: No default case required! | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment