-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Endianness sensitive collection #71
Comments
The collection should be a public member of NBKCoreKit. |
I suppose it needs to be clear how the direction relates to endianness: NBKLittleEndianCollection? |
Hm. It is possible to make this collection super generic, but do I want that? Or do I want to keep it simple? The super generic approach cannot use Int indices with random access performance, however, which is a bit sad. Alternatively, I can make it really light weight by requiring a RandomAccessCollection base with Range<Int> indices. The lightweight approach covers all the use cases I care about:
|
Hm. If possible, I would like to avoid extending it with de/initialization methods. It would be much better if it "just works" in my opinion. I want something like the following: for index in littleEndianOrdered.indices {
littleEndianOrdered.base.initializeElement(at: index.baseIndex, to: 1234)
} |
Hm. I think the following is the closest you can get: // where Base.Indices != Range<Index>
for index in littleEndianOrdered.indices {
let baseIndex = litteEndianOrdered.baseSubscriptIndex(at: index)
littleEndianOrdered.base.initializeElement(at: baseIndex, to: 0)
} // where Base.Indices == Range<Index>
for index in littleEndianOrdered.indices {
littleEndianOrdered.base.initializeElement(at: index.baseSubscriptIndex, to: 0)
} |
Hm. The general approach requires that the indices keep a reference to the base: for index in littleEndianOrdered.indices {
mutate( &littleEndianOrdered[index]) // may copy-on-write
} I suppose this can be circumvented by a while loop, however: var index = littleEndianOrdered.startIndex
while index < littleEndianOrdered.endIndex {
mutate( &littleEndianOrdered[index])
littleEndianOrdered.formIndex(after: &index)
} Alternatively, I can omit MutableCollection like ReversedCollection does. |
I went with conditionally wrapping Base or ReversedCollection<Base> depending on endianness. |
I also managed to implement this convenience on the index type. /// Returns the subscript index of the corresponding collection, assuming it exists.
///
/// - Note: This operation is unchecked.
///
@inlinable public func baseSubscriptIndex<T: Strideable>() -> Base.Index where Base.Indices == Range<T> {
#if _endian(big)
return self.storageIndex.base.advanced(by: -1)
#else
return self.storageIndex
#endif
} |
I ended up wanting a unique index type to avoid accidentally subscripting the base collection. |
Hm. I see an argument for Range<Int> indices, even if the base must provide random access. |
I reworked it using Int indices. Realistically, the base collection should always represent some kind of integer or integer-like thing. In that case, you have random access collections and sequences, and basically never anything in-between.
|
I suppose I should compare it to calling reverse() on the UnsafeMutableBufferPointer. Edit: I don't have a setup for testing one reverse(), but 2x, 4x, 6x, makes 1x seem slow too. |
A thought: you can parameterize the collection and accept an ordering meta type (or a dynamic closure) that maps positions to indices. With this in mind, it may or may not be useful and/or neat to have endianness meta types: EndiannessSensitiveCollection(base, ordering: LittleEndian.self) |
I might also have to add |
Adapting it to handle big endianness, or even something dynamic, appears to be a trivial change. Edit: it could even be unrelated to endianness, but dunno what to call it at that point. |
I mentioned this in (#67), and I think it's a much better solution:
The text was updated successfully, but these errors were encountered: