@@ -6,17 +6,18 @@ extension CasePath {
6
6
/// - Parameter embed: An embed function.
7
7
/// - Returns: A case path.
8
8
public init ( _ embed: @escaping ( Value ) -> Root ) {
9
- self . init ( embed: embed, extract: extractHelp ( embed) )
10
- }
11
-
12
- /// Returns a case path for the given embed function.
13
- ///
14
- /// - Note: This operator is only intended to be used with enum cases that have no associated
15
- /// values. Its behavior is otherwise undefined.
16
- /// - Parameter embed: An embed function.
17
- /// - Returns: A case path.
18
- public init < Wrapped> ( _ embed: @escaping ( Value ) -> Root ) where Root == Wrapped ? {
19
- self . init ( embed: embed, extract: optionalPromotedExtractHelp ( embed) )
9
+ func open< Wrapped> ( _: Wrapped . Type ) -> ( Root ) -> Value ? {
10
+ optionalPromotedExtractHelp ( unsafeBitCast ( embed, to: ( ( Value) - > Wrapped? ) . self) )
11
+ as! ( Root ) -> Value ?
12
+ }
13
+ let extract =
14
+ ( ( _Witness < Root > . self as? _AnyOptional . Type) ? . wrappedType)
15
+ . map { _openExistential ( $0, do: open) }
16
+ ?? extractHelp ( embed)
17
+ self . init (
18
+ embed: embed,
19
+ extract: extract
20
+ )
20
21
}
21
22
}
22
23
@@ -28,17 +29,14 @@ extension CasePath where Value == Void {
28
29
/// - Parameter root: A case with no an associated value.
29
30
/// - Returns: A void case path.
30
31
public init ( _ root: Root ) {
31
- self . init ( embed: { root } , extract: extractVoidHelp ( root) )
32
- }
33
-
34
- /// Returns a void case path for a case with no associated value.
35
- ///
36
- /// - Note: This operator is only intended to be used with enum cases that have no associated
37
- /// values. Its behavior is otherwise undefined.
38
- /// - Parameter root: A case with no an associated value.
39
- /// - Returns: A void case path.
40
- public init < Wrapped> ( _ root: Root ) where Root == Wrapped ? {
41
- self . init ( embed: { root } , extract: optionalPromotedExtractVoidHelp ( root) )
32
+ func open< Wrapped> ( _: Wrapped . Type ) -> ( Root ) -> Void ? {
33
+ optionalPromotedExtractVoidHelp ( unsafeBitCast ( root, to: Wrapped ? . self) ) as! ( Root ) -> Void ?
34
+ }
35
+ let extract =
36
+ ( ( _Witness < Root > . self as? _AnyOptional . Type) ? . wrappedType)
37
+ . map { _openExistential ( $0, do: open) }
38
+ ?? extractVoidHelp ( root)
39
+ self . init ( embed: { root } , extract: extract)
42
40
}
43
41
}
44
42
@@ -704,3 +702,17 @@ extension UnsafeRawPointer {
704
702
705
703
// This is the size of any Unsafe*Pointer and also the size of Int and UInt.
706
704
private let pointerSize = MemoryLayout< UnsafeRawPointer> . size
705
+
706
+ private protocol _Optional {
707
+ associatedtype Wrapped
708
+ }
709
+ extension Optional : _Optional { }
710
+ private enum _Witness < A> { }
711
+ private protocol _AnyOptional {
712
+ static var wrappedType : Any . Type { get }
713
+ }
714
+ extension _Witness : _AnyOptional where A: _Optional {
715
+ static var wrappedType : Any . Type {
716
+ A . Wrapped. self
717
+ }
718
+ }
0 commit comments