diff options
author | Gil <mcg@google.com> | 2018-01-19 12:27:11 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-19 12:27:11 -0800 |
commit | 39d8252300015c26f1932cff42032613fdb36a09 (patch) | |
tree | 93bb3ab7c476289c4afe6cf91773a60b6f53a94d /Firestore/Source/Util | |
parent | 9f7c094f9f00a6efc0107071f109ef1bc4d7357d (diff) |
Port comparison to C++ (#678)
This reimplements our comparison functions as C++ Comparators and then provides compatibility shims for interoperating with existing Objective-C usage.
A few specialized comparators aren't suitable for porting but only have a single usage (e.g. CompareBytes for comparing NSData * instances). In these cases I've moved them into the caller.
* Use int32_t for typeof(ID) in FSTDocumentReference
* Migrate callers of FSTComparison.h to Objective-C++
* Port comparison to C++
* Migrate usages of FSTComparison.h to C++ equivalents
* Remove FSTComparison
Diffstat (limited to 'Firestore/Source/Util')
-rw-r--r-- | Firestore/Source/Util/FSTComparison.h | 66 | ||||
-rw-r--r-- | Firestore/Source/Util/FSTComparison.m | 175 |
2 files changed, 0 insertions, 241 deletions
diff --git a/Firestore/Source/Util/FSTComparison.h b/Firestore/Source/Util/FSTComparison.h deleted file mode 100644 index e6e57e6..0000000 --- a/Firestore/Source/Util/FSTComparison.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -/** Compares two NSStrings. */ -NSComparisonResult FSTCompareStrings(NSString *left, NSString *right); - -/** Compares two BOOLs. */ -NSComparisonResult FSTCompareBools(BOOL left, BOOL right); - -/** Compares two integers. */ -NSComparisonResult FSTCompareInts(int left, int right); - -/** Compares two int32_t. */ -NSComparisonResult FSTCompareInt32s(int32_t left, int32_t right); - -/** Compares two int64_t. */ -NSComparisonResult FSTCompareInt64s(int64_t left, int64_t right); - -/** Compares two NSUIntegers. */ -NSComparisonResult FSTCompareUIntegers(NSUInteger left, NSUInteger right); - -/** Compares two doubles (using Firestore semantics for NaN). */ -NSComparisonResult FSTCompareDoubles(double left, double right); - -/** Compares a double and an int64_t. */ -NSComparisonResult FSTCompareMixed(double doubleValue, int64_t longValue); - -/** Compare two NSData byte sequences. */ -NSComparisonResult FSTCompareBytes(NSData *left, NSData *right); - -/** A simple NSComparator for comparing NSNumber instances. */ -extern const NSComparator FSTNumberComparator; - -/** A simple NSComparator for comparing NSString instances. */ -extern const NSComparator FSTStringComparator; - -/** - * Compares the bitwise representation of two doubles, but normalizes NaN values. This is - * similar to what the backend and android clients do, including comparing -0.0 as not equal to 0.0. - */ -BOOL FSTDoubleBitwiseEquals(double left, double right); - -/** - * Computes a bitwise hash of a double, but normalizes NaN values, suitable for use when using - * FSTDoublesAreBitwiseEqual for equality. - */ -NSUInteger FSTDoubleBitwiseHash(double d); - -NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTComparison.m b/Firestore/Source/Util/FSTComparison.m deleted file mode 100644 index 9c5c3eb..0000000 --- a/Firestore/Source/Util/FSTComparison.m +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "Firestore/Source/Util/FSTComparison.h" - -NS_ASSUME_NONNULL_BEGIN - -union DoubleBits { - double d; - uint64_t bits; -}; - -const NSComparator FSTNumberComparator = ^NSComparisonResult(NSNumber *left, NSNumber *right) { - return [left compare:right]; -}; - -const NSComparator FSTStringComparator = ^NSComparisonResult(NSString *left, NSString *right) { - return FSTCompareStrings(left, right); -}; - -NSComparisonResult FSTCompareStrings(NSString *left, NSString *right) { - // NOTE: NSLiteralSearch is necessary to compare the raw character codes. By default, - // precomposed characters are considered equivalent to their decomposed equivalents. - return [left compare:right options:NSLiteralSearch]; -} - -NSComparisonResult FSTCompareBools(BOOL left, BOOL right) { - if (!left) { - return right ? NSOrderedAscending : NSOrderedSame; - } else { - return right ? NSOrderedSame : NSOrderedDescending; - } -} - -NSComparisonResult FSTCompareInts(int left, int right) { - if (left > right) { - return NSOrderedDescending; - } - if (right > left) { - return NSOrderedAscending; - } - return NSOrderedSame; -} - -NSComparisonResult FSTCompareInt32s(int32_t left, int32_t right) { - if (left > right) { - return NSOrderedDescending; - } - if (right > left) { - return NSOrderedAscending; - } - return NSOrderedSame; -} - -NSComparisonResult FSTCompareInt64s(int64_t left, int64_t right) { - if (left > right) { - return NSOrderedDescending; - } - if (right > left) { - return NSOrderedAscending; - } - return NSOrderedSame; -} - -NSComparisonResult FSTCompareUIntegers(NSUInteger left, NSUInteger right) { - if (left > right) { - return NSOrderedDescending; - } - if (right > left) { - return NSOrderedAscending; - } - return NSOrderedSame; -} - -NSComparisonResult FSTCompareDoubles(double left, double right) { - // NaN sorts equal to itself and before any other number. - if (left < right) { - return NSOrderedAscending; - } else if (left > right) { - return NSOrderedDescending; - } else if (left == right) { - return NSOrderedSame; - } else { - // One or both left and right is NaN. - if (isnan(left)) { - return isnan(right) ? NSOrderedSame : NSOrderedAscending; - } else { - return NSOrderedDescending; - } - } -} - -static const double LONG_MIN_VALUE_AS_DOUBLE = (double)LLONG_MIN; -static const double LONG_MAX_VALUE_AS_DOUBLE = (double)LLONG_MAX; - -NSComparisonResult FSTCompareMixed(double doubleValue, int64_t longValue) { - // LLONG_MIN has an exact representation as double, so to check for a value outside the range - // representable by long, we have to check for strictly less than LLONG_MIN. Note that this also - // handles negative infinity. - if (doubleValue < LONG_MIN_VALUE_AS_DOUBLE) { - return NSOrderedAscending; - } - - // LLONG_MAX has no exact representation as double (casting as we've done makes 2^63, which is - // larger than LLONG_MAX), so consider any value greater than or equal to the threshold to be out - // of range. This also handles positive infinity. - if (doubleValue >= LONG_MAX_VALUE_AS_DOUBLE) { - return NSOrderedDescending; - } - - // In Firestore NaN is defined to compare before all other numbers. - if (isnan(doubleValue)) { - return NSOrderedAscending; - } - - int64_t doubleAsLong = (int64_t)doubleValue; - NSComparisonResult cmp = FSTCompareInt64s(doubleAsLong, longValue); - if (cmp != NSOrderedSame) { - return cmp; - } - - // At this point the long representations are equal but this could be due to rounding. - double longAsDouble = (double)longValue; - return FSTCompareDoubles(doubleValue, longAsDouble); -} - -NSComparisonResult FSTCompareBytes(NSData *left, NSData *right) { - NSUInteger minLength = MIN(left.length, right.length); - int result = memcmp(left.bytes, right.bytes, minLength); - if (result < 0) { - return NSOrderedAscending; - } else if (result > 0) { - return NSOrderedDescending; - } else if (left.length < right.length) { - return NSOrderedAscending; - } else if (left.length > right.length) { - return NSOrderedDescending; - } else { - return NSOrderedSame; - } -} - -/** Helper to normalize a double and then return the raw bits as a uint64_t. */ -uint64_t FSTDoubleBits(double d) { - if (isnan(d)) { - d = NAN; - } - union DoubleBits converter = {.d = d}; - return converter.bits; -} - -BOOL FSTDoubleBitwiseEquals(double left, double right) { - return FSTDoubleBits(left) == FSTDoubleBits(right); -} - -NSUInteger FSTDoubleBitwiseHash(double d) { - uint64_t bits = FSTDoubleBits(d); - // Note that x ^ (x >> 32) works fine for both 32 and 64 bit definitions of NSUInteger - return (((NSUInteger)bits) ^ (NSUInteger)(bits >> 32)); -} - -NS_ASSUME_NONNULL_END |