55// Created by Christian Treffs on 05.09.19.
66//
77
8- public struct Matrix3x3 < Storage> where Storage: Storage3x3Protocol {
8+ @frozen
9+ public struct Matrix3x3 < Storage> : RandomAccessCollection , MutableCollection where Storage: Storage3x3Protocol , Storage. Value == Storage . Element {
10+ public typealias Element = Storage . Element
11+ public typealias Index = Storage . Index
912 public typealias Value = Storage . Value
1013 public typealias Vector = Storage . Column
1114
1215 @usableFromInline var storage : Storage
1316
14- public init ( storage: Storage ) {
17+ public var startIndex : Index { storage. startIndex }
18+ public var endIndex : Index { storage. endIndex }
19+ public func index( after i: Index ) -> Index { storage. index ( after: i) }
20+ public func index( before i: Index ) -> Index { storage. index ( before: i) }
21+
22+ @usableFromInline init ( storage: Storage ) {
1523 self . storage = storage
1624 }
17- }
1825
19- extension Matrix3x3 {
2026 public init ( diagonal: Vector ) {
2127 self . storage = Storage ( diagonal: diagonal)
2228 }
@@ -29,56 +35,53 @@ extension Matrix3x3 {
2935 public init ( _ column0: Vector , _ column1: Vector , _ column2: Vector ) {
3036 self . init ( [ column0, column1, column2] )
3137 }
32- }
3338
34- extension Matrix3x3 {
3539 public init ( _ values: [ Storage . Value ] ) {
3640 precondition ( values. count == 9 , " Matrix needs exactly 9 values " )
3741 self . init ( [ Vector ( values [ 0 ... 2 ] ) ,
3842 Vector ( values [ 3 ... 5 ] ) ,
3943 Vector ( values [ 6 ... 8 ] ) ] )
4044 }
41- }
4245
43- extension Matrix3x3 : ExpressibleByArrayLiteral {
44- public init ( arrayLiteral elements : Storage . Value ... ) {
45- self . init ( elements )
46+ public subscript ( index : Index ) -> Element {
47+ get { storage [ index ] }
48+ set { storage [ index ] = newValue }
4649 }
47- }
4850
49- extension Matrix3x3 : Sequence {
50- public func makeIterator( ) -> IndexingIterator < [ Value ] > {
51- unsafeBitCast ( storage. makeIterator ( ) , to: IndexingIterator< [ Storage . Value] > . self )
52- }
53-
54- @inlinable public var elements : [ Value ] {
55- [ Value] ( self )
51+ public subscript( column: Int , row: Int ) -> Value {
52+ get { storage [ column, row] }
53+ set { storage [ column, row] = newValue }
5654 }
57- }
5855
59- extension Matrix3x3 {
6056 @inlinable public var columns : ( Vector , Vector , Vector ) {
6157 storage. columns
6258 }
63- }
6459
65- extension Matrix3x3 {
66- public subscript( column: Int , row: Int ) -> Value {
67- get {
68- storage [ column, row]
69- }
70- set {
71- storage [ column, row] = newValue
60+ @inlinable public var elements : [ Value ] {
61+ [ Value] ( AnyIterator ( self . storage. makeIterator ( ) ) )
62+ }
63+
64+ @inlinable public func withForcedContiguousStorage< R> ( _ body: ( UnsafeBufferPointer < Element > ) -> R ) throws -> R ? {
65+ // https://forums.swift.org/t/se-0256-introduce-mutable-contiguouscollection-protocol/22569/7
66+ if let result = withContiguousStorageIfAvailable ( body) {
67+ return result
7268 }
69+
70+ return ContiguousArray ( self ) . withContiguousStorageIfAvailable ( body)
7371 }
7472
75- public subscript( index: Int ) -> Value {
76- get {
77- storage [ index]
73+ @inlinable public mutating func withForcedContiguousMutableStorage< R> ( _ body: ( inout UnsafeMutableBufferPointer < Element > ) -> R ) throws -> R ? {
74+ // https://forums.swift.org/t/se-0256-introduce-mutable-contiguouscollection-protocol/22569/7
75+ if let result = withContiguousMutableStorageIfAvailable ( body) {
76+ return result
7877 }
79- set {
80- storage [ index] = newValue
78+
79+ var array = ContiguousArray ( self )
80+ let result = array. withContiguousMutableStorageIfAvailable ( body)
81+ for (idx, arrayIdx) in zip ( self . indices, array. indices) {
82+ self [ idx] = array [ arrayIdx]
8183 }
84+ return result
8285 }
8386}
8487
0 commit comments