Authored by Nikolay Tymchenko

Initial equalTo() autoboxing implementation

... ... @@ -121,28 +121,10 @@
#pragma mark - NSLayoutRelation proxies
- (MASConstraint * (^)(id))equalTo {
return ^id(id attr) {
- (MASConstraint * (^)(id, NSLayoutRelation))_equalToWithRelation {
return ^id(id attr, NSLayoutRelation relation) {
for (MASConstraint *constraint in self.childConstraints.copy) {
constraint.equalTo(attr);
}
return self;
};
}
- (MASConstraint * (^)(id))greaterThanOrEqualTo {
return ^id(id attr) {
for (MASConstraint *constraint in self.childConstraints.copy) {
constraint.greaterThanOrEqualTo(attr);
}
return self;
};
}
- (MASConstraint * (^)(id))lessThanOrEqualTo {
return ^id(id attr) {
for (MASConstraint *constraint in self.childConstraints.copy) {
constraint.lessThanOrEqualTo(attr);
constraint._equalToWithRelation(attr, relation);
}
return self;
};
... ...
... ... @@ -99,6 +99,16 @@
*/
- (MASConstraint * (^)(id attr))lessThanOrEqualTo;
// TODO: description
// TODO: update docs for the methods above
- (MASConstraint * (^)(id attr, NSLayoutRelation relation))_equalToWithRelation;
#define equalTo(...) _equalToWithRelation(MASBoxValue((__VA_ARGS__)), NSLayoutRelationEqual)
#define greaterThanOrEqualTo(...) _equalToWithRelation(MASBoxValue((__VA_ARGS__)), NSLayoutRelationGreaterThanOrEqual)
#define lessThanOrEqualTo(...) _equalToWithRelation(MASBoxValue((__VA_ARGS__)), NSLayoutRelationLessThanOrEqual)
/**
* optional semantic property which has no effect but improves the readability of constraint
*/
... ... @@ -179,4 +189,4 @@
*/
- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;
@end
@end
\ No newline at end of file
... ...
... ... @@ -21,6 +21,14 @@
return [super init];
}
#pragma mark - Dummies
- (MASConstraint * (^)(id))equalTo { return nil; }
- (MASConstraint * (^)(id))greaterThanOrEqualTo { return nil; }
- (MASConstraint * (^)(id))lessThanOrEqualTo { return nil; }
#pragma mark - Abstract
- (MASConstraint * (^)(MASEdgeInsets insets))insets { methodNotImplemented(); }
... ... @@ -43,11 +51,7 @@
- (MASConstraint * (^)())priorityHigh { methodNotImplemented(); }
- (MASConstraint * (^)(id attr))equalTo { methodNotImplemented(); }
- (MASConstraint * (^)(id attr))greaterThanOrEqualTo { methodNotImplemented(); }
- (MASConstraint * (^)(id attr))lessThanOrEqualTo { methodNotImplemented(); }
- (MASConstraint * (^)(id, NSLayoutRelation))_equalToWithRelation { methodNotImplemented(); }
- (MASConstraint *)with { methodNotImplemented(); }
... ...
... ... @@ -67,3 +67,68 @@
*/
#define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger))
#define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch)))
// TODO: description
static inline id _MASBoxValue(const char *type, ...) {
va_list v;
va_start(v, type);
id obj = nil;
if (strcmp(type, @encode(id)) == 0) {
id actual = va_arg(v, id);
obj = actual;
} else if (strcmp(type, @encode(CGPoint)) == 0) {
CGPoint actual = (CGPoint)va_arg(v, CGPoint);
obj = [NSValue value:&actual withObjCType:type];
} else if (strcmp(type, @encode(CGSize)) == 0) {
CGSize actual = (CGSize)va_arg(v, CGSize);
obj = [NSValue value:&actual withObjCType:type];
} else if (strcmp(type, @encode(MASEdgeInsets)) == 0) {
MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets);
obj = [NSValue value:&actual withObjCType:type];
} else if (strcmp(type, @encode(char)) == 0) {
char actual = (char)va_arg(v, int);
obj = [NSNumber numberWithChar:actual];
} else if(strcmp(type, @encode(_Bool)) == 0) {
_Static_assert(sizeof(_Bool) <= sizeof(int), "Expected _Bool to be subject to vararg type promotion");
_Bool actual = (_Bool)va_arg(v, int);
obj = [NSNumber numberWithBool:actual];
} else if (strcmp(type, @encode(double)) == 0) {
double actual = (double)va_arg(v, double);
obj = [NSNumber numberWithDouble:actual];
} else if (strcmp(type, @encode(float)) == 0) {
float actual = (float)va_arg(v, double);
obj = [NSNumber numberWithFloat:actual];
} else if (strcmp(type, @encode(int)) == 0) {
int actual = (int)va_arg(v, int);
obj = [NSNumber numberWithInt:actual];
} else if (strcmp(type, @encode(long)) == 0) {
long actual = (long)va_arg(v, long);
obj = [NSNumber numberWithLong:actual];
} else if (strcmp(type, @encode(long long)) == 0) {
long long actual = (long long)va_arg(v, long long);
obj = [NSNumber numberWithLongLong:actual];
} else if (strcmp(type, @encode(short)) == 0) {
short actual = (short)va_arg(v, int);
obj = [NSNumber numberWithShort:actual];
} else if (strcmp(type, @encode(unsigned char)) == 0) {
unsigned char actual = (unsigned char)va_arg(v, unsigned int);
obj = [NSNumber numberWithUnsignedChar:actual];
} else if (strcmp(type, @encode(unsigned int)) == 0) {
unsigned int actual = (int)va_arg(v, unsigned int);
obj = [NSNumber numberWithUnsignedInt:actual];
} else if (strcmp(type, @encode(unsigned long)) == 0) {
unsigned long actual = (unsigned long)va_arg(v, unsigned long);
obj = [NSNumber numberWithUnsignedLong:actual];
} else if (strcmp(type, @encode(unsigned long long)) == 0) {
unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long);
obj = [NSNumber numberWithUnsignedLongLong:actual];
} else if (strcmp(type, @encode(unsigned short)) == 0) {
unsigned short actual = (unsigned short)va_arg(v, unsigned int);
obj = [NSNumber numberWithUnsignedShort:actual];
}
va_end(v);
return obj;
}
#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))
... ...
... ... @@ -79,7 +79,25 @@
- (void)setSecondViewAttribute:(id)secondViewAttribute {
if ([secondViewAttribute isKindOfClass:NSNumber.class]) {
self.layoutConstant = [secondViewAttribute doubleValue];
} else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) {
} else if ([secondViewAttribute isKindOfClass:NSValue.class]) {
NSValue *value = (NSValue *)secondViewAttribute;
if (strcmp(value.objCType, @encode(CGPoint)) == 0) {
CGPoint point;
[value getValue:&point];
self.centerOffset = point;
} else if (strcmp(value.objCType, @encode(CGSize)) == 0) {
CGSize size;
[value getValue:&size];
self.sizeOffset = size;
} else if (strcmp(value.objCType, @encode(MASEdgeInsets)) == 0) {
MASEdgeInsets insets;
[value getValue:&insets];
self.insets = insets;
} else {
// TODO: avoid duplication
NSAssert(NO, @"attempting to add unsupported attribute: %@", secondViewAttribute);
}
} else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) {
_secondViewAttribute = [[MASViewAttribute alloc] initWithView:secondViewAttribute layoutAttribute:self.firstViewAttribute.layoutAttribute];
} else if ([secondViewAttribute isKindOfClass:MASViewAttribute.class]) {
_secondViewAttribute = secondViewAttribute;
... ... @@ -174,10 +192,10 @@
};
}
#pragma mark - NSLayoutRelation proxies
#pragma mark - NSLayoutRelation proxy
- (MASConstraint * (^)(id))equalityWithRelation:(NSLayoutRelation)relation {
return ^id(id attribute) {
- (MASConstraint * (^)(id, NSLayoutRelation))_equalToWithRelation {
return ^id(id attribute, NSLayoutRelation relation) {
if ([attribute isKindOfClass:NSArray.class]) {
NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation");
NSMutableArray *children = NSMutableArray.new;
... ... @@ -191,7 +209,7 @@
[self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint];
return compositeConstraint;
} else {
NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSNumber.class], @"Redefinition of constraint relation");
NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation");
self.layoutRelation = relation;
self.secondViewAttribute = attribute;
return self;
... ... @@ -199,18 +217,6 @@
};
}
- (MASConstraint * (^)(id))equalTo {
return [self equalityWithRelation:NSLayoutRelationEqual];
}
- (MASConstraint * (^)(id))greaterThanOrEqualTo {
return [self equalityWithRelation:NSLayoutRelationGreaterThanOrEqual];
}
- (MASConstraint * (^)(id))lessThanOrEqualTo {
return [self equalityWithRelation:NSLayoutRelationLessThanOrEqual];
}
#pragma mark - Semantic properties
- (MASConstraint *)with {
... ...