aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Source
diff options
context:
space:
mode:
authorGravatar Gil <mcg@google.com>2018-01-19 12:27:11 -0800
committerGravatar GitHub <noreply@github.com>2018-01-19 12:27:11 -0800
commit39d8252300015c26f1932cff42032613fdb36a09 (patch)
tree93bb3ab7c476289c4afe6cf91773a60b6f53a94d /Firestore/Source
parent9f7c094f9f00a6efc0107071f109ef1bc4d7357d (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')
-rw-r--r--Firestore/Source/API/FIRGeoPoint.mm (renamed from Firestore/Source/API/FIRGeoPoint.m)17
-rw-r--r--Firestore/Source/Core/FSTTimestamp.mm (renamed from Firestore/Source/Core/FSTTimestamp.m)9
-rw-r--r--Firestore/Source/Local/FSTDocumentReference.h4
-rw-r--r--Firestore/Source/Local/FSTDocumentReference.mm (renamed from Firestore/Source/Local/FSTDocumentReference.m)11
-rw-r--r--Firestore/Source/Local/FSTMemoryMutationQueue.mm (renamed from Firestore/Source/Local/FSTMemoryMutationQueue.m)7
-rw-r--r--Firestore/Source/Model/FSTFieldValue.mm (renamed from Firestore/Source/Model/FSTFieldValue.m)72
-rw-r--r--Firestore/Source/Util/FSTComparison.h66
-rw-r--r--Firestore/Source/Util/FSTComparison.m175
8 files changed, 89 insertions, 272 deletions
diff --git a/Firestore/Source/API/FIRGeoPoint.m b/Firestore/Source/API/FIRGeoPoint.mm
index 72e9e7d..8d89633 100644
--- a/Firestore/Source/API/FIRGeoPoint.m
+++ b/Firestore/Source/API/FIRGeoPoint.mm
@@ -16,9 +16,14 @@
#import "Firestore/Source/API/FIRGeoPoint+Internal.h"
-#import "Firestore/Source/Util/FSTComparison.h"
+#import "Firestore/core/src/firebase/firestore/util/comparison.h"
+
#import "Firestore/Source/Util/FSTUsageValidation.h"
+using firebase::firestore::util::DoubleBitwiseEquals;
+using firebase::firestore::util::DoubleBitwiseHash;
+using firebase::firestore::util::WrapCompare;
+
NS_ASSUME_NONNULL_BEGIN
@implementation FIRGeoPoint
@@ -45,11 +50,11 @@ NS_ASSUME_NONNULL_BEGIN
}
- (NSComparisonResult)compare:(FIRGeoPoint *)other {
- NSComparisonResult result = FSTCompareDoubles(self.latitude, other.latitude);
+ NSComparisonResult result = WrapCompare<double>(self.latitude, other.latitude);
if (result != NSOrderedSame) {
return result;
} else {
- return FSTCompareDoubles(self.longitude, other.longitude);
+ return WrapCompare<double>(self.longitude, other.longitude);
}
}
@@ -67,12 +72,12 @@ NS_ASSUME_NONNULL_BEGIN
return NO;
}
FIRGeoPoint *otherGeoPoint = (FIRGeoPoint *)other;
- return FSTDoubleBitwiseEquals(self.latitude, otherGeoPoint.latitude) &&
- FSTDoubleBitwiseEquals(self.longitude, otherGeoPoint.longitude);
+ return DoubleBitwiseEquals(self.latitude, otherGeoPoint.latitude) &&
+ DoubleBitwiseEquals(self.longitude, otherGeoPoint.longitude);
}
- (NSUInteger)hash {
- return 31 * FSTDoubleBitwiseHash(self.latitude) + FSTDoubleBitwiseHash(self.longitude);
+ return 31 * DoubleBitwiseHash(self.latitude) + DoubleBitwiseHash(self.longitude);
}
/** Implements NSCopying without actually copying because geopoints are immutable. */
diff --git a/Firestore/Source/Core/FSTTimestamp.m b/Firestore/Source/Core/FSTTimestamp.mm
index 6d9e314..d2b492a 100644
--- a/Firestore/Source/Core/FSTTimestamp.m
+++ b/Firestore/Source/Core/FSTTimestamp.mm
@@ -16,8 +16,11 @@
#import "Firestore/Source/Core/FSTTimestamp.h"
+#include "Firestore/core/src/firebase/firestore/util/comparison.h"
+
#import "Firestore/Source/Util/FSTAssert.h"
-#import "Firestore/Source/Util/FSTComparison.h"
+
+using firebase::firestore::util::WrapCompare;
NS_ASSUME_NONNULL_BEGIN
@@ -110,11 +113,11 @@ static const int kNanosPerSecond = 1000000000;
}
- (NSComparisonResult)compare:(FSTTimestamp *)other {
- NSComparisonResult result = FSTCompareInt64s(self.seconds, other.seconds);
+ NSComparisonResult result = WrapCompare<int64_t>(self.seconds, other.seconds);
if (result != NSOrderedSame) {
return result;
}
- return FSTCompareInt32s(self.nanos, other.nanos);
+ return WrapCompare<int32_t>(self.nanos, other.nanos);
}
@end
diff --git a/Firestore/Source/Local/FSTDocumentReference.h b/Firestore/Source/Local/FSTDocumentReference.h
index eff60e4..04b8416 100644
--- a/Firestore/Source/Local/FSTDocumentReference.h
+++ b/Firestore/Source/Local/FSTDocumentReference.h
@@ -32,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface FSTDocumentReference : NSObject <NSCopying>
/** Initializes the document reference with the given key and ID. */
-- (instancetype)initWithKey:(FSTDocumentKey *)key ID:(int)ID NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithKey:(FSTDocumentKey *)key ID:(int32_t)ID NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@@ -43,7 +43,7 @@ NS_ASSUME_NONNULL_BEGIN
* The targetID of a referring target or the batchID of a referring mutation batch. (Which this
* is depends upon which FSTReferenceSet this reference is a part of.)
*/
-@property(nonatomic, assign, readonly) int ID;
+@property(nonatomic, assign, readonly) int32_t ID;
@end
diff --git a/Firestore/Source/Local/FSTDocumentReference.m b/Firestore/Source/Local/FSTDocumentReference.mm
index 25a5935..4310baa 100644
--- a/Firestore/Source/Local/FSTDocumentReference.m
+++ b/Firestore/Source/Local/FSTDocumentReference.mm
@@ -16,14 +16,17 @@
#import "Firestore/Source/Local/FSTDocumentReference.h"
+#include "Firestore/core/src/firebase/firestore/util/comparison.h"
+
#import "Firestore/Source/Model/FSTDocumentKey.h"
-#import "Firestore/Source/Util/FSTComparison.h"
+
+using firebase::firestore::util::WrapCompare;
NS_ASSUME_NONNULL_BEGIN
@implementation FSTDocumentReference
-- (instancetype)initWithKey:(FSTDocumentKey *)key ID:(int)ID {
+- (instancetype)initWithKey:(FSTDocumentKey *)key ID:(int32_t)ID {
self = [super init];
if (self) {
_key = key;
@@ -67,13 +70,13 @@ const NSComparator FSTDocumentReferenceComparatorByKey =
if (result != NSOrderedSame) {
return result;
}
- return FSTCompareInts(left.ID, right.ID);
+ return WrapCompare<int32_t>(left.ID, right.ID);
};
/** Sorts document references by ID then key. */
const NSComparator FSTDocumentReferenceComparatorByID =
^NSComparisonResult(FSTDocumentReference *left, FSTDocumentReference *right) {
- NSComparisonResult result = FSTCompareInts(left.ID, right.ID);
+ NSComparisonResult result = WrapCompare<int32_t>(left.ID, right.ID);
if (result != NSOrderedSame) {
return result;
}
diff --git a/Firestore/Source/Local/FSTMemoryMutationQueue.m b/Firestore/Source/Local/FSTMemoryMutationQueue.mm
index b155264..702f614 100644
--- a/Firestore/Source/Local/FSTMemoryMutationQueue.m
+++ b/Firestore/Source/Local/FSTMemoryMutationQueue.mm
@@ -23,10 +23,13 @@
#import "Firestore/Source/Model/FSTMutationBatch.h"
#import "Firestore/Source/Model/FSTPath.h"
#import "Firestore/Source/Util/FSTAssert.h"
-#import "Firestore/Source/Util/FSTComparison.h"
NS_ASSUME_NONNULL_BEGIN
+static const NSComparator NumberComparator = ^NSComparisonResult(NSNumber *left, NSNumber *right) {
+ return [left compare:right];
+};
+
@interface FSTMemoryMutationQueue ()
/**
@@ -260,7 +263,7 @@ NS_ASSUME_NONNULL_BEGIN
// Find unique batchIDs referenced by all documents potentially matching the query.
__block FSTImmutableSortedSet<NSNumber *> *uniqueBatchIDs =
- [FSTImmutableSortedSet setWithComparator:FSTNumberComparator];
+ [FSTImmutableSortedSet setWithComparator:NumberComparator];
FSTDocumentReferenceBlock block = ^(FSTDocumentReference *reference, BOOL *stop) {
FSTResourcePath *rowKeyPath = reference.key.path;
if (![prefix isPrefixOfPath:rowKeyPath]) {
diff --git a/Firestore/Source/Model/FSTFieldValue.m b/Firestore/Source/Model/FSTFieldValue.mm
index a6326a7..8ffc98e 100644
--- a/Firestore/Source/Model/FSTFieldValue.m
+++ b/Firestore/Source/Model/FSTFieldValue.mm
@@ -16,6 +16,9 @@
#import "Firestore/Source/Model/FSTFieldValue.h"
+#include "Firestore/core/src/firebase/firestore/util/comparison.h"
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+
#import "Firestore/Source/API/FIRGeoPoint+Internal.h"
#import "Firestore/Source/API/FIRSnapshotOptions+Internal.h"
#import "Firestore/Source/Core/FSTTimestamp.h"
@@ -24,7 +27,14 @@
#import "Firestore/Source/Model/FSTPath.h"
#import "Firestore/Source/Util/FSTAssert.h"
#import "Firestore/Source/Util/FSTClasses.h"
-#import "Firestore/Source/Util/FSTComparison.h"
+
+using firebase::firestore::util::Comparator;
+using firebase::firestore::util::CompareMixedNumber;
+using firebase::firestore::util::DoubleBitwiseEquals;
+using firebase::firestore::util::DoubleBitwiseHash;
+using firebase::firestore::util::MakeStringView;
+using firebase::firestore::util::ReverseOrder;
+using firebase::firestore::util::WrapCompare;
NS_ASSUME_NONNULL_BEGIN
@@ -208,7 +218,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSComparisonResult)compare:(FSTFieldValue *)other {
if ([other isKindOfClass:[FSTBooleanValue class]]) {
- return FSTCompareBools(self.internalValue, ((FSTBooleanValue *)other).internalValue);
+ return WrapCompare<bool>(self.internalValue, ((FSTBooleanValue *)other).internalValue);
} else {
return [self defaultCompare:other];
}
@@ -231,19 +241,22 @@ NS_ASSUME_NONNULL_BEGIN
if ([self isKindOfClass:[FSTDoubleValue class]]) {
double thisDouble = ((FSTDoubleValue *)self).internalValue;
if ([other isKindOfClass:[FSTDoubleValue class]]) {
- return FSTCompareDoubles(thisDouble, ((FSTDoubleValue *)other).internalValue);
+ return WrapCompare(thisDouble, ((FSTDoubleValue *)other).internalValue);
} else {
FSTAssert([other isKindOfClass:[FSTIntegerValue class]], @"Unknown number value: %@",
other);
- return FSTCompareMixed(thisDouble, ((FSTIntegerValue *)other).internalValue);
+ auto result = CompareMixedNumber(thisDouble, ((FSTIntegerValue *)other).internalValue);
+ return static_cast<NSComparisonResult>(result);
}
} else {
int64_t thisInt = ((FSTIntegerValue *)self).internalValue;
if ([other isKindOfClass:[FSTIntegerValue class]]) {
- return FSTCompareInt64s(thisInt, ((FSTIntegerValue *)other).internalValue);
+ return WrapCompare(thisInt, ((FSTIntegerValue *)other).internalValue);
} else {
FSTAssert([other isKindOfClass:[FSTDoubleValue class]], @"Unknown number value: %@", other);
- return -1 * FSTCompareMixed(((FSTDoubleValue *)other).internalValue, thisInt);
+ double otherDouble = ((FSTDoubleValue *)other).internalValue;
+ auto result = ReverseOrder(CompareMixedNumber(otherDouble, thisInt));
+ return static_cast<NSComparisonResult>(result);
}
}
}
@@ -334,11 +347,11 @@ NS_ASSUME_NONNULL_BEGIN
// NOTE: isEqual: should compare NaN equal to itself and -0.0 not equal to 0.0.
return [other isKindOfClass:[FSTDoubleValue class]] &&
- FSTDoubleBitwiseEquals(self.internalValue, ((FSTDoubleValue *)other).internalValue);
+ DoubleBitwiseEquals(self.internalValue, ((FSTDoubleValue *)other).internalValue);
}
- (NSUInteger)hash {
- return FSTDoubleBitwiseHash(self.internalValue);
+ return DoubleBitwiseHash(self.internalValue);
}
// NOTE: compare: is implemented in NumberValue.
@@ -347,6 +360,17 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - FSTStringValue
+/**
+ * Specialization of Comparator for NSStrings.
+ */
+template <>
+struct Comparator<NSString *> {
+ bool operator()(NSString *left, NSString *right) const {
+ Comparator<absl::string_view> lessThan;
+ return lessThan(MakeStringView(left), MakeStringView(right));
+ }
+};
+
@interface FSTStringValue ()
@property(nonatomic, copy, readonly) NSString *internalValue;
@end
@@ -385,7 +409,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSComparisonResult)compare:(FSTFieldValue *)other {
if ([other isKindOfClass:[FSTStringValue class]]) {
- return FSTCompareStrings(self.internalValue, ((FSTStringValue *)other).internalValue);
+ return WrapCompare(self.internalValue, ((FSTStringValue *)other).internalValue);
} else {
return [self defaultCompare:other];
}
@@ -556,6 +580,22 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - FSTBlobValue
+static NSComparisonResult CompareBytes(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;
+ }
+}
+
@interface FSTBlobValue ()
@property(nonatomic, copy, readonly) NSData *internalValue;
@end
@@ -594,7 +634,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSComparisonResult)compare:(FSTFieldValue *)other {
if ([other isKindOfClass:[FSTBlobValue class]]) {
- return FSTCompareBytes(self.internalValue, ((FSTBlobValue *)other).internalValue);
+ return CompareBytes(self.internalValue, ((FSTBlobValue *)other).internalValue);
} else {
return [self defaultCompare:other];
}
@@ -664,6 +704,10 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - FSTObjectValue
+static const NSComparator StringComparator = ^NSComparisonResult(NSString *left, NSString *right) {
+ return WrapCompare(left, right);
+};
+
@interface FSTObjectValue ()
@property(nonatomic, strong, readonly)
FSTImmutableSortedDictionary<NSString *, FSTFieldValue *> *internalValue;
@@ -677,7 +721,7 @@ NS_ASSUME_NONNULL_BEGIN
dispatch_once(&onceToken, ^{
FSTImmutableSortedDictionary<NSString *, FSTFieldValue *> *empty =
- [FSTImmutableSortedDictionary dictionaryWithComparator:FSTStringComparator];
+ [FSTImmutableSortedDictionary dictionaryWithComparator:StringComparator];
sharedEmptyInstance = [[FSTObjectValue alloc] initWithImmutableDictionary:empty];
});
return sharedEmptyInstance;
@@ -694,7 +738,7 @@ NS_ASSUME_NONNULL_BEGIN
- (id)initWithDictionary:(NSDictionary<NSString *, FSTFieldValue *> *)value {
FSTImmutableSortedDictionary<NSString *, FSTFieldValue *> *dictionary =
- [FSTImmutableSortedDictionary dictionaryWithDictionary:value comparator:FSTStringComparator];
+ [FSTImmutableSortedDictionary dictionaryWithDictionary:value comparator:StringComparator];
return [self initWithImmutableDictionary:dictionary];
}
@@ -748,7 +792,7 @@ NS_ASSUME_NONNULL_BEGIN
key2 = [enumerator2 nextObject];
}
// Only equal if both enumerators are exhausted.
- return FSTCompareBools(key1 != nil, key2 != nil);
+ return WrapCompare(key1 != nil, key2 != nil);
} else {
return [self defaultCompare:other];
}
@@ -876,7 +920,7 @@ NS_ASSUME_NONNULL_BEGIN
return cmp;
}
}
- return FSTCompareUIntegers(selfArray.count, otherArray.count);
+ return WrapCompare<int64_t>(selfArray.count, otherArray.count);
} else {
return [self defaultCompare:other];
}
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