File tree Expand file tree Collapse file tree 4 files changed +67
-0
lines changed Expand file tree Collapse file tree 4 files changed +67
-0
lines changed Original file line number Diff line number Diff line change @@ -35,6 +35,7 @@ This library comes with a number of tools that make working with Swift concurren
3535testable.
3636
3737  *  [ ` LockIsolated ` ] ( #lockisolated ) 
38+   *  [ ` AnyHashableSendable ` ] ( #anyhashablesendable ) 
3839  *  [ Streams] ( #streams ) 
3940  *  [ Tasks] ( #tasks ) 
4041  *  [ Serial execution] ( #serial-execution ) 
@@ -44,6 +45,11 @@ testable.
4445The ` LockIsolated `  type helps wrap other values in an isolated context. It wraps the value in a 
4546class with a lock, which allows you to read and write the value with a synchronous interface.
4647
48+ ### ` AnyHashableSendable `  
49+ 
50+ The ` AnyHashableSendable `  type is a type-erased wrapper like ` AnyHashable `  that preserves the
51+ sendability of the underlying value.
52+ 
4753### Streams  
4854
4955The library comes with numerous helper APIs spread across the two Swift stream types:
Original file line number Diff line number Diff line change 1+ /// A type-erased hashable, sendable value.
2+ ///
3+ /// A sendable version of `AnyHashable` that is useful in working around the limitation that an
4+ /// existential `any Hashable` does not conform to `Hashable`.
5+ public  struct  AnyHashableSendable :  Hashable ,  Sendable  { 
6+   public  let  base :  any  Hashable  &  Sendable 
7+ 
8+   /// Creates a type-erased hashable, sendable value that wraps the given instance.
9+   public  init ( _ base:  some  Hashable  &  Sendable )  { 
10+     if  let  base =  base as?  AnyHashableSendable  { 
11+       self  =  base
12+     }  else  { 
13+       self . base =  base
14+     } 
15+   } 
16+ 
17+   public  static  func  ==  ( lhs:  Self ,  rhs:  Self )  ->  Bool  { 
18+     AnyHashable ( lhs. base)  ==  AnyHashable ( rhs. base) 
19+   } 
20+ 
21+   public  func  hash( into hasher:  inout  Hasher )  { 
22+     hasher. combine ( base) 
23+   } 
24+ } 
25+ 
26+ extension  AnyHashableSendable :  CustomDebugStringConvertible  { 
27+   public  var  debugDescription :  String  { 
28+     " AnyHashableSendable( "  +  String( reflecting:  base)  +  " ) " 
29+   } 
30+ } 
31+ 
32+ extension  AnyHashableSendable :  CustomReflectable  { 
33+   public  var  customMirror :  Mirror  { 
34+     Mirror ( self ,  children:  [ " value " :  base] ) 
35+   } 
36+ } 
37+ 
38+ extension  AnyHashableSendable :  CustomStringConvertible  { 
39+   public  var  description :  String  { 
40+     String ( describing:  base) 
41+   } 
42+ } 
Original file line number Diff line number Diff line change @@ -236,6 +236,7 @@ need to make weaker assertions due to non-determinism, but can still assert on s
236236### Data races  
237237
238238-  `` LockIsolated `` 
239+ -  `` AnyHashableSendable `` 
239240
240241### Serial execution  
241242
Original file line number Diff line number Diff line change 1+ import  ConcurrencyExtras
2+ import  XCTest
3+ 
4+ final  class  AnyHashableSendableTests :  XCTestCase  { 
5+   func  testBasics( )  { 
6+     XCTAssertEqual ( AnyHashableSendable ( 1 ) ,  AnyHashableSendable ( 1 ) ) 
7+     XCTAssertNotEqual ( AnyHashableSendable ( 1 ) ,  AnyHashableSendable ( 2 ) ) 
8+ 
9+     func  make( _ base:  some  Hashable  &  Sendable )  ->  AnyHashableSendable  { 
10+       AnyHashableSendable ( base) 
11+     } 
12+ 
13+     let  flat  =  make ( 1 ) 
14+     let  nested  =  make ( flat) 
15+ 
16+     XCTAssertEqual ( flat,  nested) 
17+   } 
18+ } 
    
 
   
 
     
   
   
          
     
  
    
     
 
    
      
     
 
     
    You can’t perform that action at this time.
  
 
    
  
     
    
      
        
     
 
       
      
     
   
 
    
    
  
 
  
 
     
    
0 commit comments