Skip to content

Commit

Permalink
Merge pull request ReactiveCocoa#87 from erichoracek/typed-tuple
Browse files Browse the repository at this point in the history
Add generic typed tuples
  • Loading branch information
mdiep committed Apr 7, 2017
2 parents a3d6e1f + 096cf30 commit 1481e30
Show file tree
Hide file tree
Showing 11 changed files with 445 additions and 55 deletions.
7 changes: 3 additions & 4 deletions ReactiveObjC/NSDictionary+RACSequenceAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@
#import <Foundation/Foundation.h>

@class RACSequence<__covariant ValueType>;
@class RACTuple;
@class RACTwoTuple<__covariant First, __covariant Second>;

NS_ASSUME_NONNULL_BEGIN

@interface NSDictionary<__covariant KeyType, __covariant ObjectType> (RACSequenceAdditions)

/// Creates and returns a sequence of RACTuple key/value pairs. The key will be
/// the first element in the tuple, and the value will be the second.
/// Creates and returns a sequence of key/value tuples.
///
/// Mutating the receiver will not affect the sequence after it's been created.
@property (nonatomic, copy, readonly) RACSequence<RACTuple *> *rac_sequence;
@property (nonatomic, copy, readonly) RACSequence<RACTwoTuple<KeyType, ObjectType> *> *rac_sequence;

/// Creates and returns a sequence corresponding to the keys in the receiver.
///
Expand Down
5 changes: 3 additions & 2 deletions ReactiveObjC/NSObject+RACPropertySubscribing.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#endif

@class RACDisposable;
@class RACTwoTuple<__covariant First, __covariant Second>;
@class RACSignal<__covariant ValueType>;

NS_ASSUME_NONNULL_BEGIN
Expand Down Expand Up @@ -95,9 +96,9 @@ NS_ASSUME_NONNULL_BEGIN
/// Returns a signal that sends tuples containing the current value at the key
/// path and the change dictionary for each KVO callback.
#if OS_OBJECT_HAVE_OBJC_SUPPORT
- (RACSignal *)rac_valuesAndChangesForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(__weak NSObject *)observer;
- (RACSignal<RACTwoTuple<id, NSDictionary *> *> *)rac_valuesAndChangesForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(__weak NSObject *)observer;
#else
- (RACSignal *)rac_valuesAndChangesForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(NSObject *)observer;
- (RACSignal<RACTwoTuple<id, NSDictionary *> *> *)rac_valuesAndChangesForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options observer:(NSObject *)observer;
#endif

@end
Expand Down
5 changes: 3 additions & 2 deletions ReactiveObjC/NSObject+RACSelectorSignal.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#import <Foundation/Foundation.h>

@class RACTuple;
@class RACSignal<__covariant ValueType>;

NS_ASSUME_NONNULL_BEGIN
Expand Down Expand Up @@ -54,7 +55,7 @@ extern const NSInteger RACSelectorSignalErrorMethodSwizzlingRace;
/// will be sent synchronously from the thread that invoked the method. If
/// a runtime call fails, the signal will send an error in the
/// RACSelectorSignalErrorDomain.
- (RACSignal *)rac_signalForSelector:(SEL)selector;
- (RACSignal<RACTuple *> *)rac_signalForSelector:(SEL)selector;

/// Behaves like -rac_signalForSelector:, but if the selector is not yet
/// implemented on the receiver, its method signature is looked up within
Expand All @@ -76,7 +77,7 @@ extern const NSInteger RACSelectorSignalErrorMethodSwizzlingRace;
/// Returns a signal which will send a tuple of arguments on each invocation of
/// the selector, or an error in RACSelectorSignalErrorDomain if a runtime
/// call fails.
- (RACSignal *)rac_signalForSelector:(SEL)selector fromProtocol:(Protocol *)protocol;
- (RACSignal<RACTuple *> *)rac_signalForSelector:(SEL)selector fromProtocol:(Protocol *)protocol;

@end

Expand Down
20 changes: 10 additions & 10 deletions ReactiveObjC/NSURLConnection+RACSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@

#import <Foundation/Foundation.h>

@class RACTuple;
@class RACTwoTuple<__covariant First, __covariant Second>;
@class RACSignal<__covariant ValueType>;

NS_ASSUME_NONNULL_BEGIN

@interface NSURLConnection (RACSupport)

// Lazily loads data for the given request in the background.
//
// request - The URL request to load. This must not be nil.
//
// Returns a signal which will begin loading the request upon each subscription,
// then send a `RACTuple` of the received `NSURLResponse` and downloaded
// `NSData`, and complete on a background thread. If any errors occur, the
// returned signal will error out.
+ (RACSignal<RACTuple *> *)rac_sendAsynchronousRequest:(NSURLRequest *)request;
/// Lazily loads data for the given request in the background.
///
/// request - The URL request to load. This must not be nil.
///
/// Returns a signal which will begin loading the request upon each subscription,
/// then send a tuple of the received response and downloaded data, and complete
/// on a background thread. If any errors occur, the returned signal will error
/// out.
+ (RACSignal<RACTwoTuple<NSURLResponse *, NSData *> *> *)rac_sendAsynchronousRequest:(NSURLRequest *)request;

@end

Expand Down
5 changes: 3 additions & 2 deletions ReactiveObjC/RACSequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import <Foundation/Foundation.h>
#import "RACStream.h"

@class RACTuple;
@class RACScheduler;
@class RACSignal<__covariant ValueType>;

Expand Down Expand Up @@ -190,7 +191,7 @@ typedef RACSequence * _Nullable (^RACSequenceBindBlock)(ValueType _Nullable valu
/// Returns a new sequence of RACTuples, representing the combined values of the
/// two sequences. Any error from one of the original sequence will be forwarded
/// on the returned sequence.
- (RACSequence *)zipWith:(RACSequence *)sequence;
- (RACSequence<RACTuple *> *)zipWith:(RACSequence *)sequence;

@end

Expand Down Expand Up @@ -286,7 +287,7 @@ typedef RACSequence * _Nullable (^RACSequenceBindBlock)(ValueType _Nullable valu
///
/// Returns a new sequence containing RACTuples of the zipped values from the
/// sequences.
+ (RACSequence<ValueType> *)zip:(id<NSFastEnumeration>)sequence;
+ (RACSequence<RACTuple *> *)zip:(id<NSFastEnumeration>)sequence;

/// Zips sequences using +zip:, then reduces the resulting tuples into a single
/// value using -reduceEach:
Expand Down
5 changes: 3 additions & 2 deletions ReactiveObjC/RACSignal+Operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
@class RACSequence<__covariant ValueType>;
@class RACSubject<ValueType>;
@class RACTuple;
@class RACTwoTuple<__covariant First, __covariant Second>;
@class RACEvent<__covariant ValueType>;
@class RACGroupedSignal;
@protocol RACSubscriber;
Expand Down Expand Up @@ -153,7 +154,7 @@ extern const NSInteger RACSignalErrorNoMatchingCase;
- (RACSignal<ValueType> *)takeLast:(NSUInteger)count RAC_WARN_UNUSED_RESULT;

/// Combines the latest values from the receiver and the given signal into
/// RACTuples, once both have sent at least one `next`.
/// 2-tuples, once both have sent at least one `next`.
///
/// Any additional `next`s will result in a new RACTuple with the latest values
/// from both signals.
Expand All @@ -162,7 +163,7 @@ extern const NSInteger RACSignalErrorNoMatchingCase;
///
/// Returns a signal which sends RACTuples of the combined values, forwards any
/// `error` events, and completes when both input signals complete.
- (RACSignal<RACTuple *> *)combineLatestWith:(RACSignal *)signal RAC_WARN_UNUSED_RESULT;
- (RACSignal<RACTwoTuple<ValueType, id> *> *)combineLatestWith:(RACSignal *)signal RAC_WARN_UNUSED_RESULT;

/// Combines the latest values from the given signals into RACTuples, once all
/// the signals have sent at least one `next`.
Expand Down
6 changes: 4 additions & 2 deletions ReactiveObjC/RACSignal.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
@class RACDisposable;
@class RACScheduler;
@class RACSubject;
@class RACTuple;
@class RACTwoTuple<__covariant First, __covariant Second>;
@protocol RACSubscriber;

NS_ASSUME_NONNULL_BEGIN
Expand Down Expand Up @@ -128,7 +130,7 @@ typedef RACSignal * _Nullable (^RACSignalBindBlock)(ValueType _Nullable value, B
/// Returns a new signal of RACTuples, representing the combined values of the
/// two signals. Any error from one of the original signals will be forwarded on
/// the returned signal.
- (RACSignal *)zipWith:(RACSignal *)signal RAC_WARN_UNUSED_RESULT;
- (RACSignal<RACTwoTuple<ValueType, id> *> *)zipWith:(RACSignal *)signal RAC_WARN_UNUSED_RESULT;

@end

Expand Down Expand Up @@ -244,7 +246,7 @@ typedef RACSignal * _Nullable (^RACSignalBindBlock)(ValueType _Nullable value, B
///
/// Returns a new signal containing RACTuples of the zipped values from the
/// signals.
+ (RACSignal<ValueType> *)zip:(id<NSFastEnumeration>)signals RAC_WARN_UNUSED_RESULT;
+ (RACSignal<RACTuple *> *)zip:(id<NSFastEnumeration>)signals RAC_WARN_UNUSED_RESULT;

/// Zips signals using +zip:, then reduces the resulting tuples into a single
/// value using -reduceEach:
Expand Down
92 changes: 90 additions & 2 deletions ReactiveObjC/RACTuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
#define RACTupleUnpack(...) \
RACTupleUnpack_(__VA_ARGS__)

@class RACTwoTuple<__covariant First, __covariant Second>;
@class RACThreeTuple<__covariant First, __covariant Second, __covariant Third>;
@class RACFourTuple<__covariant First, __covariant Second, __covariant Third, __covariant Fourth>;
@class RACFiveTuple<__covariant First, __covariant Second, __covariant Third, __covariant Fourth, __covariant Fifth>;

NS_ASSUME_NONNULL_BEGIN

/// A sentinel object that represents nils in the tuple.
Expand Down Expand Up @@ -94,7 +99,7 @@ NS_ASSUME_NONNULL_BEGIN
/// obj - The object to add to the tuple. This argument may be nil.
///
/// Returns a new tuple.
- (instancetype)tupleByAddingObject:(nullable id)obj;
- (__kindof RACTuple *)tupleByAddingObject:(nullable id)obj;

@end

Expand All @@ -111,15 +116,98 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable id)objectAtIndexedSubscript:(NSUInteger)idx;
@end

/// A tuple with exactly one generic value.
@interface RACOneTuple<__covariant First> : RACTuple

+ (instancetype)tupleWithObjects:(id)object, ... __attribute((unavailable("Use pack: instead.")));

- (RACTwoTuple<First, id> *)tupleByAddingObject:(nullable id)obj;

/// Creates a new tuple with the given values.
+ (RACOneTuple<First> *)pack:(First)first;

@property (nonatomic, readonly, nullable) First first;

@end

/// A tuple with exactly two generic values.
@interface RACTwoTuple<__covariant First, __covariant Second> : RACTuple

+ (instancetype)tupleWithObjects:(id)object, ... __attribute((unavailable("Use pack:: instead.")));

- (RACThreeTuple<First, Second, id> *)tupleByAddingObject:(nullable id)obj;

/// Creates a new tuple with the given value.
+ (RACTwoTuple<First, Second> *)pack:(First)first :(Second)second;

@property (nonatomic, readonly, nullable) First first;
@property (nonatomic, readonly, nullable) Second second;

@end

/// A tuple with exactly three generic values.
@interface RACThreeTuple<__covariant First, __covariant Second, __covariant Third> : RACTuple

+ (instancetype)tupleWithObjects:(id)object, ... __attribute((unavailable("Use pack::: instead.")));

- (RACFourTuple<First, Second, Third, id> *)tupleByAddingObject:(nullable id)obj;

/// Creates a new tuple with the given values.
+ (instancetype)pack:(nullable First)first :(nullable Second)second :(nullable Third)third;

@property (nonatomic, readonly, nullable) First first;
@property (nonatomic, readonly, nullable) Second second;
@property (nonatomic, readonly, nullable) Third third;

@end

/// A tuple with exactly four generic values.
@interface RACFourTuple<__covariant First, __covariant Second, __covariant Third, __covariant Fourth> : RACTuple

+ (instancetype)tupleWithObjects:(id)object, ... __attribute((unavailable("Use pack:::: instead.")));

- (RACFiveTuple<First, Second, Third, Fourth, id> *)tupleByAddingObject:(nullable id)obj;

/// Creates a new tuple with the given values.
+ (instancetype)pack:(nullable First)first :(nullable Second)second :(nullable Third)third :(nullable Fourth)fourth;

@property (nonatomic, readonly, nullable) First first;
@property (nonatomic, readonly, nullable) Second second;
@property (nonatomic, readonly, nullable) Third third;
@property (nonatomic, readonly, nullable) Fourth fourth;

@end

/// A tuple with exactly five generic values.
@interface RACFiveTuple<__covariant First, __covariant Second, __covariant Third, __covariant Fourth, __covariant Fifth> : RACTuple

+ (instancetype)tupleWithObjects:(id)object, ... __attribute((unavailable("Use pack::::: instead.")));

/// Creates a new tuple with the given values.
+ (instancetype)pack:(nullable First)first :(nullable Second)second :(nullable Third)third :(nullable Fourth)fourth :(nullable Fifth)fifth;

@property (nonatomic, readonly, nullable) First first;
@property (nonatomic, readonly, nullable) Second second;
@property (nonatomic, readonly, nullable) Third third;
@property (nonatomic, readonly, nullable) Fourth fourth;
@property (nonatomic, readonly, nullable) Fifth fifth;

@end

/// This and everything below is for internal use only.
///
/// See RACTuplePack() and RACTupleUnpack() instead.
#define RACTuplePack_(...) \
([RACTuple tupleWithObjectsFromArray:@[ metamacro_foreach(RACTuplePack_object_or_ractuplenil,, __VA_ARGS__) ]])
([RACTuplePack_class_name(__VA_ARGS__) tupleWithObjectsFromArray:@[ metamacro_foreach(RACTuplePack_object_or_ractuplenil,, __VA_ARGS__) ]])

#define RACTuplePack_object_or_ractuplenil(INDEX, ARG) \
(ARG) ?: RACTupleNil.tupleNil,

/// Returns the class that should be used to create a tuple with the provided
/// variadic arguments to RACTuplePack_(). Supports up to 20 arguments.
#define RACTuplePack_class_name(...) \
metamacro_at(20, __VA_ARGS__, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACTuple, RACFiveTuple, RACFourTuple, RACThreeTuple, RACTwoTuple, RACOneTuple)

#define RACTupleUnpack_(...) \
metamacro_foreach(RACTupleUnpack_decl,, __VA_ARGS__) \
\
Expand Down
Loading

0 comments on commit 1481e30

Please sign in to comment.